Automated Threat Modeling

Ghidra BSim SQL Injection (CVE-2026-49498): Brief Summary of PostgreSQL Privilege Escalation via Unescaped Usernames

A brief summary of CVE-2026-49498, a high-severity SQL injection in Ghidra's BSim password change flow that lets authenticated users escalate to PostgreSQL superuser privileges. Includes patch analysis and affected-version details.

CVE Analysis

9 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-06-10

Ghidra BSim SQL Injection (CVE-2026-49498): Brief Summary of PostgreSQL Privilege Escalation via Unescaped Usernames
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

A SQL injection flaw in the NSA's Ghidra reverse engineering framework lets any authenticated BSim user escalate to PostgreSQL superuser privileges. The attacker injects SQL commands through a crafted username in the password change flow. Thousands of security researchers, malware analysts, and government teams rely on Ghidra's BSim feature for binary function similarity analysis, and for them this bug turns a routine credential change into a path to full database compromise.

Ghidra is a free, open-source software reverse engineering framework developed by the National Security Agency and publicly released in 2019. It has over 61,000 GitHub stars, is widely used by government agencies, private sector security teams, and independent researchers, and is the main free alternative to commercial tools like IDA Pro. BSim, the affected component, is Ghidra's built-in function similarity search framework. It uses a PostgreSQL backend to store and query binary function signatures.

Technical information

Root cause

The vulnerability is in the changePassword() method of the PostgresFunctionDatabase class in Ghidra's BSim feature. This method builds SQL ALTER ROLE statements with string interpolation, inserting the username directly between double-quote delimiters without any escaping.

Here is the vulnerable code from Ghidra 12.0.4 and earlier:

// VULNERABLE — Ghidra 12.0.4 and earlier buffer.append("ALTER ROLE \""); buffer.append(username); // username inserted verbatim, no escaping! buffer.append("\" WITH PASSWORD '"); for (char ch : newPassword) { if (ch == '\'') { buffer.append(ch); // manual single-quote doubling for password } buffer.append(ch); } buffer.append('\'');

