Skip to content

Enhancement: Comprehensive NoSQL Injection Module (Levels 1-6)#537

Open
MohammedGhallab wants to merge 21 commits intoSasanLabs:masterfrom
MohammedGhallab:nosql-vulnerability
Open

Enhancement: Comprehensive NoSQL Injection Module (Levels 1-6)#537
MohammedGhallab wants to merge 21 commits intoSasanLabs:masterfrom
MohammedGhallab:nosql-vulnerability

Conversation

@MohammedGhallab
Copy link
Copy Markdown

🚀 Enhancement: Comprehensive NoSQL Injection Module (Levels 1-6)

📝 Description

This Pull Request introduces a robust set of learning levels for the NoSQL Injection module. The goal is to guide users through the evolution of NoSQL vulnerabilities in MongoDB, starting from basic string-based injections to advanced Aggregation Pipeline breakouts and finally demonstrating the secure implementation.


🛠️ Key Levels Implemented

Level Description Technique
Level 1 & 2 Basic String Injection Unescaped string concatenation
Level 3 Blind NoSQL Injection Boolean-based exfiltration (exists vs not found)
Level 4 Logical Operator Injection Data exfiltration using $ne, $gt, etc.
Level 5 Aggregation Pipeline Injection Multi-stage breakout via Document.parse
Level 6 SECURE Implementation Using Criteria API (Parameterized Queries)

☣️ Proof of Concept (PoC) for Level 5

To demonstrate the vulnerability in the new Aggregation level:

  1. Vulnerable Endpoint: NoSQLInjection/LEVEL_5
  2. Attack Vector: Aggregation Pipeline Breakout.
  3. Payload:
    admin" } },{"$lookup": {"from": "user","pipeline": [],"as":"all_users"}},{ "$unwind": "$all_users" },{ "$replaceRoot": { "newRoot": "$all_users" } } ]

@codecov-commenter
Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 3.92157% with 98 lines in your changes missing coverage. Please review.
✅ Project coverage is 48.79%. Comparing base (3dd7ba8) to head (3e7cfc8).
⚠️ Report is 84 commits behind head on master.

Files with missing lines Patch % Lines
...lnerability/nosql/NoSQLInjectionVulnerability.java 0.00% 75 Missing ⚠️
...lnerability/fileupload/UnrestrictedFileUpload.java 0.00% 9 Missing ⚠️
...labs/configuration/VulnerableAppConfiguration.java 0.00% 7 Missing ⚠️
...rg/sasanlabs/service/vulnerability/nosql/User.java 0.00% 7 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master     #537      +/-   ##
============================================
- Coverage     49.33%   48.79%   -0.54%     
- Complexity      346      398      +52     
============================================
  Files            56       66      +10     
  Lines          2090     2439     +349     
  Branches        225      255      +30     
============================================
+ Hits           1031     1190     +159     
- Misses          978     1152     +174     
- Partials         81       97      +16     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

import org.sasanlabs.internal.utility.LevelConstants;
import org.sasanlabs.internal.utility.Variant;
import org.sasanlabs.internal.utility.annotations.AttackVector;
import org.sasanlabs.internal.utility.annotations.VulnerableAppRequestMapping;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

please remove sample vulnerability related classes and files. there are js files as well.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

ok

false);
}

// Level 11: Maximum protection using Content-based validation (MIME Type)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why did we added this ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I apologize for not clarifying earlier. The reason is that Level 10 is secure but remains vulnerable to file content spoofing. For instance, if a text file's extension is renamed to an image format, the server accepts it immediately. To address this, I’ve introduced Level 11, which implements deep file content inspection to ensure the server isn't deceived by misleading extensions.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

sure thank you.

