Recovers the OnlyFans request-signing configuration from OnlyFans' obfuscated
challenge script (2313.js) and validates it against the live public API.
The signing parameters change whenever OnlyFans re-obfuscates its script, so the extractor is built to run the script's own logic rather than pattern-match its (deliberately shuffled) source — see How it stays robust.
mod.py ──fetch──▶ _2313.js ──node extract_config.js──▶ result.json ──▶ signing params
│ ▲
└── 24h cache: reuse result.json if fresh ───────────────┘
| File | Role |
|---|---|
mod.py |
Driver. Fetches the live 2313.js, caches, and shells out to the extractor. |
extract_config.js |
The reverser. Deobfuscates the script and writes result.json. Node.js. |
test_sign.py |
Signs a request to a public OF endpoint and checks it's accepted (200). |
result.json |
Output. staticParam, start, end, checksumIndexes, checksumConstant. Generated at runtime. |
payload = staticParam + "\n" + time_ms + "\n" + path + "\n" + user_id
hash = sha1(payload).hexdigest()
checksum = abs( sum(hash[i] for i in checksumIndexes) + checksumConstant )
sign = f"{start}:{hash}:{checksum:x}:{end}"
- Python 3.9+
- Node.js on your
PATH(used byextract_config.js)
python -m venv .venv
# Windows: .\.venv\Scripts\activate
# Unix: source .venv/bin/activate
pip install -r requirements.txt# Fetch the live script and produce result.json (reuses a <24h cache):
python mod.py
# Force a fresh extract:
# (delete result.json first, then run mod.py)
# Run the extractor directly on any saved script:
node extract_config.js <path-to-2313.js> <output.json>
# Validate that result.json produces an accepted signature:
python test_sign.pyOnlyFans periodically re-runs its obfuscator on 2313.js. In practice this only
ever renames identifiers and reorders decoder-call arguments (e.g.
i(n-744, W) becomes i(W- -290, n)) — the same obfuscator with a new random
seed. Any extractor that hard-codes a variable name or argument order breaks on
every reshuffle.
extract_config.js avoids that entirely:
- It bootstraps the script's own string decoder and executes it, instead of re-deriving decoded strings by hand.
- It carves out the pieces it needs by brace-matching structure, never by matching specific minified names.
- It rebuilds the checksum as a live function and recovers the indexes and constant by black-box probing it (finite differences) — not by counting tokens in the source.
- It then self-verifies the recovered parameters against the site's own
checksum on hundreds of random inputs, and refuses to emit
result.jsonon any mismatch.
The result: renames and reorderings just work. The only thing that would break it
is genuinely new anti-automation (e.g. environment/DOM/toString traps), in which
case the self-check stops with a clear error instead of writing a broken config.
This project is for educational and research purposes — understanding client side request-signing / anti-bot obfuscation. It only reads publicly available data and does not bypass authentication, handle credentials, or scrape at scale. Using it may violate OnlyFans' Terms of Service; you are responsible for how you use it. Provided as is, without warranty. Not affiliated with or endorsed by OnlyFans.