The two inputs are treated differently. The password gets manual single-quote escaping, but the username is concatenated between double-quote delimiters with no escaping at all. A username containing a literal double quote character (") breaks out of the identifier quoting and allows arbitrary SQL injection into the ALTER ROLE statement.

Attack flow

The full CVSS v4.0 vector string is CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N. It describes a network-accessible, low-complexity attack with high impact on confidentiality, integrity, and availability.

The attack runs in four steps:

  1. The attacker authenticates to the BSim server with any valid user credentials. This is the only prerequisite, and any user with BSim access qualifies.

  2. The attacker sends a PasswordChange network message with a crafted username parameter containing embedded double quotes. For example, a username such as user"; CREATE ROLE attacker SUPERUSER;-- would break out of the intended ALTER ROLE statement and inject a second command that creates a superuser account.

  3. The PostgresFunctionDatabase.changePassword() method interpolates the malicious username into the ALTER ROLE statement and executes it against the PostgreSQL backend, without parameterized queries or prepared statements.

  4. The injected SQL commands run with the privileges of the database connection the BSim server uses. A successful injection lets the attacker escalate to PostgreSQL superuser status, which means full control over the database. The attacker can read, modify, or delete all data, create new database users, and run administrative functions.

CVSS scoring

MetricCVSS v3.xCVSS v4.0
Base Score8.8 (High)8.7 (High)
Attack VectorNetworkNetwork
Attack ComplexityLowLow
Privileges RequiredLowLow
User InteractionNoneNone
Confidentiality ImpactHighHigh (VC:H)
Integrity ImpactHighHigh (VI:H)
Availability ImpactHighHigh (VA:H)

The CNA (VulnCheck) assessed the CVSS v4.0 score at 8.7, and the CVSS v3.x score is 8.8. Both describe a network-accessible, low-complexity, authenticated privilege escalation with high system impact.

Security bulletin SB20260515104 identifies a second, distinct SQL injection vulnerability in the BSim search filter types. This flaw fails to neutralize special elements in XML protocol messages sent over the BSim network query protocol, which allows injection of arbitrary SQL commands through a different attack surface. Organizations addressing CVE-2026-49498 should evaluate this related flaw as well.

Patch information

The vulnerability was fixed in Ghidra 12.1, released on May 13, 2026. The GitHub Security Advisory GHSA-vv7r-2rhf-5h7g explicitly lists the patched version as 12.1, and VulnCheck independently confirms the affected range as Ghidra 11.0 through versions prior to 12.1.

The patch targets the changePassword() method in Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/PostgresFunctionDatabase.java. Here is the patched version from Ghidra 12.1:

// PATCHED — Ghidra 12.1 buffer.append("ALTER ROLE "); Utils.escapeIdentifier(buffer, username); // proper identifier escaping buffer.append(" WITH PASSWORD '"); Utils.escapeLiteral(buffer, new String(newPassword), true); // proper literal escaping buffer.append('\'');

The fix makes two changes:

  1. For the username, the code no longer wraps the raw value in double quotes by hand. It calls org.postgresql.core.Utils.escapeIdentifier(), the PostgreSQL JDBC driver's built-in utility, which escapes any embedded double quote characters by doubling them (e.g., my"user becomes "my""user"). That is the correct way to embed identifiers safely in PostgreSQL SQL statements. The patch adds an import for org.postgresql.core.Utils to support this.

  2. For the password, the hand-rolled single-quote escaping loop is replaced with Utils.escapeLiteral(), the matching PostgreSQL JDBC utility for escaping string literals. The old manual escaping was functionally adequate, but the library function is more robust and consistent.

This is a textbook example of replacing ad hoc string escaping with well-tested library functions, a practice that eliminates an entire class of injection bugs. Users running Ghidra 11.0 through 12.0.x with a BSim PostgreSQL backend should upgrade to Ghidra 12.1 (or the latest 12.1.2 release) to apply this fix.

You can compare the vulnerable and patched source files directly:

Affected systems and versions

The vulnerability affects Ghidra versions 11.0 through 12.0.x (inclusive). Any Ghidra installation that uses the BSim feature with a PostgreSQL database backend is vulnerable. Installations using BSim with other database backends, and installations not using BSim at all, are not affected by this specific flaw.

The patched version is Ghidra 12.1, released May 13, 2026. The latest available release at the time of writing is Ghidra 12.1.2.

Vendor security history

Ghidra's past advisories show a recurring pattern of injection and trust-boundary vulnerabilities:

  • CVE-2019-16941: An early vulnerability that let attackers compromise exposed systems while Ghidra's experimental mode was running, a risk that came from the tool's network-facing features.
  • GHSA-j3xg-fc2p-4jc4 (Log4j): A remote code injection vulnerability in the Log4j library, from the Log4Shell crisis.
  • GHSA-cqfj-5crw-rh6p (Command Injection in launch.sh): A command injection flaw where user-provided command-line arguments were passed to the Java application launch without sanitization.
  • CVE-2026-4946 (Command Execution via Auto Generated Comments): Discovered by AHA! (Austin Hackers Anonymous) and the Mobasi Security Team, this high-severity flaw (CVSS 8.8) let a malicious binary trigger arbitrary command execution when an analyst clicked on auto-generated comments. The CFStringAnalyzer extracted strings from Mach-O binaries, and Annotation.java interpreted @execute directives, running commands via ProcessBuilder without confirmation. Patched in Ghidra 12.0.3.
  • SB20260515104 (Nine Vulnerabilities, May 2026): The current cluster includes two SQL injection flaws (one of them CVE-2026-49498), command injection in URL annotation handling, improper cryptographic signature verification in PKIAuthenticationModule.authenticate(), deserialization of untrusted data in shared project connections, denial of service via ExportTrie.parseTrie(), path traversal in SameDirDebugInfoProvider, and two use-after-free vulnerabilities in decompilation code.

The NSA has followed a responsible disclosure and patching process, publishing security advisories through GitHub and coordinating with external researchers. Internal NSA development staff published the advisory for GHSA-vv7r-2rhf-5h7g, and external organizations such as Oceanit have also helped identify and resolve vulnerabilities. The researcher credited with discovering CVE-2026-49498 is Sean Nejad (@allsmog).

The NSA's Ghidra page acknowledges the risk directly. It states that "there are known security vulnerabilities within certain versions of Ghidra" and advises users to review security advisories before proceeding.

References

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Gerrit
  • CVS
  • Jira
  • Linear
  • Slack
  • Security Compass
Explore integrations
Security magnifying glass visualization