-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Update test and add new demos for screenshot prevention in Android #3457
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
cpholguera
wants to merge
31
commits into
master
Choose a base branch
from
more-android-screenshots-testing
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 14 commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
bb3bb4d
Enhance documentation on screenshot handling in Android, detailing sy…
cpholguera fff4ec9
Revise guidelines on preventing sensitive data capture, detailing ris…
cpholguera a9e5cbc
Add additional rules for FLAG_SECURE handling and recents screenshot …
cpholguera 870fca7
Add guidelines for identifying sensitive screens during testing
cpholguera 875244f
Update FLAG_SECURE usage examples and documentation in Android MASTG-…
cpholguera 1a66957
Add new MASTG-DEMO-0062 for setRecentsScreenshotEnabled in Android 14+
cpholguera 6604db3
Add new MASTG-DEMO-0063 for Jetpack Compose Dialogs
cpholguera fa08647
Remove redundant rules for recents screenshot enabled/disabled in sen…
cpholguera 771a7fc
Enhance documentation for screen capture prevention APIs, including d…
cpholguera 81c6310
rm extra ref to file
cpholguera c58f7b3
Merge branch 'master' of https://github.com/OWASP/owasp-mastg into mo…
cpholguera 7af35bd
refine documentation on FLAG_SECURE usage for Android UI components
cpholguera a6bbca3
refine wording and clarity in MASTG-TEST-0291.md regarding FLAG_SECUR…
cpholguera e4d8754
fix regex
cpholguera 1c3369a
Split best practices for preventing screenshots in Android apps.
cpholguera 4a483b4
Split tests for preventing screenshots in Android apps.
cpholguera 3250c83
Fix test refs
cpholguera de7c3a0
add refs
cpholguera 3111eda
link best to knowledge
cpholguera 3c6eb43
Clarify wording in MASTG-TEST-0291.md for better readability
cpholguera 13975cb
Add best practice for non-caching input types in sensitive fields
cpholguera 1d946d8
Update MASTG-BEST-0018.md to clarify usage of SecureFlagPolicy.Secure…
cpholguera 01e9d69
Add reference to overlay attack warnings and improve wording in MASTG…
cpholguera 83c1346
Correct MASTG-KNOW-0053 location
cpholguera 8d83288
Update MASTG-KNOW-0022.md to correct Tapjacking reference and add bes…
cpholguera 532d4a1
Update best practices and knowledge documents for screenshot preventi…
cpholguera 07a89e6
Add MASTG-KNOW-0107.md for screenshots and screen recording detection…
cpholguera 5c8a99e
fix indentation
cpholguera d9ff8d4
Merge branch 'master' into more-android-screenshots-testing
cpholguera a95e414
Apply suggestions from code review
cpholguera b18f69c
Merge branch 'master' of https://github.com/OWASP/owasp-mastg into mo…
cpholguera File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 15 additions & 5 deletions
20
demos/android/MASVS-PLATFORM/MASTG-DEMO-0061/MASTG-DEMO-0061.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,41 @@ | ||
--- | ||
platform: android | ||
title: Uses of FLAG_SECURE with semgrep | ||
title: Setting and Clearing FLAG_SECURE in an Activity and Dialog with semgrep | ||
id: MASTG-DEMO-0061 | ||
code: [kotlin] | ||
test: MASTG-TEST-0291 | ||
--- | ||
|
||
### Sample | ||
|
||
The sample uses the `addFlags` method to set the `FLAG_SECURE` window flag on an activity that displays sensitive data. | ||
The sample demonstrates multiple ways of preventing screenshots of sensitive content in two Android components: an Activity and a standard Dialog. It also demonstrates incorrect ways of removing the screenshot prevention. | ||
|
||
{{ MastgTest.kt # MastgTest_reversed.java }} | ||
|
||
### Steps | ||
|
||
Let's run our @MASTG-TOOL-0110 rule against the reversed java code. | ||
Let's run our @MASTG-TOOL-0110 rule against the reversed Java code. | ||
|
||
{{ ../../../../rules/mastg-android-sensitive-data-in-screenshot.yml }} | ||
|
||
{{ run.sh }} | ||
|
||
### Observation | ||
|
||
The rule has identified one location in the code file where the app has set the `FLAG_SECURE` window flag using the `addFlags` method. | ||
The rule has identified several locations in the code file where the app sets or clears the `FLAG_SECURE` window flag. | ||
|
||
{{ output.txt }} | ||
|
||
### Evaluation | ||
|
||
This test passes because the app used the `addFlags` method to set the `FLAG_SECURE` window flag on an activity that displays sensitive data. | ||
The test fails because even though the app demonstrates correct protection patterns by setting `FLAG_SECURE` for an Activity and a dialog, it subsequently removes protection by clearing/overwriting `FLAG_SECURE` on both the Activity and the dialog. | ||
|
||
We can see this in `MastgTest_reversed.java`: | ||
|
||
- For the activity: | ||
- it adds the `FLAG_SECURE` flag via `getWindow().addFlags(8192)` (line 35) | ||
- sets it again with `getWindow().setFlags(8192, 8192)` (line 36) | ||
- and then immediately clears it with `getWindow().setFlags(0, 8192)` (line 37) | ||
- For the dialog: | ||
- it sets `window.setFlags(8192, 8192)` (line 42) | ||
- and then calls `window2.clearFlags(8192)` (line 46) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,29 @@ | ||
|
||
|
||
┌────────────────┐ | ||
│ 1 Code Finding │ | ||
└────────────────┘ | ||
┌─────────────────┐ | ||
│ 5 Code Findings │ | ||
└─────────────────┘ | ||
|
||
MastgTest_reversed.java | ||
❱ rules.mastg-android-flag-secure-enable-flags | ||
[MASVS-PLATFORM] Make sure you use this flag for all screens with sensitive data | ||
|
||
32┆ ((Activity) this.context).getWindow().addFlags(8192); | ||
35┆ ((Activity) this.context).getWindow().addFlags(8192); | ||
⋮┆---------------------------------------- | ||
36┆ ((Activity) this.context).getWindow().setFlags(8192, 8192); | ||
|
||
❯❱ rules.mastg-android-flag-secure-clear-flags | ||
[MASVS-PLATFORM] Window clears or overwrites FLAG_SECURE. | ||
|
||
37┆ ((Activity) this.context).getWindow().setFlags(0, 8192); | ||
|
||
❱ rules.mastg-android-flag-secure-enable-flags | ||
[MASVS-PLATFORM] Make sure you use this flag for all screens with sensitive data | ||
|
||
42┆ window.setFlags(8192, 8192); | ||
|
||
❯❱ rules.mastg-android-flag-secure-clear-flags | ||
[MASVS-PLATFORM] Window clears or overwrites FLAG_SECURE. | ||
|
||
46┆ window2.clearFlags(8192); | ||
|
31 changes: 31 additions & 0 deletions
31
demos/android/MASVS-PLATFORM/MASTG-DEMO-0062/MASTG-DEMO-0062.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
--- | ||
platform: android | ||
title: Enabling Screenshots in Recents via setRecentsScreenshotEnabled with semgrep | ||
id: MASTG-DEMO-0062 | ||
code: [kotlin] | ||
test: MASTG-TEST-0291 | ||
--- | ||
|
||
### Sample | ||
|
||
The sample demonstrates how an app does not prevent screenshots/leaks of sensitive content in Android 14+ recents via calls to `setRecentsScreenshotEnabled(true)`. | ||
|
||
{{ MastgTest.kt # MastgTest_reversed.java }} | ||
|
||
### Steps | ||
|
||
Let's run our @MASTG-TOOL-0110 rule against the reversed Java code. | ||
|
||
{{ ../../../../rules/mastg-android-sensitive-data-in-screenshot.yml }} | ||
|
||
{{ run.sh }} | ||
|
||
### Observation | ||
|
||
The rule has identified one location in the code file where the app calls `setRecentsScreenshotEnabled()`. | ||
|
||
{{ output.txt }} | ||
|
||
### Evaluation | ||
|
||
The test fails because the app calls `setRecentsScreenshotEnabled(true)` on Android 14+, which allows screenshots in recents and may lead to sensitive data exposure. The app does not use `FLAG_SECURE` or any other screenshot prevention mechanism. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package org.owasp.mastestapp | ||
|
||
import android.app.Activity | ||
import android.content.Context | ||
import android.os.Build | ||
|
||
class MastgTest (private val context: Context){ | ||
|
||
var shouldRunInMainThread: Boolean = true | ||
|
||
fun mastgTest(): String { | ||
if (context is Activity) { | ||
|
||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { | ||
context.setRecentsScreenshotEnabled(true) | ||
} | ||
else { | ||
return "ERROR: The setRecentsScreenshotEnabled() method is not available on Android versions below 34." | ||
} | ||
|
||
return "SUCCESS!!\n\nThe setRecentsScreenshotEnabled() method has been set to true." | ||
} else { | ||
return "ERROR: Context is not an Activity" | ||
} | ||
|
||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
demos/android/MASVS-PLATFORM/MASTG-DEMO-0062/MastgTest_reversed.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package org.owasp.mastestapp; | ||
|
||
import android.app.Activity; | ||
import android.content.Context; | ||
import android.os.Build; | ||
import kotlin.Metadata; | ||
import kotlin.jvm.internal.Intrinsics; | ||
|
||
/* compiled from: MastgTest.kt */ | ||
@Metadata(d1 = {"\u0000 \n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0003\n\u0002\u0010\u000b\n\u0002\b\u0005\n\u0002\u0010\u000e\n\u0000\b\u0007\u0018\u00002\u00020\u0001B\u000f\u0012\u0006\u0010\u0002\u001a\u00020\u0003¢\u0006\u0004\b\u0004\u0010\u0005J\u0006\u0010\f\u001a\u00020\rR\u000e\u0010\u0002\u001a\u00020\u0003X\u0082\u0004¢\u0006\u0002\n\u0000R\u001a\u0010\u0006\u001a\u00020\u0007X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\b\u0010\t\"\u0004\b\n\u0010\u000b¨\u0006\u000e"}, d2 = {"Lorg/owasp/mastestapp/MastgTest;", "", "context", "Landroid/content/Context;", "<init>", "(Landroid/content/Context;)V", "shouldRunInMainThread", "", "getShouldRunInMainThread", "()Z", "setShouldRunInMainThread", "(Z)V", "mastgTest", "", "app_debug"}, k = 1, mv = {2, 0, 0}, xi = 48) | ||
/* loaded from: classes3.dex */ | ||
public final class MastgTest { | ||
public static final int $stable = 8; | ||
private final Context context; | ||
private boolean shouldRunInMainThread; | ||
|
||
public MastgTest(Context context) { | ||
Intrinsics.checkNotNullParameter(context, "context"); | ||
this.context = context; | ||
this.shouldRunInMainThread = true; | ||
} | ||
|
||
public final boolean getShouldRunInMainThread() { | ||
return this.shouldRunInMainThread; | ||
} | ||
|
||
public final void setShouldRunInMainThread(boolean z) { | ||
this.shouldRunInMainThread = z; | ||
} | ||
|
||
public final String mastgTest() { | ||
if (this.context instanceof Activity) { | ||
if (Build.VERSION.SDK_INT >= 34) { | ||
((Activity) this.context).setRecentsScreenshotEnabled(true); | ||
return "SUCCESS!!\n\nThe setRecentsScreenshotEnabled() method has been set to true."; | ||
} | ||
return "ERROR: The setRecentsScreenshotEnabled() method is not available on Android versions below 34."; | ||
} | ||
return "ERROR: Context is not an Activity"; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
|
||
|
||
┌────────────────┐ | ||
│ 1 Code Finding │ | ||
└────────────────┘ | ||
|
||
MastgTest_reversed.java | ||
❯❱ rules.android-set-recents-screenshot | ||
[MASVS-PLATFORM] Application controls whether recents screenshots are enabled. | ||
|
||
34┆ ((Activity) this.context).setRecentsScreenshotEnabled(true); | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
NO_COLOR=true semgrep -c ../../../../rules/mastg-android-sensitive-data-in-screenshot.yml ./MastgTest_reversed.java > output.txt |
31 changes: 31 additions & 0 deletions
31
demos/android/MASVS-PLATFORM/MASTG-DEMO-0063/MASTG-DEMO-0063.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
--- | ||
platform: android | ||
title: Incorrectly Preventing Screenshots with SecureFlagPolicy in Compose Dialogs with semgrep | ||
id: MASTG-DEMO-0063 | ||
code: [kotlin] | ||
test: MASTG-TEST-0291 | ||
--- | ||
|
||
### Sample | ||
|
||
The sample demonstrates how an app allows screenshots/leaks of sensitive content by misusing screenshot prevention APIs in a Jetpack Compose dialog that uses `DialogProperties(securePolicy = SecureFlagPolicy.SecureOff)`. | ||
|
||
{{ MastgTest.kt # MastgTest_reversed.java # MastgTestKt_reversed.java }} | ||
|
||
### Steps | ||
|
||
Let's run our @MASTG-TOOL-0110 rule against the reversed Java code. | ||
|
||
{{ ../../../../rules/mastg-android-sensitive-data-in-screenshot.yml }} | ||
|
||
{{ run.sh }} | ||
|
||
### Observation | ||
|
||
The rule has identified one location in `MastgTestKt_reversed.java` where the app sets the `SecureFlagPolicy` in a Jetpack Compose `DialogProperties`. | ||
|
||
{{ output.txt }} | ||
|
||
### Evaluation | ||
|
||
The test fails because `SecureFlagPolicy` is set to `SecureOff`, which doesn't prevent screenshots or screen recordings of the dialog content. The app does not use `FLAG_SECURE` or any other screenshot prevention mechanism. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package org.owasp.mastestapp | ||
|
||
import android.app.Activity | ||
import android.content.Context | ||
import android.view.ViewGroup | ||
import androidx.compose.foundation.layout.Column | ||
import androidx.compose.foundation.layout.padding | ||
import androidx.compose.material3.Button | ||
import androidx.compose.material3.MaterialTheme | ||
import androidx.compose.material3.Surface | ||
import androidx.compose.material3.Text | ||
import androidx.compose.ui.platform.ComposeView | ||
import androidx.compose.ui.unit.dp | ||
import androidx.compose.ui.window.DialogProperties | ||
import androidx.compose.ui.window.SecureFlagPolicy | ||
import androidx.compose.runtime.Composable | ||
|
||
class MastgTest (private val context: Context){ | ||
|
||
var shouldRunInMainThread: Boolean = true | ||
|
||
fun mastgTest(): String { | ||
if (context is Activity) { | ||
|
||
// Compose dialog with SecureFlagPolicy.SecureOn | ||
val composeHost = ComposeView(context) | ||
val lp = ViewGroup.LayoutParams( | ||
ViewGroup.LayoutParams.MATCH_PARENT, | ||
ViewGroup.LayoutParams.MATCH_PARENT | ||
) | ||
composeHost.setContent { | ||
SecureComposeDialog( | ||
onDismiss = { | ||
val parent = composeHost.parent as? ViewGroup | ||
parent?.removeView(composeHost) | ||
} | ||
) | ||
} | ||
context.addContentView(composeHost, lp) | ||
|
||
return "SUCCESS!!\n\nThe Compose dialog should be visible.\n\nIt has SecureFlagPolicy.SecureOff set, so it should appear in screenshots or the recent apps view." | ||
} else { | ||
return "ERROR: Context is not an Activity" | ||
} | ||
|
||
} | ||
} | ||
|
||
@Composable | ||
private fun SecureComposeDialog(onDismiss: () -> Unit) { | ||
androidx.compose.ui.window.Dialog( | ||
onDismissRequest = onDismiss, | ||
properties = DialogProperties(securePolicy = SecureFlagPolicy.SecureOff) | ||
) { | ||
MaterialTheme { | ||
Surface { | ||
Column(modifier = androidx.compose.ui.Modifier.padding(16.dp)) { | ||
Text("This is a Compose dialog.") | ||
Text("Secure policy is set to SecureOff.") | ||
Button(onClick = onDismiss, modifier = androidx.compose.ui.Modifier.padding(top = 12.dp)) { | ||
Text("OK") | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.