-
-
Couldn't load subscription status.
- Fork 2.5k
Port MASTG-TEST-0036: Testing Enforced Updating (android) (by @appknox) #3462
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
base: master
Are you sure you want to change the base?
Conversation
|
@cpholguera The build works fine on my device, the application utilizes the dependency |
|
Thanks for letting me know. I think we'll need to add support for demos to "add dependencies" when needed. That'd solve the issue. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for the migration and for putting this together! I’ve added some comments that might help bring it closer to the guidelines.
One thing I noticed is that the original test (0036) might have been interpreted a bit differently — the current content + Demo don’t quite reflect the real production issue. It could help to re-read the original description for the nuance. I also tried to rephrase the issue here for clarity: https://github.com/OWASP/mastg/pull/3462/files#r2367330215
And just a small tip: if you’re using co-pilot (like in 0290.md), it often works best to first describe the issue in your own words, and then let the LLM refine it. That way the text stays closer to the intent.
Overall though, really nice progress — it’s clear you put effort into this!
@sk3l10x1ng you can now add this dependency like this: Simply add a /MASTG-DEMO-xxxx/build.gradle.kts.libs |
|
@cpholguera updated the changes, please check |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR ports the Android enforced updating test (MASTG-TEST-0036) to the new MASTG V2 format, deprecating the original test in favor of MASTG-TEST-0x36. The update includes a new test methodology focusing on detecting Google Play Core's immediate in-app update enforcement using static analysis.
Key Changes:
- Deprecated the original MASTG-TEST-0036 and created a new V2 version (MASTG-TEST-0x36)
- Added a Semgrep rule to detect usage of
startUpdateFlowForResultwith immediate update configuration - Included comprehensive demo code showing both Kotlin source and reversed Java implementation
Reviewed Changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| tests/android/MASVS-CODE/MASTG-TEST-0036.md | Marked original test as deprecated with reference to new version |
| tests-beta/android/MASVS-CODE/MASTG-TEST-0x36.md | New V2 test definition focusing on Play Core API detection |
| rules/mastg-android-enforced-updating.yml | Semgrep rule for detecting immediate update enforcement |
| demos/android/MASVS-CODE/MASTG-DEMO-0x36/* | Demo implementation with Kotlin source, reversed Java, and expected output |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| super.onCreate(savedInstanceState) | ||
| enableEdgeToEdge() | ||
|
|
||
| // mastgTest = MastgTest(applicationContext) |
Copilot
AI
Oct 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove commented-out code. The initialization is already handled by the lazy delegate on line 26.
| // mastgTest = MastgTest(applicationContext) |
| // The unused 'this' parameter is now removed. | ||
| mastgTest.checkForUpdate(appUpdateResultLauncher) |
Copilot
AI
Oct 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove obsolete comment referring to a removed parameter. The comment no longer provides relevant context.
| // The unused 'this' parameter is now removed. | ||
| mastgTest.checkForUpdate(appUpdateResultLauncher) |
Copilot
AI
Oct 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove obsolete comment referring to a removed parameter. The comment no longer provides relevant context.
| // The unused 'this' parameter is now removed. | ||
| mastgTest.checkForUpdate(appUpdateResultLauncher) |
Copilot
AI
Oct 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove obsolete comment referring to a removed parameter. The comment no longer provides relevant context.
| // if (::mastgTest.isInitialized) { | ||
| // The unused 'this' parameter is now removed. | ||
| mastgTest.resumeUpdateIfInProgress(appUpdateResultLauncher) |
Copilot
AI
Oct 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove commented-out initialization check and obsolete parameter comment. Since mastgTest is initialized by lazy delegation, the check is unnecessary.
| @@ -0,0 +1 @@ | |||
| NO_COLOR=true semgrep -c ../../../../rules/mastg-android-enforced-updating.yml ./MastgTest_reversed.java --text -o output.txt No newline at end of file | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| NO_COLOR=true semgrep -c ../../../../rules/mastg-android-enforced-updating.yml ./MastgTest_reversed.java --text -o output.txt | |
| NO_COLOR=true semgrep -c ../../../../rules/mastg-android-enforced-updating.yml ./MastgTest_reversed.java > output.txt |
|
|
||
| ## Overview | ||
|
|
||
| The goal of this test is to verify whether the application enforces updates in a way that blocks usage until the latest version is installed. This is typically achieved using the [Google Play Core In-App Update API](https://developer.android.com/guide/playcore/in-app-updates/kotlin-java) by invoking `startUpdateFlowForResult` with an Immediate update type option `AppUpdateType.IMMEDIATE` or value `1`. This configuration initiates a non-cancellable, blocking update flow. The test should involve launching the app when an update is available and verifying that access to the app's functionality remains restricted until the update has been successfully downloaded and installed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| The goal of this test is to verify whether the application enforces updates in a way that blocks usage until the latest version is installed. This is typically achieved using the [Google Play Core In-App Update API](https://developer.android.com/guide/playcore/in-app-updates/kotlin-java) by invoking `startUpdateFlowForResult` with an Immediate update type option `AppUpdateType.IMMEDIATE` or value `1`. This configuration initiates a non-cancellable, blocking update flow. The test should involve launching the app when an update is available and verifying that access to the app's functionality remains restricted until the update has been successfully downloaded and installed. | |
| The goal of this test is to verify whether the application enforces mandatory updates, preventing users from accessing the app until the latest version has been successfully downloaded and installed. A mandatory update can typically be achieved by using the [Google Play Core In-App Update API](https://developer.android.com/guide/playcore/in-app-updates/kotlin-java) and invoking `startUpdateFlowForResult` with an Immediate update type option `AppUpdateType.IMMEDIATE` or value `1`. |
I couldn't find anywhere in Android docs that "this configuration initiates a non-cancellable, blocking update flow"
Reading https://developer.android.com/guide/playcore/in-app-updates#immediate I see that there is an X button when an immediate update is available, indicating that the user can refuse an immediate update, meaning that any blocking functionality is to the developer's discretion.
|
|
||
| ## Steps | ||
|
|
||
| 1. Run a static analysis tool such as @MASTG-TOOL-0110 on codebase for usages of the calls to the Play Core in-app update API, specifically `startUpdateFlowForResult`, that are configured with the integer value `1`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 1. Run a static analysis tool such as @MASTG-TOOL-0110 on codebase for usages of the calls to the Play Core in-app update API, specifically `startUpdateFlowForResult`, that are configured with the integer value `1`. | |
| 1. Run a static analysis tool such as @MASTG-TOOL-0110 on codebase for usages of the calls to the Play Core in-app update API, specifically `startUpdateFlowForResult`, that are configured with the integer value `1` (`AppUpdateType.IMMEDIATE`). |
|
|
||
| ## Evaluation | ||
|
|
||
| The test fails if the app does not enforce updates and still allows users to skip or ignore them. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please indicate what should look for in the code based on the above observation in order to evaluate this?
This PR closes #2994