Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions ProductController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.corp.catalog;

import java.beans.XMLDecoder;
import java.io.ByteArrayInputStream;

import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.web.bind.annotation.*;

@RestController
public class ProductController {

// VULN 1: SpEL Injection — a user-supplied string is parsed and evaluated as
// a Spring Expression, giving arbitrary Java execution (RCE).
@GetMapping("/filter")
public String filter(@RequestParam String q) {
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(q); // ?q=T(java.lang.Runtime).getRuntime().exec("id")
return String.valueOf(exp.getValue());
}
Comment on lines +16 to +21

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

CRITICAL Spring Expression Language (SpEL) Injection in /filter Endpoint

The /filter endpoint in ProductController.java accepts a query parameter 'q' and evaluates it directly as a Spring Expression Language (SpEL) expression using SpelExpressionParser. Because there is no validation or sanitization of the input before parsing and evaluation, an unauthenticated remote attacker can send a crafted SpEL expression (such as T(java.lang.Runtime).getRuntime().exec(...)) to execute arbitrary Java code on the host system.

Steps to Reproduce
curl -G "http://localhost:8080/filter" --data-urlencode "q=T(java.lang.Runtime).getRuntime().exec('id')"
Fix with AI

Open in Cursor Open in Claude

A security vulnerability was found by Hacktron.

File: ProductController.java
Lines: 16-21
Severity: critical

Vulnerability: Spring Expression Language (SpEL) Injection in /filter Endpoint

Description:
The /filter endpoint in ProductController.java accepts a query parameter 'q' and evaluates it directly as a Spring Expression Language (SpEL) expression using SpelExpressionParser. Because there is no validation or sanitization of the input before parsing and evaluation, an unauthenticated remote attacker can send a crafted SpEL expression (such as T(java.lang.Runtime).getRuntime().exec(...)) to execute arbitrary Java code on the host system.

Proof of Concept:
```bash
curl -G "http://localhost:8080/filter" --data-urlencode "q=T(java.lang.Runtime).getRuntime().exec('id')"
```

Affected Code:
    @GetMapping("/filter")
    public String filter(@RequestParam String q) {
        ExpressionParser parser = new SpelExpressionParser();
        Expression exp = parser.parseExpression(q); // ?q=T(java.lang.Runtime).getRuntime().exec("id")
        return String.valueOf(exp.getValue());
    }

Acceptance criteria:
- Acceptance is defined by the **actual reported behavior**, not by tests passing.
- Reproduce the issue, or narrow the exact code path that produces it, *before* changing code. State what you confirmed.
- Fix the underlying cause. Mitigations that paper over the reported behavior do not count as a fix.
- Add a regression test that fails on the unpatched code and passes on the fix. If a regression test is genuinely impractical (e.g. race condition, infra-level issue), say so and explain why.
- Existing tests passing is **not** the bar. Do not declare done on tests-pass theatre.

Only change what is necessary to fix this vulnerability. Do not refactor adjacent code or modify unrelated files.

Triage: Reply !fp <reason> (false positive), !valid (confirmed), !accepted_risk <reason>, or !fixed (resolved). Any other reply is saved as a triage note.
Reason is optional but improves future scans — e.g. !fp internal endpoint, not user-facing.

View finding in Hacktron


// VULN 2: XML Injection — user values are concatenated into an XML document
// without encoding, so input can inject or alter elements consumed
// downstream as trusted XML.
@PostMapping("/order")
public String order(@RequestParam String item, @RequestParam String qty) {
String xml = "<order><item>" + item + "</item><qty>" + qty + "</qty></order>";
return xml;
}
Comment on lines +26 to +30

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

MEDIUM XML Injection in ProductController /order Endpoint

The /order endpoint constructs an XML string by concatenating user-supplied 'item' and 'qty' parameters without sanitization. This allows an attacker to inject arbitrary XML tags into the output, which can be used to manipulate downstream data processing or conduct further attacks if the output is consumed by an XML parser.

Steps to Reproduce
  1. Send a POST request to the /order endpoint with the following parameters:
    item = 0
    qty = 1
  2. Observe that the returned XML contains the injected elements:
    01
Fix with AI

Open in Cursor Open in Claude

A security vulnerability was found by Hacktron.

File: ProductController.java
Lines: 26-30
Severity: medium

Vulnerability: XML Injection in ProductController `/order` Endpoint

Description:
The `/order` endpoint constructs an XML string by concatenating user-supplied 'item' and 'qty' parameters without sanitization. This allows an attacker to inject arbitrary XML tags into the output, which can be used to manipulate downstream data processing or conduct further attacks if the output is consumed by an XML parser.

Proof of Concept:
**Steps to Reproduce**

1. Send a POST request to the `/order` endpoint with the following parameters:
   item = </item><price>0</price><item>
   qty = 1
2. Observe that the returned XML contains the injected elements:
   <order><item></item><price>0</price><item></item><qty>1</qty></order>

Acceptance criteria:
- Acceptance is defined by the **actual reported behavior**, not by tests passing.
- Reproduce the issue, or narrow the exact code path that produces it, *before* changing code. State what you confirmed.
- Fix the underlying cause. Mitigations that paper over the reported behavior do not count as a fix.
- Add a regression test that fails on the unpatched code and passes on the fix. If a regression test is genuinely impractical (e.g. race condition, infra-level issue), say so and explain why.
- Existing tests passing is **not** the bar. Do not declare done on tests-pass theatre.

Only change what is necessary to fix this vulnerability. Do not refactor adjacent code or modify unrelated files.

Triage: Reply !fp <reason> (false positive), !valid (confirmed), !accepted_risk <reason>, or !fixed (resolved). Any other reply is saved as a triage note.
Reason is optional but improves future scans — e.g. !fp internal endpoint, not user-facing.

View finding in Hacktron


// VULN 3: Insecure Deserialization via XMLDecoder — decodes attacker-supplied
// XML into live objects, a well-known Java RCE sink.
@PostMapping("/import")
public String importData(@RequestBody byte[] body) {
XMLDecoder dec = new XMLDecoder(new ByteArrayInputStream(body));
Object o = dec.readObject(); // RCE
return "imported: " + o;
}
Comment on lines +34 to +39

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

CRITICAL Insecure Deserialization via XMLDecoder in ProductController

The '/import' endpoint in ProductController accepts a raw byte array from the request body and passes it directly to 'java.beans.XMLDecoder' for deserialization. XMLDecoder is inherently unsafe when processing untrusted input because it allows arbitrary Java object instantiation and method invocation, which can be leveraged by an attacker to achieve arbitrary Remote Code Execution (RCE) on the host system.

Steps to Reproduce
  1. Identify the public '/import' endpoint on the running Spring Boot application.
  2. Construct an HTTP POST request to '/import' with the Content-Type header set appropriately (e.g., application/xml or application/octet-stream).
  3. Provide a serialized XML payload representing a standard XMLDecoder gadget chain (such as invoking java.lang.ProcessBuilder to execute a system command).
  4. Send the request. The server will deserialize the request body using XMLDecoder.readObject(), triggering the instantiation of the specified objects and executing the command.
Fix with AI

Open in Cursor Open in Claude

A security vulnerability was found by Hacktron.

File: ProductController.java
Lines: 34-39
Severity: critical

Vulnerability: Insecure Deserialization via XMLDecoder in ProductController

Description:
The '/import' endpoint in ProductController accepts a raw byte array from the request body and passes it directly to 'java.beans.XMLDecoder' for deserialization. XMLDecoder is inherently unsafe when processing untrusted input because it allows arbitrary Java object instantiation and method invocation, which can be leveraged by an attacker to achieve arbitrary Remote Code Execution (RCE) on the host system.

Proof of Concept:
**Steps to Reproduce**

1. Identify the public '/import' endpoint on the running Spring Boot application.
2. Construct an HTTP POST request to '/import' with the Content-Type header set appropriately (e.g., application/xml or application/octet-stream).
3. Provide a serialized XML payload representing a standard XMLDecoder gadget chain (such as invoking java.lang.ProcessBuilder to execute a system command).
4. Send the request. The server will deserialize the request body using XMLDecoder.readObject(), triggering the instantiation of the specified objects and executing the command.

Acceptance criteria:
- Acceptance is defined by the **actual reported behavior**, not by tests passing.
- Reproduce the issue, or narrow the exact code path that produces it, *before* changing code. State what you confirmed.
- Fix the underlying cause. Mitigations that paper over the reported behavior do not count as a fix.
- Add a regression test that fails on the unpatched code and passes on the fix. If a regression test is genuinely impractical (e.g. race condition, infra-level issue), say so and explain why.
- Existing tests passing is **not** the bar. Do not declare done on tests-pass theatre.

Only change what is necessary to fix this vulnerability. Do not refactor adjacent code or modify unrelated files.

Triage: Reply !fp <reason> (false positive), !valid (confirmed), !accepted_risk <reason>, or !fixed (resolved). Any other reply is saved as a triage note.
Reason is optional but improves future scans — e.g. !fp internal endpoint, not user-facing.

View finding in Hacktron

}