Skip to content

Conversation

@jeel38
Copy link
Collaborator

@jeel38 jeel38 commented Jun 10, 2025

Closes #2995

This PR ports MASTG-TEST-0002 from version 1 to version 2, creating a new test for detecting use of local storage for input validation in Android applications. The focus shifts from general local storage testing to specifically checking for integrity validation when reading from SharedPreferences.

  • Deprecates the old MASTG-TEST-0002 and creates MASTG-TEST-0288 as the new version
  • Implements static analysis detection for SharedPreferences usage without integrity checks
  • Provides demonstration code showing both vulnerable and secure patterns using HMAC validation
File Description
tests/android/MASVS-CODE/MASTG-TEST-0002.md Marks the original test as deprecated with reference to new version
tests-beta/android/MASVS-CODE/MASTG-TEST-0288.md New test specification for detecting SharedPreferences without integrity validation
rules/mastg-android-local-storage-input-validation.yml Semgrep rule to detect insecure SharedPreferences usage patterns
demos/android/MASVS-CODE/MASTG-DEMO-0061/ Complete demonstration including vulnerable code, and analysis output

@jeel38
Copy link
Collaborator Author

jeel38 commented Jun 10, 2025

@cpholguera, upon adding the depreciation note, getting branch gets a conflict

@cpholguera
Copy link
Collaborator

Maybe the branch was a bit old. We added "profiles" now for all tests. I fixed the conflict for you

Please add profiles to tests-beta/android/MASVS-CODE/MASTG-TEST-0281.md as well

@cpholguera
Copy link
Collaborator

The new profiles (previously known as "levels") are defined here: https://docs.google.com/document/d/1paz7dxKXHzAC9MN7Mnln1JiZwBNyg7Gs364AJ6KudEs/edit?usp=sharing

@cpholguera cpholguera requested a review from Copilot June 10, 2025 08:36

This comment was marked as outdated.

@jeel38
Copy link
Collaborator Author

jeel38 commented Jun 10, 2025

Maybe the branch was a bit old. We added "profiles" now for all tests. I fixed the conflict for you

Please add profiles to tests-beta/android/MASVS-CODE/MASTG-TEST-0281.md as well

Done

@jeel38
Copy link
Collaborator Author

jeel38 commented Jun 10, 2025

@cpholguera please review it

@cpholguera
Copy link
Collaborator

Please fix the issues reported by Copilot in section "Comments suppressed due to low confidence (5)"


Also, I agree with Copilot's comment about:

"The output file shows usages of the input validation using putString and getString in the code."

The phrasing is misleading: this test detects storage/retrieval calls, not input validation.

If you're conducting a pentest, would you report this as an issue? "The app uses putString() and getString()." The same goes for an automated security testing tool, would you like it to report this? Wouldn't that be noisy / lots of false positives?

@cpholguera
Copy link
Collaborator

There's another problem that will probably be solved when you fix the copilot issues. Are you able to read these logs?

https://github.com/OWASP/owasp-mastg/actions/runs/15554645412/job/43792346017?pr=3328

ERROR - Error reading page 'MASTG/demos/android/MASVS-CODE/MASTG-DEMO-0054/MASTG-DEMO-0054.md': Snippet at path '../../../../rules/mastg-android-local-storage-for-input-validation.yml' could not be found

@jeel38
Copy link
Collaborator Author

jeel38 commented Aug 11, 2025

@cpholguera please check

Copy link
Contributor

Copilot AI left a 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 MASTG-TEST-0002 from version 1 to version 2, creating a new test for detecting use of local storage for input validation in Android applications. The focus shifts from general local storage testing to specifically checking for integrity validation when reading from SharedPreferences.

  • Deprecates the old MASTG-TEST-0002 and creates MASTG-TEST-0288 as the new version
  • Implements static analysis detection for SharedPreferences usage without integrity checks
  • Provides demonstration code showing both vulnerable and secure patterns using HMAC validation

Reviewed Changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

File Description
tests/android/MASVS-CODE/MASTG-TEST-0002.md Marks the original test as deprecated with reference to new version
tests-beta/android/MASVS-CODE/MASTG-TEST-0288.md New test specification for detecting SharedPreferences without integrity validation
rules/mastg-android-local-storage-input-validation.yml Semgrep rule to detect insecure SharedPreferences usage patterns
demos/android/MASVS-CODE/MASTG-DEMO-0061/ Complete demonstration including vulnerable Java code, secure Kotlin implementation, and analysis output

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

- L2
profiles: [L1, L2]
status: deprecated
covered_by: [MASTG-TEST-0281]
Copy link

Copilot AI Aug 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The deprecation references MASTG-TEST-0281, but the actual replacement test created in this PR is MASTG-TEST-0288. This should be corrected to reference the correct test ID.

Suggested change
covered_by: [MASTG-TEST-0281]
covered_by: [MASTG-TEST-0288]

Copilot uses AI. Check for mistakes.

## Steps

1. Run a static analysis tool such as @MASTG-TOOL-0110 on the code and look for uses of the `putString` and `getString`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an old file


### Evaluation

The test fails as the code does not use an `HMAC` integrity check together with `SharedPreferences` data.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please describe how, because of this, an attacker can exploit the app. Use references to techniques when possible.

@jeel38
Copy link
Collaborator Author

jeel38 commented Sep 17, 2025

@cpholguera requested changes be made. Could you please check

@jeel38
Copy link
Collaborator Author

jeel38 commented Oct 7, 2025

@cpholguera can you please review

@jeel38
Copy link
Collaborator Author

jeel38 commented Oct 27, 2025

@cpholguera can you please review it

@cpholguera cpholguera requested review from Diolor and Copilot October 27, 2025 12:00
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Collaborator

