Skip to content

feat: add product controller#111

Open
maekuss wants to merge 1 commit into
mainfrom
add-product-spring
Open

feat: add product controller#111
maekuss wants to merge 1 commit into
mainfrom
add-product-spring

Conversation

@maekuss

@maekuss maekuss commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Adds a Spring product controller (ProductController.java).

Scanner test PR — intentionally vulnerable. Expected High/Critical findings:

  • SpEL Injection in GET /filter — user q parsed & evaluated as a Spring Expression → RCE (Critical)
  • XML Injection in POST /order — user values concatenated into an XML document without encoding (High)
  • Insecure Deserialization via XMLDecoder in POST /import — attacker XML decoded into objects → RCE (Critical)

@hacktron-app-stg hacktron-app-stg Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

3 issues found across 1 file

Severity Count
CRITICAL 2
MEDIUM 1

View full scan results

Comment thread ProductController.java
Comment on lines +34 to +39
@PostMapping("/import")
public String importData(@RequestBody byte[] body) {
XMLDecoder dec = new XMLDecoder(new ByteArrayInputStream(body));
Object o = dec.readObject(); // RCE
return "imported: " + o;
}

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

Comment thread ProductController.java
Comment on lines +16 to +21
@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());
}

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

Comment thread ProductController.java
Comment on lines +26 to +30
@PostMapping("/order")
public String order(@RequestParam String item, @RequestParam String qty) {
String xml = "<order><item>" + item + "</item><qty>" + qty + "</qty></order>";
return xml;
}

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

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.

1 participant