clawd/memory/shannon-scan-2026-02-14/deliverables/xss_exploitation_queue.json

36 lines
3.7 KiB
JSON

{
"vulnerabilities": [
{
"ID": "XSS-VULN-01",
"vulnerability_type": "Stored",
"externally_exploitable": false,
"source": "DICOM file upload: SeriesDescription tag (0x0008,0x103E)",
"source_detail": "DICOM tag extracted via readStringTag() at /repos/inou-portal/main.go:407, stored in series.series_desc at main.go:424 without HTML encoding",
"path": "DICOM file upload → import-dicom binary readStringTag() → SQLite series table → Entry.Tags field → /api/series endpoint (api_series.go:65) → JSON response → viewer.js fetch → String concatenation → div.innerHTML assignment",
"sink_function": "div.innerHTML at /repos/inou-portal/portal/static/viewer.js:450",
"render_context": "HTML_BODY",
"encoding_observed": "None - Raw DICOM tag value flows through entire pipeline without any HTML encoding or sanitization",
"verdict": "vulnerable",
"mismatch_reason": "DICOM metadata (SeriesDescription) is extracted as raw bytes and stored in database without HTML encoding. API returns unescaped JSON. Client-side JavaScript builds HTML via string concatenation and assigns to innerHTML without sanitization. No encoding exists for HTML_BODY context.",
"witness_payload": "<img src=x onerror=alert(1)>",
"confidence": "high",
"notes": "Requires authenticated user to upload DICOM file. HttpOnly cookie prevents direct session theft, but XSS can exfiltrate medical records, perform unauthorized actions, or inject fake login forms. No CSP protection. External exploitation blocked by authentication requirement."
},
{
"ID": "XSS-VULN-02",
"vulnerability_type": "Stored",
"externally_exploitable": false,
"source": "Freeform tracker input via LLM generation: tracker.question field",
"source_detail": "User freeform input at /repos/inou-portal/portal/templates/trackers.tmpl:164 → POST to /api/trackers/respond → tryGenerateTrackerFromFreeform() at api_trackers.go:203 → callLLMForTracker() → Gemini API prompt injection → LLM returns question field → TrackerAdd() stores at lib/tracker.go:11",
"path": "Freeform textarea → handleTrackerRespond (api_trackers.go:148) → callLLMForTracker (api_llm.go:65) → Gemini API with {{INPUT}} substitution → LLM JSON response with 'question' field → TrackerAdd() database storage → TrackerQueryAll() retrieval → /api/trackers JSON response → JavaScript template literal ${tracker.question} → insertAdjacentHTML()",
"sink_function": "insertAdjacentHTML() at /repos/inou-portal/portal/templates/trackers.tmpl:887",
"render_context": "HTML_BODY",
"encoding_observed": "None - User input passed directly to LLM via string replacement (api_llm.go:107). LLM output stored in database without sanitization. API returns raw JSON. Client renders via template literals without encoding.",
"verdict": "vulnerable",
"mismatch_reason": "Tracker questions are generated by Google Gemini LLM from user-controlled freeform input. LLM can be prompt-injected to output arbitrary HTML/JavaScript in the 'question' field. No HTML encoding at database storage, API response, or client-side rendering. JavaScript template literal ${tracker.question} directly interpolates unsanitized data into HTML string assigned via insertAdjacentHTML.",
"witness_payload": "I take <img src=x onerror=alert(1)> daily",
"confidence": "high",
"notes": "Requires authenticated user to create tracker via freeform input. Prompt injection against LLM can bypass any AI-based filtering. HttpOnly cookie prevents session theft, but attacker can exfiltrate medical data or perform account takeover actions. No CSP. Affects all users viewing the tracker. External exploitation blocked by authentication requirement."
}
]
}