diff options
author | Mark <mteffeteller@google.com> | 2023-06-21 22:47:10 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-06-21 22:47:10 +0000 |
commit | e73be1680dae58cb83d869104def1c59102d59b2 (patch) | |
tree | 68cf332a40b94b2d28b256b19b916f99220bb0c4 /sanitizers/src/main/java/com/code_intelligence/jazzer/sanitizers/SqlInjection.kt | |
parent | ba37c2e361c2ba91bacc47fcae5383c52e50f6be (diff) | |
parent | 34a8e5c8aa0e14c79803a61c3eb7a66436482b18 (diff) | |
download | jazzer-api-e73be1680dae58cb83d869104def1c59102d59b2.tar.gz |
Sync jazzer in AOSP with upstream repo (new SHA: 30decf81a147c66fa5a098072c38ab6924ba0aa6) am: 9350e0ab03 am: 99d9a79746 am: 34a8e5c8aa
Original change: https://android-review.googlesource.com/c/platform/external/jazzer-api/+/2627336
Change-Id: I0f00e1cd356d2e6c7dc1b744fea8a898fd5714c6
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'sanitizers/src/main/java/com/code_intelligence/jazzer/sanitizers/SqlInjection.kt')
-rw-r--r-- | sanitizers/src/main/java/com/code_intelligence/jazzer/sanitizers/SqlInjection.kt | 113 |
1 files changed, 0 insertions, 113 deletions
diff --git a/sanitizers/src/main/java/com/code_intelligence/jazzer/sanitizers/SqlInjection.kt b/sanitizers/src/main/java/com/code_intelligence/jazzer/sanitizers/SqlInjection.kt deleted file mode 100644 index f317bcc8..00000000 --- a/sanitizers/src/main/java/com/code_intelligence/jazzer/sanitizers/SqlInjection.kt +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2022 Code Intelligence GmbH -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.code_intelligence.jazzer.sanitizers - -import com.code_intelligence.jazzer.api.FuzzerSecurityIssueHigh -import com.code_intelligence.jazzer.api.HookType -import com.code_intelligence.jazzer.api.Jazzer -import com.code_intelligence.jazzer.api.MethodHook -import com.code_intelligence.jazzer.api.MethodHooks -import net.sf.jsqlparser.JSQLParserException -import net.sf.jsqlparser.parser.CCJSqlParserUtil -import java.lang.invoke.MethodHandle - -/** - * Detects SQL injections. - * - * Untrusted input has to be escaped in such a way that queries remain valid otherwise an injection - * could be possible. This sanitizer guides the fuzzer to inject insecure characters. If an exception - * is raised during execution the fuzzer was able to inject an invalid pattern, otherwise all input - * was escaped correctly. - * - * Two types of methods are hooked: - * 1. Methods that take an SQL query as the first argument (e.g. [java.sql.Statement.execute]). - * 2. Methods that don't take any arguments and execute an already prepared statement - * (e.g. [java.sql.PreparedStatement.execute]). - * For 1. we validate the syntax of the query using <a href="https://github.com/JSQLParser/JSqlParser">jsqlparser</a> - * and if both the syntax is invalid and the query execution throws an exception we report an SQL injection. - * Since we can't reliably validate SQL queries in arbitrary dialects this hook is expected to produce some - * amount of false positives. - * For 2. we can't validate the query syntax and therefore only rethrow any exceptions. - */ -@Suppress("unused_parameter", "unused") -object SqlInjection { - - // Characters that should be escaped in user input. - // See https://dev.mysql.com/doc/refman/8.0/en/string-literals.html - private const val CHARACTERS_TO_ESCAPE = "'\"\b\n\r\t\\%_" - - private val SQL_SYNTAX_ERROR_EXCEPTIONS = listOf( - "java.sql.SQLException", - "java.sql.SQLNonTransientException", - "java.sql.SQLSyntaxErrorException", - "org.h2.jdbc.JdbcSQLSyntaxErrorException", - ) - - @MethodHooks( - MethodHook(type = HookType.REPLACE, targetClassName = "java.sql.Statement", targetMethod = "execute"), - MethodHook(type = HookType.REPLACE, targetClassName = "java.sql.Statement", targetMethod = "executeBatch"), - MethodHook(type = HookType.REPLACE, targetClassName = "java.sql.Statement", targetMethod = "executeLargeBatch"), - MethodHook(type = HookType.REPLACE, targetClassName = "java.sql.Statement", targetMethod = "executeLargeUpdate"), - MethodHook(type = HookType.REPLACE, targetClassName = "java.sql.Statement", targetMethod = "executeQuery"), - MethodHook(type = HookType.REPLACE, targetClassName = "java.sql.Statement", targetMethod = "executeUpdate"), - MethodHook( - type = HookType.REPLACE, - targetClassName = "javax.persistence.EntityManager", - targetMethod = "createNativeQuery" - ) - ) - @JvmStatic - fun checkSqlExecute(method: MethodHandle, thisObject: Any?, arguments: Array<Any>, hookId: Int): Any { - var hasValidSqlQuery = false - - if (arguments.isNotEmpty() && arguments[0] is String) { - val query = arguments[0] as String - hasValidSqlQuery = isValidSql(query) - Jazzer.guideTowardsContainment(query, CHARACTERS_TO_ESCAPE, hookId) - } - return try { - method.invokeWithArguments(thisObject, *arguments) - } catch (throwable: Throwable) { - // If we already validated the query string and know it's correct, - // The exception is likely thrown by a non-existent table or something - // that we don't want to report. - if (!hasValidSqlQuery && SQL_SYNTAX_ERROR_EXCEPTIONS.contains(throwable.javaClass.name)) { - Jazzer.reportFindingFromHook( - FuzzerSecurityIssueHigh( - """ - SQL Injection - Injected query: ${arguments[0]} - """.trimIndent(), - throwable - ) - ) - } - throw throwable - } - } - - private fun isValidSql(sql: String): Boolean = - try { - CCJSqlParserUtil.parseStatements(sql) - true - } catch (e: JSQLParserException) { - false - } catch (t: Throwable) { - // Catch any unexpected exceptions so that we don't disturb the - // instrumented application. - t.printStackTrace() - true - } -} |