From 20b2956322ee0a57900097ec5b2feda21db7ed63 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 26 Aug 2022 16:34:06 +0100 Subject: [PATCH] Add webview debugging query --- .../security/WebviewDubuggingEnabledQuery.qll | 43 +++++++++++++++++++ .../CWE/CWE-489/WebviewDebuggingEnabled.ql | 20 +++++++++ 2 files changed, 63 insertions(+) create mode 100644 java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll create mode 100644 java/ql/src/Security/CWE/CWE-489/WebviewDebuggingEnabled.ql diff --git a/java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll b/java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll new file mode 100644 index 00000000000..ca1412886d7 --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll @@ -0,0 +1,43 @@ +/** Definitions for the Android Webview Debugging Enabled query */ + +import java +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.controlflow.Guards +import semmle.code.java.security.SecurityTests + +/** Holds if `ex` looks like a check that this is a debug build. */ +private predicate isDebugCheck(Expr ex) { + exists(Expr subex, string debug | + debug.toLowerCase().matches("%debug%") and + subex.getParent*() = ex + | + subex.(VarAccess).getVariable().getName() = debug + or + subex.(MethodAccess).getMethod().hasName("getProperty") and + subex.(MethodAccess).getAnArgument().(CompileTimeConstantExpr).getStringValue() = debug + ) +} + +/** Configuration to find instances of `setWebContentDebuggingEnabled` called with `true` values. */ +class WebviewDebugEnabledConfig extends DataFlow::Configuration { + WebviewDebugEnabledConfig() { this = "WebviewDebugEnabledConfig" } + + override predicate isSource(DataFlow::Node node) { + node.asExpr().(BooleanLiteral).getBooleanValue() = true + } + + override predicate isSink(DataFlow::Node node) { + exists(MethodAccess ma | + ma.getMethod().hasQualifiedName("android.webkit", "WebView", "setWebContentsDebuggingEnabled") and + node.asExpr() = ma.getArgument(0) + ) + } + + override predicate isBarrier(DataFlow::Node node) { + not node.getType() instanceof BooleanType + or + exists(Guard debug | isDebugCheck(debug) and debug.controls(node.asExpr().getBasicBlock(), _)) + or + node.getEnclosingCallable().getDeclaringType() instanceof NonSecurityTestClass + } +} diff --git a/java/ql/src/Security/CWE/CWE-489/WebviewDebuggingEnabled.ql b/java/ql/src/Security/CWE/CWE-489/WebviewDebuggingEnabled.ql new file mode 100644 index 00000000000..8355ce76412 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-489/WebviewDebuggingEnabled.ql @@ -0,0 +1,20 @@ +/** + * @name Android Webview debugging enabled + * @description Webview debugging should not be enabled in production builds. + * @kind path-problem + * @problem.severity warning + * @security-severity 7.2 + * @id java/android/webview-debugging-enabled + * @tags security + * external/cwe/cwe-489 + * @precision high + */ + +import java +import semmle.code.java.security.WebviewDubuggingEnabledQuery +import semmle.code.java.dataflow.DataFlow +import DataFlow::PathGraph + +from WebviewDebugEnabledConfig conf, DataFlow::PathNode source, DataFlow::PathNode sink +where conf.hasFlowPath(source, sink) +select sink, source, sink, "Webview debugging is enabled here."