# Unauthenticated RCE in Vaultpress

VaultPress's validate_api_signature treats openssl_verify's -1 error return as truthy, letting an attacker bypass signature checks and reach RCE.

- Payout: hidden
- Severity: critical
- Program: Automattic
- Found by: b258ea62bf297b02afa9854
- Disclosed: 2017-09-15
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/236552
- Library page: https://bugbountylibrary.com/r/h1%3A236552
- Tags: area:oss domain:oss impact:ato impact:rce kind:bounty platform:hackerone sev:critical tech:php tech:wordpress technique:source-review vuln:auth-bypass vuln:rce

**Target:** WordPress plugin VaultPress API signature validation endpoint
**Root cause:** openssl_verify returns int(-1) on error, and the code checks the result with a loose truthiness test instead of strict ===1, so an error is treated as a valid signature.
**Steps:**
1. Request the WordPress install with `?vaultpress=true` to reach the API handler.
2. Ensure firewall is disabled/bypassed so validate_api_signature runs.
3. Generate two keypairs with `php genkey1.php` and `php genkey2.php`.
4. Run `php PoC.php` to craft a signature of a different key type that makes openssl_verify return -1.
5. Send the request with the crafted `sslsig` post parameter; openssl_verify returns -1 which is truthy, bypassing validation.
**How found:** Reading validate_api_signature, noticed openssl_verify's documented three return values (1/0/-1) and that the code used a truthy if instead of strict comparison, then reasoned a key-type mismatch would force the -1 error path.
**Exploitation:** Attacker supplies a base64 `sslsig` derived from a mismatched key type so openssl_verify errors (-1); the truthy check passes, granting authenticated API access and leading to RCE.
**Escalation:** Signature bypass grants access to privileged VaultPress API methods, escalating to remote code execution.
**Insight:** When auditing PHP crypto checks, look for loose truthiness on functions with tri-state returns (openssl_verify, strcmp, etc.); forcing the error return (-1) via type/key mismatch bypasses the check entirely.

