Merge pull request #10241 from joefarebrother/android-webview-dubugging

Java: Add query for WebView debugging enabled
This commit is contained in:
Joe Farebrother
2022-09-28 10:50:51 +01:00
committed by GitHub
17 changed files with 143 additions and 1 deletions

View File

@@ -0,0 +1,41 @@
/** 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%", "%test%"]) and
subex.getParent*() = ex
|
subex.(VarAccess).getVariable().getName() = debug
or
subex.(MethodAccess).getMethod().hasName("getProperty") and
subex.(MethodAccess).getAnArgument().(CompileTimeConstantExpr).getStringValue() = debug
)
}
/** A 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) {
exists(Guard debug | isDebugCheck(debug) and debug.controls(node.asExpr().getBasicBlock(), _))
or
node.getEnclosingCallable().getDeclaringType() instanceof NonSecurityTestClass
}
}

View File

@@ -0,0 +1,7 @@
// BAD - debugging is always enabled
WebView.setWebContentsDebuggingEnabled(true);
// GOOD - debugging is only enabled when this is a debug build, as indicated by the debuggable flag being set.
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE)) {
WebView.setWebContentsDebuggingEnabled(true);
}

View File

@@ -0,0 +1,36 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>The <code>WebView.setWebContentsDebuggingEnabled</code> method enables or disables the contents of any <code>WebView</code> in the application to be debugged.</p>
<p>You should only enable debugging features during development. When you create a production build, you should disable it. If you enable debugging features, this can make your code vulnerable by adding entry points, or leaking sensitive information.</p>
</overview>
<recommendation>
<p>Ensure that debugging features are not enabled in production builds, such as by guarding calls to <code>WebView.setWebContentsDebuggingEnabled(true)</code> by a flag that is only enabled in debug builds. </p>
</recommendation>
<example>
<p>In the first (bad) example, WebView debugging is always enabled.
whereas the GOOD case only enables it if the <code>android:debuggable</code> attribute is set to <code>true</code>.</p>
<sample src="WebviewDebuggingEnabled.java" />
</example>
<references>
<li>
Android Developers:
<a href="https://developer.android.com/reference/android/webkit/WebView.html#setWebContentsDebuggingEnabled(boolean)">setWebContentsDebuggingEnabled</a>.
</li>
<li>
Android Developers:
<a href="https://developer.chrome.com/docs/devtools/remote-debugging/webviews/">Remote debugging WebViews</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,19 @@
/**
* @name Android Webview debugging enabled
* @description Enabling Webview debugging in production builds can expose entry points or leak sensitive information.
* @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 DataFlow::PathGraph
from WebviewDebugEnabledConfig conf, DataFlow::PathNode source, DataFlow::PathNode sink
where conf.hasFlowPath(source, sink)
select sink, source, sink, "Webview debugging is enabled."

View File

@@ -0,0 +1,4 @@
---
category: newQuery
---
* Added a new query, `java/android/webview-debugging-enabled`, to detect instances of WebView debugging being enabled in production builds.

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/google-android-9.0.0

View File

@@ -0,0 +1,23 @@
import android.webkit.WebView;
class Test {
boolean DEBUG_BUILD;
void test1() {
WebView.setWebContentsDebuggingEnabled(true); // $hasValueFlow
}
void test2(){
if (DEBUG_BUILD) {
WebView.setWebContentsDebuggingEnabled(true);
}
}
void test3(boolean enabled){
WebView.setWebContentsDebuggingEnabled(enabled); // $hasValueFlow
}
void test4(){
test3(true);
}
}

View File

@@ -0,0 +1,11 @@
import java
import TestUtilities.InlineFlowTest
import semmle.code.java.security.WebviewDubuggingEnabledQuery
class HasFlowTest extends InlineFlowTest {
override DataFlow::Configuration getTaintFlowConfig() { none() }
override DataFlow::Configuration getValueFlowConfig() {
result = any(WebviewDebugEnabledConfig c)
}
}

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/google-android-9.0.0
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/google-android-9.0.0