rspec/rules/S7409/java/rule.adoc
2025-03-28 20:51:38 +01:00

107 lines
3.1 KiB
Plaintext

include::../description.adoc[]
include::../ask-yourself.adoc[]
:setJavaScriptEnabledSnippet: webSettings.setJavaScriptEnabled(false)
include::../recommended.adoc[]
== Sensitive Code Example
[source,java]
----
public class ExampleActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView webView = new WebView(this);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JavaScriptBridge(), "androidBridge"); // Sensitive
}
public static class JavaScriptBridge {
@JavascriptInterface
public String accessUserData(String userId) {
return getUserData(userId);
}
}
}
----
== Compliant Solution
The most secure option is to disable JavaScript entirely. S6362 further explains why it should not be enabled
unless absolutely necessary.
[source,java]
----
public class ExampleActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView webView = new WebView(this);
webView.getSettings().setJavaScriptEnabled(false);
}
}
----
If possible, remove the JavaScript interface after it is no longer needed, or before loading any untrusted content.
[source,java]
----
public class ExampleActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView webView = new WebView(this);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JavaScriptBridge(), "androidBridge");
// Sometime later, before unsafe content is loaded, remove the JavaScript interface
webView.removeJavascriptInterface("androidBridge");
}
}
----
If a JavaScript bridge must be used, consider using ``WebViewCompat.addWebMessageListener`` instead. This allows you to restrict
the origins that can send messages to the JavaScript bridge.
[source,java]
----
public class ExampleActivity extends AppCompatActivity {
private static final Set<String> ALLOWED_ORIGINS = Collections.singleton("https://example.com");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView webView = new WebView(this);
webView.getSettings().setJavaScriptEnabled(true);
WebViewCompat.addWebMessageListener(
webView,
"androidBridge",
ALLOWED_ORIGINS, // Only allow messages from these origins
new WebMessageListener() {
@Override
public void onPostMessage(
WebView view,
WebMessageCompat message,
Uri sourceOrigin,
boolean isMainFrame,
JavaScriptReplyProxy replyProxy
) {
// Handle the message
}
}
);
}
}
----
include::../see.adoc[]