Skip to content

Post the login form from the sandbox and replay every collection body - #6

Closed
OmerFarukOruc wants to merge 1 commit into
proofofbots:mainfrom
OmerFarukOruc:akamai-login-form-and-collection-replay
Closed

OmerFarukOruc wants to merge 1 commit into
proofofbots:mainfrom
OmerFarukOruc:akamai-login-form-and-collection-replay

Conversation

@OmerFarukOruc

Copy link
Copy Markdown

On a login page the Akamai sensor posts twice: the sensor_data payload, then a
follow-up json body. Only the first was replayed, and clicking submit in the
sandbox did nothing, so a run never produced the form navigation the edge
expects.

What this changes

Forms submit. HTMLFormElement.submit() posts the entry list.
requestSubmit() fires a cancellable submit event first, and a click on a
submit control goes through it, so a page that calls preventDefault() and
posts by XHR is not double-posted. The submitting button joins the entry list
the way a browser builds it.

solve replays what the script actually sent. Every collection post the
sensor made is replayed with its own framing (text/plain for sensor_data,
application/json for a collection body), then fresh payloads top the run up to
the requested round count. sensor::classify is the single place that decides
what a captured body is.

Header fidelity for form navigations. A form post carries the header block
and wire order of the browser family the fingerprint was picked from.
session::plan(user_agent, form) is the only place that choice is made, and it
reads the family from wre_net::is_firefox, which is built on the same
family_of that selects the TLS and H2 profile. The header policy cannot drift
from the fingerprint.

request op. Gains redirects (0 returns the first hop), omit_referer
and omit_origin, and reports set_cookies: the name, domain, path,
same_site, secure and http_only of every Set-Cookie line the edge sent,
including ones the jar rejected. Parsing lives in wre_net::jar next to the
cookie model.

The sandbox html cap no longer hides the sensor. Page::load never
truncates before the end of the last script the page loads, so an obfuscated
sensor sitting past the cap on a large page still reaches the document.

Tests

cargo test --workspace is green. New coverage:

  • a click on submit posts the right entry list, and a page that cancels the
    submit event sends nothing (both arms)
  • a sensor script past the html cap reaches the DOM, at both the Page and
    browser layers
  • a {"body":...} collection post round-trips as json through solve
  • Set-Cookie attribute parsing, including a line that carries no cookie

Worth a reviewer's eye

FIREFOX_FORM and FIREFOX_FORM_ORDER, including te: trailers and its
position before priority, are not backed by a capture in this repo. They are
worth checking against a real Firefox navigation before anyone relies on them.

XMLHttpRequest now exposes status at HEADERS_RECEIVED but withholds the
body until LOADING, since a browser has no body at readyState 2.

On a login page the sensor posts twice: the sensor_data payload, then a
follow-up json body. Only the first was replayed, and clicking submit in the
sandbox did nothing, so a run never produced the form navigation the edge
expects.

- HTMLFormElement submits for real. submit() posts the entry list,
  requestSubmit() fires a cancellable submit event first, and a click on a
  submit control goes through it, so a page that calls preventDefault and
  posts by XHR is not double-posted.
- solve replays every collection post the script made, keeping each body's
  own framing, then tops up with fresh payloads to the requested rounds.
- A form navigation carries the header block and wire order of the browser
  family the fingerprint was picked from. Both are chosen in one place so
  they cannot drift from each other or from the fingerprint.
- request gains redirects, omit_referer and omit_origin, and reports the
  attributes of every set-cookie line the edge sent.
- The sandbox html cap no longer cuts before the last script the page loads,
  which was hiding the sensor on large pages.
@OmerFarukOruc OmerFarukOruc closed this by deleting the head repository Sep 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant