java.lang.security.audit.sqli.hibernate-sqli.hibernate-sqli

profile photo of semgrepsemgrep
Author
649
Download Count*

Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'.

Run Locally

Run in CI

Defintion

rules:
  - id: hibernate-sqli
    pattern-either:
      - patterns:
          - pattern-either:
              - pattern-inside: |
                  String $SQL = $X + $Y;
                  ...
              - pattern-inside: |
                  String $SQL = String.format(...);
                  ...
              - pattern-inside: |
                  $VAL $FUNC(...,String $SQL,...) {
                  ...
                  }
          - pattern-not-inside: |
              String $SQL = "..." + "...";
              ...
          - pattern: org.hibernate.criterion.Restrictions.sqlRestriction($SQL,...)
      - pattern: org.hibernate.criterion.Restrictions.sqlRestriction(String.format(...),...)
      - patterns:
          - pattern: org.hibernate.criterion.Restrictions.sqlRestriction($X + $Y,...)
          - pattern-not: org.hibernate.criterion.Restrictions.sqlRestriction("..." +
              "...",...)
      - patterns:
          - pattern-either:
              - patterns:
                  - pattern-either:
                      - pattern-inside: |
                          String $SQL = $X + $Y;
                          ...
                      - pattern-inside: |
                          String $SQL = String.format(...);
                          ...
                      - pattern-inside: |
                          $TYPE $FUNC(...,String $SQL,...) {
                            ...
                          }
                  - pattern-not-inside: |
                      String $SQL = "..." + "...";
                      ...
                  - pattern: $SESSION.$METHOD($SQL,...)
              - pattern: |
                  $SESSION.$METHOD(String.format(...),...);
              - pattern: |
                  $SESSION.$METHOD($X + $Y,...);
          - pattern-either:
              - pattern-inside: |
                  org.hibernate.Session $SESSION = ...;
                  ...
              - pattern-inside: |
                  $TYPE $FUNC(...,org.hibernate.Session $SESSION,...) {
                    ...
                  }
          - pattern-not: |
              $SESSION.$METHOD("..." + "...",...);
          - metavariable-regex:
              metavariable: $METHOD
              regex: ^(createQuery|createSQLQuery)$
    message: Detected a formatted string in a SQL statement. This could lead to SQL
      injection if variables in the SQL statement are not properly sanitized.
      Use a prepared statements (java.sql.PreparedStatement) instead. You can
      obtain a PreparedStatement using 'connection.prepareStatement'.
    metadata:
      cwe:
        - "CWE-89: Improper Neutralization of Special Elements used in an SQL
          Command ('SQL Injection')"
      source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SQL_INJECTION_HIBERNATE
      asvs:
        section: V5 Stored Cryptography Verification Requirements
        control_id: 5.3.5 Insecure Custom Algorithm
        control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements
        version: "4"
      category: security
      technology:
        - hibernate
      owasp:
        - A01:2017 - Injection
        - A03:2021 - Injection
      references:
        - https://owasp.org/Top10/A03_2021-Injection
      cwe2022-top25: true
      cwe2021-top25: true
      subcategory:
        - audit
      likelihood: LOW
      impact: HIGH
      confidence: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - SQL Injection
    languages:
      - java
    severity: WARNING

Examples

hibernate-sqli.java

package testcode.sqli;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;

public class HibernateSql {

    public void testQueries(SessionFactory sessionFactory, String input) {

        Session session = sessionFactory.openSession();

        Criteria criteria = session.createCriteria(UserEntity.class);

        // ruleid: hibernate-sqli
        criteria.add(Restrictions.sqlRestriction("test=1234" + input + "zzz"));
        // ruleid: hibernate-sqli
        session.createQuery("select t from UserEntity t where id = " + input);
        // ruleid: hibernate-sqli
        session.createSQLQuery(String.format("select * from TestEntity where id = %s ", input));
        // ruleid: hibernate-sqli
        criteria.add(Restrictions.sqlRestriction("param1  = ? and param2 = " + input,input, StandardBasicTypes.STRING));
        // ruleid: hibernate-sqli
        criteria.add(Restrictions.sqlRestriction("param1  = ? and param2 = " + input,new String[] {input}, new Type[] {StandardBasicTypes.STRING}));

        // ok: hibernate-sqli
        criteria.add(Restrictions.sqlRestriction("test=1234"));

        final String localSafe = "where id=1337";
        // ok: hibernate-sqli
        session.createQuery("select t from UserEntity t " + localSafe);

        final String localSql = "select * from TestEntity " + localSafe;
        // ok: hibernate-sqli
        session.createSQLQuery(localSql);

        // ok: hibernate-sqli
        criteria.add(Restrictions.sqlRestriction("param1  = ?",input, StandardBasicTypes.STRING));
        // ok: hibernate-sqli
        criteria.add(Restrictions.sqlRestriction("param1  = ? and param2 = ?", new String[] {input}, new Type[] {StandardBasicTypes.STRING}));

    }
}