# Drupal 7 pre auth sql injection and remote code execution

Drupal 7 expandArguments mishandles non-integer array keys in IN clauses, enabling pre-auth SQL injection and PHP code execution via forged session.

- Payout: hidden
- Severity: critical
- Program: Internet Bug Bounty
- Found by: shorst
- Disclosed: 2015-04-06
- CVE: CVE-2014-3704
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/31756
- Library page: https://bugbountylibrary.com/r/h1%3A31756
- Tags: area:web domain:web impact:ato impact:rce kind:bounty platform:hackerone sev:critical tech:php technique:chained technique:source-review vuln:rce vuln:sqli

**Target:** Drupal 7 database abstraction layer (expandArguments / db_query)
**Root cause:** expandArguments builds placeholder names from array keys assuming integer indices; string keys containing SQL syntax are concatenated into the query, breaking out of the IN clause.
**Steps:**
1. Call db_query with an IN placeholder whose array has a string key containing SQL, e.g. `array(':name'=>array('test) -- ' => 'user1','test' => 'user2'))`
2. expandArguments generates `SELECT * FROM users WHERE name IN (:name_test) -- , :name_test )`
3. Because PDO allows multi-queries, inject INSERT/UPDATE/DROP statements
4. Insert a forged session row granting uid 1 (admin) or use callbacks to execute PHP
**How found:** Code review of Drupal's prepared-statement helper: noticed expandArguments assumes integer array keys and concatenates keys into placeholder names, then tested a string key containing SQL comment syntax.
**Exploitation:** Unauthenticated attacker sends a crafted request to a Drupal endpoint that passes user-controlled array keys into an IN clause; injected multi-query INSERTs a session record with admin privileges, then a second request (or callback feature) executes arbitrary PHP.
**Escalation:** SQL injection chained to arbitrary INSERT of a forged admin session, then to PHP code execution via Drupal callbacks.
**Insight:** Prepared-statement wrappers that build placeholder names from array keys are injectable when keys are attacker-controlled; test IN-clause expanders with string keys containing `) -- ` and similar.

## Proof of concept (copied exactly from the original report)

**db_query with malicious array keys producing injection**

```
db_query("SELECT * FROM {users} where name IN (:name)", array(':name'=>array('test) -- ' => 'user1','test' => 'user2')));

this results in an exploitable SQL query:

     SELECT * FROM users WHERE name IN (:name_test) -- , :name_test )
```

**expandArguments placeholder key construction loop**

```
foreach ($data as $i => $value) {
          [...]
          $new_keys[$key . '_' . $i] = $value;
```

