Repository navigation
Serialized Object Detection
📖 Canonical version: read this page on the official docs site — https://www.redamon.org/docs/serialized-object-detection. The GitHub wiki is a mirror.
Serialized Object Detection is RedAmon's insecure-deserialization capability. It is split into two halves that work as one loop:
-
Detect (recon). A passive, in-memory recon module — Serialized Object Scan —
reads what the pipeline already holds (response headers,
Set-Cookie, the parameters resource enumeration discovered, and the hidden and visible fields of the forms it crawled) and flags serialized-object signatures across every major family. Each sink becomes oneinfo-severity:Vulnerabilitycandidate per format, markedneeds_agent_confirmation: a base64 Java cookie matches asrO0ABtext and again once decoded, a serializationContent-Typeis reported both by the probe and in its header list, and each is still one candidate. Recon sends no extra traffic and never deserializes anything. - Confirm (agent). The built-in Insecure Deserialization agent skill reads those candidates, confirms the one that matters with a non-destructive out-of-band oracle, and records proof so the candidate is promoted on the Priority Board.
The split is deliberate: recon flags "serialization is present and attacker-reachable" cheaply and safely; the agent does the request-side digging and the confirmation. A candidate stays a quiet lead until the agent proves it.
Serialized blobs mostly ride request-side — cookies, POST bodies, parameters. The recon pipeline's in-memory corpus only carries the response side plus the enumerated endpoints/parameters (request bodies are dropped). So recon seeds candidates from what it can see for free, and the agent — which has full captured-traffic access via its traffic tools — pulls the original request and confirms. This is why TrafficMind (HTTP capture) is a soft prerequisite: with it on, the agent has a request-side corpus to confirm against. The recon side still runs without it, just with a thinner corpus.
The scan runs every candidate value through a bomb-safe decode-and-recurse normalizer (URL → base64 → gzip → zlib → hex, re-matching at each layer) and matches these families:
| Family | Signature | deser_format |
|---|---|---|
| Native Java |
AC ED 00 05; base64 rO0AB; hex aced0005; Content-Type: application/x-java-serialized-object
|
native_java |
| Jackson / json-io / Genson | JSON @class key |
jackson_json |
| FastJSON | JSON @type key |
fastjson |
| XMLDecoder |
<java version=, <object class=, <void
|
xmldecoder |
| XStream | FQ-class element / class= attribute |
xstream |
| SnakeYAML |
!! + a Java package tag |
snakeyaml |
| PHP |
O:<n>:", a:<n>:{; phar://
|
php_serialize / phar
|
| Python pickle |
\x80\x02/\x04/\x05; base64 gASV / gAJ
|
python_pickle |
| .NET BinaryFormatter / ViewState |
00 01 00 00 00 FF FF FF FF; base64 AAEAAAD/////; __VIEWSTATE
|
dotnet_binaryformatter / viewstate
|
| Ruby Marshal | \x04\x08 |
ruby_marshal |
| Hessian | Content-Type: application/x-hessian |
hessian |
Honest ceiling. Recon flags serialization present and reachable, not exploitable.
It misses encrypted blobs, off-HTTP channels, and anything the in-memory slice never
carried. The biggest blind spot is concrete: the slice holds response headers and
Set-Cookie only for the URLs httpx probed: each base URL's root (after any
redirect), plus the paths listed in httpxPaths, which is empty by default. The crawler
keeps a deeper endpoint's path, parameters and forms, but not its response, so a blob
that a page such as /login returns in a header or a cookie is missed unless that path
is probed. Measured on the serialized-object lab with the defaults, a live run flags the
families it also exposes in a link or a form, and none of the ten it serves only in
deeper responses. Those are the agent's to find, from captured traffic. Confirmation is
the agent's job.
-
Never deserializes. Standard-library decode + regex only — no
pickle, noyaml.load, noObjectInputStream-equivalent. The scanner never becomes the victim. -
Bomb-safe decoder. At most 4 decode layers and ≤ 1 MiB of decompressed output per
value; a decompression bomb is aborted and the candidate is flagged
truncatedrather than expanded. -
Render-safe evidence. The stored
evidence_snippetis printable-ASCII only (non-printable bytes hex-escaped), capped at 120 characters — never raw decoded bytes.
- Recon writes a
:Vulnerability {source:'serialized_scan', needs_agent_confirmation:true, severity:'info'}candidate, linked to the affectedEndpoint/BaseURLviaHAS_VULNERABILITY, carryingdeser_language,deser_format,deser_transport(cookie / param / header),deser_location(the cookie's, parameter's or header's own name),deser_encoding_layers(the layers peeled to reach the match, which a payload must be wrapped in again),deser_magic(the marker that matched) andevidence_snippet, plus Jev'sdeser_jev_*reading when the project ranks them with Jev. The candidate's id is its sink and format, so a later run that sees the same sink matched by another marker updates it rather than adding a twin. - On the Priority Board the
infoseverity pins it to T4 "Track" — the bottom of the list. It is a quiet lead, not noise at the top. - The agent's Insecure Deserialization skill reads pending candidates (read-only
query_graph), confirms with a non-destructive oracle (out-of-band callback, timing or error differential, as the project's switches allow), and records the confirmation as achain_findingsentry in its output analysis, withfinding_type='vulnerability_confirmed'plus the candidate's id. - That lands a proof-typed
(:ChainFinding)-[:CONFIRMS]->(candidate)edge, which flows through the proof gate and promotes the candidate to T1 "Act now".
Until a candidate is confirmed, Pentest Reports and the
Insights Dashboard hide it — an unconfirmed info candidate is
never counted as a real vulnerability there. The graph screen, Node Inspector and
Priority Board keep showing it, so an operator can always see the lead. Once confirmed, it
appears in the report labelled "Insecure Deserialization".
The built-in Insecure Deserialization agent skill (badge DESER, classification
key deserialization) owns confirmation. See Agent Skills
for the full write-up. In short, it:
-
Reuses recon first —
query_graphfor pendingserialized_scancandidates (most reachable first when Jev ranks them, then by id, with an explicitLIMIT), capturing each id and itsdeser_*metadata. -
Pulls the original request with its traffic tools (search by endpoint/method, or
fetch_transaction) rather than re-crawling; if there are no candidates it probes from scratch using the same signatures. -
Confirms with a non-destructive oracle through the channels the project enables: an
out-of-band callback (for example a Java URLDNS or a Python
__reduce__-DNS blob that only performs a lookup), response timing, or the error differential. See the skill's switches. -
Records the confirmation by filling
chain_findingsin itsoutput_analysis, in the same response that reads the proof, withfinding_type='vulnerability_confirmed'and the candidate id. There is no report tool or action: the field is the only way a confirmation reaches the graph. It then re-queries to verify theCONFIRMSedge landed (a wrong/cross-tenant id matches nothing silently); if the edge is missing, the entry goes into the next response. - Escalation to a code-execution gadget is gated off by default — the operator opts in per project. The default path is the non-destructive oracle only.
Model note. Recording depends on the model filling a structured field. In the end-to-end test against the lab,
deepseek-chatconfirmed the sink but kept writing "emit chain_findings" as a next step and never filled it, so no edge landed;deepseek-v4-profilled it and the candidate was proven on the first try.
Both halves default off — a gated posture. An operator opts in per project.
| Setting | Where | Default | What it does |
|---|---|---|---|
Serialized Object Scan (serializedScanEnabled) |
Project form → Recon Pipeline → JS Recon tab | off | Runs the passive detection module. |
Rank candidates with Jev (serializedScanJevRank) |
Serialized Object Scan card, or Target & Modules → AI in Pipeline | off | Optional TypeSafe Jev assessment of each flagged blob (format + reachability). Writes Jev's reading onto each candidate and orders them for the agent. Needs AI in Pipeline and a Jev token on the owner's account. |
Insecure Deserialization (deserialization built-in skill) |
Project form → AI Agent → Agent Skills | off | Lets the agent confirm candidates. |
OOB callback workflow (deserializationOobCallbackEnabled) |
Agent Skills → Insecure Deserialization | on | The non-destructive interactsh oracle. Off = confirm via the timing and error channels only. |
OOB provider (deserializationOobProvider) |
same card | oast.fun | interactsh server the oracle registers on. |
Timing channel (deserializationTimingEnabled) |
same card | on | Confirm by response timing; disable on fragile targets. |
Find sinks beyond recon candidates (deserializationFindSinksEnabled) |
same card | on | Sweep inputs for sinks recon never flagged. Off = confirm only recon's candidates. |
Runtimes to cover (deserializationRuntimes) |
same card | all seven | Which per-runtime oracle blocks ship (java, java_typed, python, php, node, ruby, dotnet). |
Exec gadget step (deserializationExecGadgetsEnabled) |
same card | off | Code-execution gadget delivery (Step 7). Needs the OOB callback on; off until an operator enables it. |
PHAR polyglot upload (deserializationPharEnabled) |
same card | off | PHP PHAR polyglots, which upload a file to the target. |
The full per-switch reference, with how each one changes the agent prompt, is on Agent Skills → Insecure Deserialization.
Because the module only flags candidates, the Serialized Object Scan settings card shows an alert when the scan is on but the Insecure Deserialization agent skill is off — pointing you to AI Agent → Attack Skills so the detect→confirm loop is not left half-wired. A second note recommends enabling TrafficMind so the agent has captured traffic to confirm against.

Serialized Object Scan is pre-enabled in the web/API/active-focused presets: API Security Audit, Web App Pentester, Bug Bounty - Deep Dive, Parameter & Injection Surface, Full Pipeline - Active Only, and Full Pipeline - Maximum. Every other preset leaves it off.
With AI in Pipeline on, the scan can ask TypeSafe Jev two
questions about each distinct blob it flagged: which serialization format it is (one of the scanner's 13
formats, or none), and how likely it is to be an attacker-reachable deserialization sink. Jev gets the
blob's evidence only: its snippet, where it was seen and how it is encoded. It is never told the format
the signatures matched, nor the marker label that names it, so its format answer is its own reading
rather than the signatures' verdict read back.
Both answers are written onto the candidate: deser_jev_format (with deser_jev_format_confidence)
and deser_jev_exploitability, 0 to 100. The Insecure Deserialization skill reads the pending candidates
most reachable first, a none answer last, and when Jev's format disagrees with the signatures' it lets
the evidence decide which oracle to build. A blob Jev could not answer keeps no deser_jev_* field and
follows the answered ones, so without a token, out of credit or with Jev down, the scan is exactly the
deterministic one, and a later run without Jev clears the fields. Each decision is also recorded in the
recon output (jev_shadow.serialized_assess) and as jev-shadow serialized_assess drawer lines. It never
drops a candidate and never rewrites the matched format, which is part of the candidate's graph id. It needs the
scan itself on, and its control appears in the card once the scan is. Over MCP,
preflight_scope_check reports it as the serialized_assess hook, off while the scan is off.
Serialized Object Scan runs as a passive GROUP 5b step, beside JS
Reconnaissance — after HTTP probing and resource enumeration (so the
corpus it reads is populated), and it runs even when active scans are skipped. In the
Recon Pipeline Workflow view it appears as the Serialized
Objects node (passive badge) in the JS-Recon group, consuming BaseURL + Endpoint
and producing Vulnerability candidates.
It is also available as a single-phase partial recon run from the workflow graph. A
partial run works from what the graph keeps: every stored response header, Set-Cookie
included, keyed by the URL that returned it; each endpoint's parameter names with up to
five sample values; and the names of crawled form fields. Form field values are not in
the graph, so a blob that rides only inside a hidden field's value is a full run's to
find, and a URL you paste in the modal is scanned with no response data.
Pending candidates awaiting confirmation:
MATCH (e:Endpoint)-[:HAS_VULNERABILITY]->(v:Vulnerability {source:'serialized_scan'})
WHERE v.needs_agent_confirmation = true
AND NOT (:ChainFinding)-[:CONFIRMS]->(v)
RETURN e.url, v.id, v.deser_format, v.deser_transport, v.deser_locationThe deser_* properties also appear in the Node Inspector and are filterable there. See
Attack Surface Graph for the :Vulnerability schema.
- Agent Skills — the Insecure Deserialization confirmation skill
- TrafficMind — the capture corpus the agent confirms against
- Priority Board — the info→T4→confirmed→T1 lifecycle
- Recon Presets — which presets enable the scan
- Pentest Reports · Insights Dashboard — where confirmed findings surface
Getting Started
- Getting Started
- Deploying to a Server
- User Management & Roles
- Creating a Project
- Recon Presets
- Global Settings
Core Workflow
- Red Zone
- Recon Pipeline Workflow
- Running Reconnaissance
- Scan Timeline
- AI Agent Guide
- Fireteam — Parallel Specialists
- Exploit-Path Search (LATS)
- Agent Workspace
- Reverse Shells
Scanning & OSINT
- AI in the Recon Pipeline
- Adversarial AI Recon
- AI Gauntlet
- JS Reconnaissance
- GraphQL Security Testing
- Subdomain Takeover Detection
- VHost & SNI Enumeration
- TLS Certificate Grab
- Web Cache Poisoning
- Serialized Object Detection
- Origin Discovery
- GVM Vulnerability Scanning
- GitHub Secret Hunting
- Secret Multiscanner
- Supply-Chain Scanning
AI & Automation
- AI Model Providers
- MCP Tool Plugins
- MCP Server
- Knowledge Base & Web Search
- Agent Skills
- Chat Skills
- Tradecraft Lookup
- CVE Intel
- Playwright Browser Automation
- CypherFix — Automated Remediation
- Priority Board
- Rules of Engagement (RoE)
HackLab
Analysis & Reporting
- Insights Dashboard
- TrafficMind
- Authenticated Session Recording
- proxy_brain — web hacking in code
- Pentest Reports
- Attack Surface Graph
- Surface Shaper
- EvoGraph — Attack Chain Evolution
- Data Export & Import
Contributing
Reference & Help