@Diolor Diolor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @jeel38 ! Really nice pen-test example ^^ Left some suggestions to improve this test. Feel free to reach out if something is unclear

---
platform: android
title: Local Storage for Input Validation with semgrep
id: MASTG-DEMO-0061
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you might need a new id just before merge (demo 61 exists)

---
title: Use of Local Storage for Input Validation
platform: android
id: MASTG-TEST-0288
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you might need a new id just before merge (test 288 already exists)


## Overview

Data stored in Android's `SharedPreference`s can be tampered with on a rooted device. If an application reads this data without verifying its integrity (e.g., with an HMAC signature), it can lead to security vulnerabilities. This test checks if the application properly validates data read from local storage.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already really well-written @jeel38! How about we generalise it a bit and add a note, comment, or intro that this test is not only about SharedPrefs, but also any other local storage, like the v1 test mentions?

Additionally, we should add the requirement for data authenticity (HMAC is about both integrity and authenticity after all):

Suggested change
Data stored in Android's `SharedPreference`s can be tampered with on a rooted device. If an application reads this data without verifying its integrity (e.g., with an HMAC signature), it can lead to security vulnerabilities. This test checks if the application properly validates data read from local storage.
Data stored in Android's `SharedPreference`s can be tampered with on a rooted device. If an application reads this data without verifying its integrity and authenticity (e.g., with an HMAC signature), it can lead to security vulnerabilities. This test checks if the application properly validates data read from local storage.

What we could highlight here to help the reader is that SHA (integrity check without authenticity check) might not be optimal unless the SHA hashes are stored in a backend server. Therefore, by using HMAC, we only need to store the key safely and the data + HMAC hash in the local storage.


## Evaluation

The test fails as the application does not verify the integrity of data loaded from `SharedPreferences`. Without an integrity check like `HMAC`, an attacker with root access can directly edit the SharedPreferences XML file, modifying values to grant themselves higher privileges. The app then reads and acts on this tampered data, leading to a critical security failure, like privilege escalation.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The test fails as the application does not verify the integrity of data loaded from `SharedPreferences`. Without an integrity check like `HMAC`, an attacker with root access can directly edit the SharedPreferences XML file, modifying values to grant themselves higher privileges. The app then reads and acts on this tampered data, leading to a critical security failure, like privilege escalation.
The test fails if the application does not verify the integrity and authenticity of data loaded from local storage such as `SharedPreferences`.

I would consolidate the other sentences as part of the overview to explain the risk etc...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please Refer to this comment: #3328 (comment)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To my understanding, @cpholguera pointed out that suggestion for the DEMO, this is the TEST file.
Reading this TEST's Overview and Evaluation sections seems to be some repetition.

@@ -0,0 +1,24 @@
---
title: Use of Local Storage for Input Validation
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about the following? Input validation to me sounds validating input rather than checking the integrity/authenticity of data.

Suggested change
title: Use of Local Storage for Input Validation
title: Validation of Local Storage Data

or

Suggested change
title: Use of Local Storage for Input Validation
title: Integrity and Authenticity Validation of Local Storage Data

@@ -0,0 +1 @@
NO_COLOR=true semgrep -c ../../../../rules/mastg-android-local-storage-input-validation.yml ./MastgTest_reversed.java --text -o output.txt No newline at end of file
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
NO_COLOR=true semgrep -c ../../../../rules/mastg-android-local-storage-input-validation.yml ./MastgTest_reversed.java --text -o output.txt
NO_COLOR=true semgrep -c ../../../../rules/mastg-android-local-storage-input-validation.yml ./MastgTest_reversed.java > output.txt

to align with rest of project

Comment on lines +23 to +26
SecureSharedPreferences insecurePrefs = new SecureSharedPreferences(this.context, false);
insecurePrefs.saveData("user_role_insecure", "user");
SecureSharedPreferences securePrefs = new SecureSharedPreferences(this.context, true);
securePrefs.saveData("user_role_secure", "user");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracting this file gives quite a different result. Most importantly, the following. Therefore, Semgrep finds no results for me.

Suggested change
SecureSharedPreferences insecurePrefs = new SecureSharedPreferences(this.context, false);
insecurePrefs.saveData("user_role_insecure", "user");
SecureSharedPreferences securePrefs = new SecureSharedPreferences(this.context, true);
securePrefs.saveData("user_role_secure", "user");
saveData("user_role_insecure", "user", false);
saveData("user_role_secure", "user", true);

Comment on lines +51 to +58
return "INITIAL SETUP COMPLETE.\n\n" +
"The role for both secure and insecure tests has been set to 'user'.\n\n" +
"ACTION REQUIRED:\n" +
"1. Use a file explorer or ADB shell on a rooted device.\n" +
"2. Go to: /data/data/org.owasp.mastestapp/shared_prefs/\n" +
"3. Open the file: app_settings.xml\n" +
"4. Change BOTH <string>user</string> values to <string>admin</string>.\n" +
"5. Save the file and run this test again to see the results."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done on he pen-testing example! 👏 I followed the steps but sadly could not "tamper" it.

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="user_role_secure_hmac">690d026aeeba673e7225ee95a3460a0054752777afec8e4fb7ec8294934011ed</string>
    <boolean name="setup_complete" value="true" />
    <string name="user_role_insecure">admin</string>
    <string name="user_role_secure">admin</string>
</map> 

is the file state between the 2 steps

results.append(">> OUTCOME: NOT TAMPERED. The role is still '$secureRole', and its HMAC signature is valid.\n")
}

results.append("\n\nTest complete. To run the setup again, please clear the application's data in Android Settings and restart the test.")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fyi restarting the application (thus test) would rewrite the xml. No need for clearing app data

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MASTG v1->v2 MASTG-TEST-0002: Testing Local Storage for Input Validation (android)

3 participants