-
Notifications
You must be signed in to change notification settings - Fork 3
feat: add product controller #111
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: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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()); | ||
| } | ||
|
|
||
| // 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The Steps to Reproduce
Fix with AITriage: Reply |
||
|
|
||
| // 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
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
Fix with AITriage: Reply |
||
| } | ||
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 /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
Fix with AI
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