Keep application cookies when submitting a solved token

By solvethree3 min read

A solved reCAPTCHA token doesn't replace the application's session cookies or CSRF value. Fetch the form and submit it through the same requests.Session so the POST keeps the cookies received during the GET.

Use the solver's returned browser headers and the same proxy for both application requests. The example solves first so those headers are available before opening the form.

On this page

Keep the form GET and POST in one session

Use Python 3.10+ with requests and the official solvethree Python SDK installed. The target hostname needs an active profile in your workspace; sending its hostname in a task doesn't create one. See site profile setup if it isn't configured.

  • Set TARGET_URL to your application's form URL. This owned demo uses the same URL for the GET and POST.
  • Set SOLVETHREE_PROXY to the single proxy used for solving and both application requests.
  • Set SOLVETHREE_API_KEY to your workspace API key. Run this code server-side.
requests.Session · keep application cookies and a CSRF value
# This owned demo form has an input named csrf_token and g-recaptcha-response.
import os
from html.parser import HTMLParser
from urllib.parse import urlsplit
import requests
from solvethree import Solvethree

class FormParser(HTMLParser):
    csrf = None
    def handle_starttag(self, tag, attributes):
        values = dict(attributes)
        if tag == "input" and values.get("name") == "csrf_token":
            self.csrf = values.get("value")

target = os.environ["TARGET_URL"]
proxy = os.environ["SOLVETHREE_PROXY"]
request = {"site": urlsplit(target).hostname, "action": "login", "proxy": proxy}
# Obtain the solver's browser headers before opening the application session.
result = Solvethree(os.environ["SOLVETHREE_API_KEY"]).solve(request, timeout=180)
solution = result["solution"]
with requests.Session() as session:
    session.headers.update({"User-Agent": solution["userAgent"], "sec-ch-ua": solution["secChUa"]})
    proxies = {"http": proxy, "https": proxy}
    page = session.get(target, proxies=proxies, timeout=20, allow_redirects=False)
    page.raise_for_status()
    parser = FormParser(); parser.feed(page.text)
    if not parser.csrf: raise RuntimeError("The expected demo CSRF input was not found")
    response = session.post(target, proxies=proxies, timeout=20, allow_redirects=False,
        data={"csrf_token": parser.csrf, "g-recaptcha-response": solution["token"]})
    print("Application HTTP status:", response.status_code)
    # Use the actual form's submit URL, fields and session rules. Inspect its result.

The SDK's solve call creates the task and polls until it's ready or raises. The example then applies solution.userAgent and solution.secChUa to the session. The GET populates its cookie jar; the POST reuses that jar and submits solution.token alongside the CSRF value parsed from the form.

Change the demo's login action, submit URL, and form fields to match your application. csrf_token is this form's field name, not a solvethree requirement. Adjust the HTML parser if yours uses another name or structure, and include any other required fields, such as login credentials. If the submit URL differs from the form URL, still use the same session.

If the application rejects the POST

The printed HTTP status is a starting point, not proof that login succeeded. Inspect the application's response and outgoing request before paying for another solve. A ready task means a solution was generated; the application still decides whether to accept the submission.

The CSRF input isn't found.

Check the GET response status and body. Redirect following is disabled, so a redirect response isn't the expected form.

Try this: Fetch the correct form deliberately through the same session, then adjust the parser to its actual CSRF field.

The application reports a missing session or invalid CSRF value.

Check whether the GET received cookies, whether the POST sent the applicable cookies, and whether its CSRF value came from that form response.

Try this: Keep both requests in the same requests.Session. Don't fetch the form with one client and submit it with another.

The application rejects the CAPTCHA.

Inspect the outgoing token field, action, proxy, User-Agent and sec-ch-ua. Confirm you're sending solution.token rather than the task ID or an older token.

Try this: Use the current token, the same proxy used for solving, and the returned browser headers. If the token expired or was already assessed, obtain a fresh one near submission.

The POST completes, but login doesn't.

Inspect the response body and any redirect destination, plus the actual submit URL and required form fields.

Try this: Adapt the demo's form data to the application's contract. A CAPTCHA token doesn't supply credentials or other missing application fields.

Run your first task.

Start with $5 in workspace credit.

Create a workspace