From 16b0081d3e698472b6b18515835596aa233aef99 Mon Sep 17 00:00:00 2001 From: Aykhan Shahsuvarov Date: Sun, 12 Apr 2026 01:34:28 +0400 Subject: [PATCH] docs: document captcha solving template functions in README and guides --- README.md | 3 +- docs/examples.md | 23 +++++++++++ docs/templating.md | 95 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fd85ba1..e9360db 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,8 @@ Sarin is designed for efficient HTTP load testing with minimal resource consumpt | Dynamic requests via 320+ template functions | Web UI or complex TUI | | Request scripting with Lua and JavaScript | Distributed load testing | | Multiple proxy protocols
(HTTP, HTTPS, SOCKS5, SOCKS5H) | HTTP/2, HTTP/3, WebSocket, gRPC | -| Flexible config (CLI, ENV, YAML) | Plugins / extensions ecosystem | +| Captcha solving
(2Captcha, Anti-Captcha, CapSolver) | Plugins / extensions ecosystem | +| Flexible config (CLI, ENV, YAML) | | ## Installation diff --git a/docs/examples.md b/docs/examples.md index 14b59ad..615e726 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -8,6 +8,7 @@ This guide provides practical examples for common Sarin use cases. - [Request-Based vs Duration-Based Tests](#request-based-vs-duration-based-tests) - [Headers, Cookies, and Parameters](#headers-cookies-and-parameters) - [Dynamic Requests with Templating](#dynamic-requests-with-templating) +- [Solving Captchas](#solving-captchas) - [Request Bodies](#request-bodies) - [File Uploads](#file-uploads) - [Using Proxies](#using-proxies) @@ -373,6 +374,28 @@ body: '{"ip": "{{ fakeit_IPv4Address }}", "timestamp": "{{ fakeit_Date }}", "act > For the complete list of 320+ template functions, see the **[Templating Guide](templating.md)**. +## Solving Captchas + +Sarin can solve captchas through third-party services and embed the resulting token into the request. Three services are supported via dedicated template functions: **2Captcha**, **Anti-Captcha**, and **CapSolver**. + +**Solve a reCAPTCHA v2 and submit the token in the request body:** + +```sh +sarin -U https://example.com/login -M POST -r 1 \ + -B '{"g-recaptcha-response": "{{ twocaptcha_RecaptchaV2 "YOUR_API_KEY" "SITE_KEY" "https://example.com/login" }}"}' +``` + +**Reuse a single solved token across multiple requests via `values`:** + +```sh +sarin -U https://example.com/api -M POST -r 5 \ + -V 'TOKEN={{ anticaptcha_Turnstile "YOUR_API_KEY" "SITE_KEY" "https://example.com/api" }}' \ + -H "X-Turnstile-Token: {{ .Values.TOKEN }}" \ + -B '{"token": "{{ .Values.TOKEN }}"}' +``` + +> See the **[Templating Guide](templating.md#captcha-functions)** for the full list of captcha functions and per-service support. + ## Request Bodies **Simple JSON body:** diff --git a/docs/templating.md b/docs/templating.md index a3156a2..cd7c6da 100644 --- a/docs/templating.md +++ b/docs/templating.md @@ -4,6 +4,8 @@ Sarin supports Go templates in URL paths, methods, bodies, headers, params, cook > **Note:** Templating in URL host and scheme is not supported. Only the path portion of the URL can contain templates. +> **Note:** Template rendering happens before the request is sent. The request timeout (`-T` / `timeout`) only governs the HTTP request itself and starts _after_ templates have finished rendering, so slow template functions (e.g. captcha solvers, remote `file_Read`) cannot cause a request timeout no matter how long they take. + ## Table of Contents - [Using Values](#using-values) @@ -14,6 +16,10 @@ Sarin supports Go templates in URL paths, methods, bodies, headers, params, cook - [Crypto Functions](#crypto-functions) - [Body Functions](#body-functions) - [File Functions](#file-functions) +- [Captcha Functions](#captcha-functions) + - [2Captcha](#2captcha) + - [Anti-Captcha](#anti-captcha) + - [CapSolver](#capsolver) - [Fake Data Functions](#fake-data-functions) - [File](#file) - [ID](#id) @@ -196,6 +202,95 @@ values: "FILE_DATA={{ file_Base64 \"/path/to/file.bin\" }}" body: '{"data": "{{ .Values.FILE_DATA }}"}' ``` +## Captcha Functions + +Captcha functions solve a captcha challenge through a third-party solving service and return the resulting token, which can then be embedded directly into a request. They are intended for load testing endpoints protected by reCAPTCHA, hCaptcha, or Cloudflare Turnstile. + +The functions are organized by service: `twocaptcha_*`, `anticaptcha_*`, and `capsolver_*`. Each accepts the API key as the first argument so no global configuration is required — bring your own key and use any of the supported services per template. + +> **Important — performance and cost:** +> +> - **Each call is slow.** Solving typically takes ~5–60 seconds because the function blocks the template render until the third-party service returns a token. Internally the solver polls every 1s and gives up after 120s. +> - **Each call costs money.** Every successful solve is billed by the captcha service (typically $0.001–$0.003 per solve). For high-volume tests, your captcha bill grows linearly with request count. + +**Common parameters across all captcha functions:** + +- `apiKey` - Your API key for the chosen captcha solving service +- `siteKey` - The captcha sitekey extracted from the target page (e.g. the `data-sitekey` attribute on a reCAPTCHA, hCaptcha, or Turnstile element) +- `pageURL` - The URL of the page where the captcha is hosted + +### 2Captcha + +Functions for the [2Captcha](https://2captcha.com) service. Note: 2Captcha **does not currently support hCaptcha** through their API. + +| Function | Description | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------- | +| `twocaptcha_RecaptchaV2(apiKey, siteKey, pageURL string)` | Solve a Google reCAPTCHA v2 challenge | +| `twocaptcha_RecaptchaV3(apiKey, siteKey, pageURL, pageAction string)` | Solve a Google reCAPTCHA v3 challenge. Pass `""` for `pageAction` to omit | +| `twocaptcha_Turnstile(apiKey, siteKey, pageURL string, cData ...string)` | Solve a Cloudflare Turnstile challenge. Optional `cData` argument | + +### Anti-Captcha + +Functions for the [Anti-Captcha](https://anti-captcha.com) service. This is currently the only service that supports all four captcha types end-to-end. + +| Function | Description | +| ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| `anticaptcha_RecaptchaV2(apiKey, siteKey, pageURL string)` | Solve a Google reCAPTCHA v2 challenge | +| `anticaptcha_RecaptchaV3(apiKey, siteKey, pageURL, pageAction string)` | Solve a Google reCAPTCHA v3 challenge. `minScore` is hardcoded to `0.3` (Anti-Captcha rejects the request without it) | +| `anticaptcha_HCaptcha(apiKey, siteKey, pageURL string)` | Solve an hCaptcha challenge | +| `anticaptcha_Turnstile(apiKey, siteKey, pageURL string, cData ...string)` | Solve a Cloudflare Turnstile challenge. Optional `cData` argument | + +### CapSolver + +Functions for the [CapSolver](https://capsolver.com) service. Note: CapSolver no longer supports hCaptcha. + +| Function | Description | +| ----------------------------------------------------------------------- | ------------------------------------------------------------------------- | +| `capsolver_RecaptchaV2(apiKey, siteKey, pageURL string)` | Solve a Google reCAPTCHA v2 challenge | +| `capsolver_RecaptchaV3(apiKey, siteKey, pageURL, pageAction string)` | Solve a Google reCAPTCHA v3 challenge. Pass `""` for `pageAction` to omit | +| `capsolver_Turnstile(apiKey, siteKey, pageURL string, cData ...string)` | Solve a Cloudflare Turnstile challenge. Optional `cData` argument | + +**Examples:** + +```yaml +# reCAPTCHA v2 in a JSON body via 2Captcha +method: POST +url: https://example.com/login +body: | + { + "username": "test", + "g-recaptcha-response": "{{ twocaptcha_RecaptchaV2 "YOUR_API_KEY" "6LfD3PIb..." "https://example.com/login" }}" + } +``` + +```yaml +# Turnstile via Anti-Captcha with cData +method: POST +url: https://example.com/submit +body: | + { + "cf-turnstile-response": "{{ anticaptcha_Turnstile "YOUR_API_KEY" "0x4AAAAAAA..." "https://example.com/submit" "session-cdata" }}" + } +``` + +```yaml +# hCaptcha via Anti-Captcha (the only service that still supports it) +method: POST +url: https://example.com/protected +body: | + { + "h-captcha-response": "{{ anticaptcha_HCaptcha "YOUR_API_KEY" "338af34c-..." "https://example.com/protected" }}" + } +``` + +```yaml +# Share a single solved token across body and headers via values +values: 'TOKEN={{ capsolver_Turnstile "YOUR_API_KEY" "0x4AAAAAAA..." "https://example.com" }}' +headers: + X-Turnstile-Token: "{{ .Values.TOKEN }}" +body: '{"token": "{{ .Values.TOKEN }}"}' +``` + ## Fake Data Functions These functions are powered by [gofakeit](https://github.com/brianvoe/gofakeit) library.