org.sasanlabs.service.vulnerability.nosql.User.class)) {
mongoTemplate.dropCollection(org.sasanlabs.service.vulnerability.nosql.User.class);
}
mongoTemplate.save(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

is there a way to jsut use application.properties to set up mongo instead of hardcoded passwords etc in configuration file?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yes, absolutely. I agree that hardcoding credentials is not ideal. I can move the MongoDB configuration to the application.properties file and use Spring Boot's @value annotation or ConfigurationProperties to inject them into the configuration class. This will make the setup more secure and flexible. I will update the PR with these changes shortly.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can we make mongodb ephemeral i.e. inmemory database like H2 db?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@MohammedGhallab I can still see passwords part of code instead of config.

Object data, boolean isValid) {
try {
String content =
(data instanceof String)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would suggest for not using ternary operator, please use If..Else

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I appreciate the suggestion. I will replace the ternary operator with a standard if..else block to improve code readability as requested. I will push the update shortly.

HEADER_INJECTION_VULNERABILITY=It tests how a JWT header can be manipulated to alter the signature verification. No newline at end of file
HEADER_INJECTION_VULNERABILITY=It tests how a JWT header can be manipulated to alter the signature verification.

NOSQL_INJECTION_VULNERABILITY=No Injection vulnrabilty No newline at end of file
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can you write payloads for each level?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Sure! Here are the payloads for each level to demonstrate the NoSQL Injection vulnerabilities:

Level 1 (String Concatenation): admin" , "password": {"$ne": "1"}

Level 2 (Direct Object Injection): {"$gt": ""}

Level 3 (Blind NoSQL Injection): admin" , "username": {"$regex": "^a.*"}

Level 4 (Logical Operator Injection): {"$ne": null}

Level 5 (Aggregation Pipeline Injection): admin" } },{"$lookup": {"from": "user","pipeline": [],"as":"all_users"}},{ "$unwind": "$all_users" },{ "$replaceRoot": { "newRoot": "$all_users" } } ]

Level 6 (Secure): No payload, as it is protected using parameterized queries.

I will add these examples to the code comments or documentation as well.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not in the comment, i meant that attackvector annotation has payload field which can contain the description i.e. way to exploit a vulnerability. you can add these payloads in descritpion and that way it works as hint

// Payload: { "$ne": null }
@AttackVector(
vulnerabilityExposed = VulnerabilityType.NOSQL_INJECTION,
description = "NOSQL_INJECTION_VULNERABILITY")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Attack vector annotation populates hints oin the UI Page. Please ensure that attack vection anotation description is really good.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good point. I will update the @AttackVector descriptions to be more educational and descriptive, so users can better understand the specific NoSQL Injection vector for each level when viewing it on the UI. Thanks for the heads-up!

import org.springframework.web.bind.annotation.RequestParam;

@VulnerableAppRestController(
descriptionLabel = "NOSQL_INJECTION_VULNERABILITY",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This description label is shwon in UI when we click on the Vulnerability. Please ensure adding a really great depth details with references to external sources,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good point. I will update the @AttackVector descriptions to be more educational and descriptive, so users can better understand the specific NoSQL Injection vector for each level when viewing it on the UI. Thanks for the heads-up!

private final ObjectMapper objectMapper;

@Autowired
public NoSQLInjectionVulnerability(MongoTemplate mongoTemplate) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

is this dependency bean resolving for you? It is failing in my local.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

It was working in my environment, but I see the issue. Since ObjectMapper is marked as final, it must be initialized in the constructor. I will update the constructor to include ObjectMapper so Spring can resolve and inject the bean correctly. Alternatively, I can define it as a @bean in the configuration class if it's missing from the context. I'll fix this in the next commit.

org.sasanlabs.service.vulnerability.nosql.User.class)) {
mongoTemplate.dropCollection(org.sasanlabs.service.vulnerability.nosql.User.class);
}
mongoTemplate.save(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can we make mongodb ephemeral i.e. inmemory database like H2 db?

false);
}

// Level 11: Maximum protection using Content-based validation (MIME Type)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

sure thank you.

HEADER_INJECTION_VULNERABILITY=It tests how a JWT header can be manipulated to alter the signature verification. No newline at end of file
HEADER_INJECTION_VULNERABILITY=It tests how a JWT header can be manipulated to alter the signature verification.

NOSQL_INJECTION_VULNERABILITY=No Injection vulnrabilty No newline at end of file
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not in the comment, i meant that attackvector annotation has payload field which can contain the description i.e. way to exploit a vulnerability. you can add these payloads in descritpion and that way it works as hint

@@ -0,0 +1,35 @@
package org.sasanlabs.service.vulnerability.sampleVulnerability;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

please remove this file

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I deleted it and just uploaded the new changes.

const config = {
"1": { title: "Level 1: String Breakout", goal: "Bypass authentication via string concatenation.", hint: "Try: <code>admin\" , \"password\": {\"$ne\": \"1\"}</code>" },
"2": { title: "Level 2: Object Injection", goal: "Direct injection into the query without quotes.", hint: "Try: <code>{\"$gt\": \"\"}</code>" },
"3": { title: "Level 3: Blind Injection", goal: "Infer data from server responses (True/False).", hint: "Try Regex for guessing: <code>admin\" , \"username\": {\"$regex\": \"^a.*\"}</code>" },
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

hint is populated automatically form attack vector annotation. it is not needed here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Okay, I'll work on resolving the new issues.


const url = `/VulnerableApp/NoSQLInjection/LEVEL_${level}?username=${encodeURIComponent(userInput)}`;

fetch(url)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There is already a method to do api call that hides all this. use mehtod called doGetAjaxCall and doPostAjaxCall

https://github.com/SasanLabs/VulnerableApp/blob/master/src/main/resources/static/vulnerableApp.js#L243

My suggestion is look at other vulnerabiulity js files to find out how we have done there.


document.addEventListener("DOMContentLoaded", updateLevelContent);

setTimeout(updateLevelContent, 1000); No newline at end of file
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would suggest not doing all this and let framework load right html file and if there is something dynamic, check how it is done in other levels,

try {
String pipelineJson = "[ { \"$match\": { \"username\": \"" + user + " } ]";

System.out.println("Full Pipeline Query: " + pipelineJson);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

please dont use println. you can use logger class. Look at other levels to see the usage of logger.


// 3. Check file size (Optional security measure to prevent Denial of Service -
// DoS).
if (file.getSize() > 5 * 1024 * 1024) { // 5MB limit
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think ddos is already handled by Spring boot. there is one property in spring boot application.properties file that does this.

String detectedType = tika.detect(file.getInputStream());

// Define a whitelist of allowed MIME types.
List<String> allowedMimeTypes = Arrays.asList("image/jpeg", "image/png", "image/gif");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we have constants defined for them. please use them or if constants are not there, please declare string constants

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you please check this?

@MohammedGhallab
Copy link
Copy Markdown
Author

@preetkaran20 Please review and accept the pull request if there are no issues.

Copy link
Copy Markdown
Member

@preetkaran20 preetkaran20 left a comment

Choose a reason for hiding this comment

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

@MohammedGhallab I can still see a lot of comments are not yet resolved. can you please check if they are fixed?

@MohammedGhallab
Copy link
Copy Markdown
Author

@MohammedGhallab I can still see a lot of comments are not yet resolved. can you please check if they are fixed?

Ok

@MohammedGhallab
Copy link
Copy Markdown
Author

@MohammedGhallab I can still see a lot of comments are not yet resolved. can you please check if they are fixed?

The review, auditing, and error correction were completed.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants