CWE-564 is SQL injection through Hibernate. A developer builds a dynamic query from user input, and an attacker changes what the query means.
A lot of Java teams assume an ORM makes injection impossible. It does not. Hibernate runs whatever query string you hand it. If that string was assembled with concatenation, the ORM is just a longer path to the same bug.
MITRE lists the platforms as SQL and database servers, with Hibernate as the context in the name.
How it happens
Hibernate offers HQL, a query language that resembles SQL. If you build HQL by joining strings, user input becomes part of the query grammar.
MITRE's example uses this pattern:
// Vulnerable: user input concatenated into HQL
String street = getStreetFromUser();
Query query = session.createQuery(
"from Address a where a.street='" + street + "'");
A normal value like Main St works. A value such as x' or '1'='1 changes the where clause so it matches every row. More elaborate input can reach other tables or run additional statements, depending on the database and driver.
The same mistake appears with the criteria API when raw restrictions are used, and with native SQL queries created through the session. The language of the query is different. The cause is not.
Client side checks do not help. MITRE notes that attackers can bypass them by editing values after the checks run, or by changing the client entirely.
What an attacker gains
MITRE lists confidentiality and integrity impact: reading application data and modifying application data.
In practice that means:
- Reading rows the user should never see, such as other customers' records.
- Changing or deleting data.
- Bypassing login logic that relies on a query returning a row.
- Learning the schema, which makes later attacks easier.
The attacker works through your application's database account, so the damage is bounded by that account's privileges. That is why least privilege matters here.
How to find it
The record has no detection list for this entry, so lean on general practice for injection.
- Search the code. Look for
createQuery,createSQLQueryandcreateNativeQuerycalls where the argument contains a+or a formatted string. - Static analysis. SAST tools trace user input to query sinks and flag concatenation.
- Dynamic testing. Send quote characters and boolean payloads to every input that feeds a search or filter and watch for errors or changed results.
- Review logs. Query errors with unexpected quote characters are a signal.
How to fix it
MITRE's mitigations for this entry, in plain steps:
- Use prepared statements that bind variables. MITRE warns that prepared statements which do not bind variables can still be vulnerable. Binding is the point.
- Use allowlist checking on input. Rather than escaping metacharacters, define the narrow set of safe characters for the expected value and reject the rest.
- Apply least privilege to database accounts. If users may only read and modify their own data, the account should not be able to touch other data where the design allows it.
- Duplicate client side checks on the server. Anything checked in the browser must be checked again on the server.
- Where requirements allow, consider a non-SQL database that is not subject to this flaw.
The fix in code is a named parameter:
// Fixed: bound parameter
Query query = session.createQuery(
"from Address a where a.street = :street");
query.setParameter("street", street);
Hibernate sends the value separately from the query text, so quote characters are data, not syntax.
Do not build the fix out of manual escaping. It is easy to miss a case, and the database layer behaves differently across vendors.
ORMs are also dependencies. Hibernate itself has had its own advisories over the years, so the version in your build matters as well as the way you call it. The free scan at gold.safeguard.sh/scan lists the libraries in a manifest with no login, keeps your file on your machine, and handles up to 100 dependencies.
Try it yourself
Click through it at your own pace, or open it full screen.
Quick check
Does using Hibernate prevent SQL injection?
No. If you build HQL or native SQL by concatenating user input, you are vulnerable. Bound parameters are what protect you.
Is a prepared statement always safe?
Only if variables are bound. MITRE notes that prepared statements that do not bind variables can still be attacked.
Why limit database account privileges?
If an injection still slips through, the attacker is limited to what the account can do.