Muse Spark 1.3·续1
For `GET /oauth/callback?code=...&state=...` in a multi-tenant SaaS, here is a focused model.
**How I’m using terms:**
* **Threat =** what an attacker can do to you.
* **Mitigation =** what you build to stop it. They are not the same.
### Explicit Assumptions
1. Authorization Code Flow + OIDC, code exchanged **server-to-server** over TLS with `client_secret` (or private_key_jwt).
2. Attacker can send the victim links, run their own tenant/subdomain like `evil.saas.com`, and observe/intercept a `code` if it leaks via logs, `Referer`, browser history.
3. Attacker cannot break TLS, compromise the IdP, or read server-side session store.
4. Tenants are mutually untrusted. Tenant identity comes from your app, not from a user-controlled query param.
5. `HttpOnly` alone does not prevent CSRF, XSS exfiltration via API calls, or subdomain cookie abuse.
### 5 Most Important Threats
**T1: Login CSRF / Code Injection via weak `state`**
Threat: Attacker starts OAuth with their own IdP account, gets `codeA`, then tricks victim into visiting `/oauth/callback?code=codeA&state=victimState` or with no state check. Victim's browser is now logged in as attacker.
Impact: Victim uploads company data to attacker's account, attacker later logs in to retrieve it. Reverse variant leads to account takeover.
Mitigation: Generate 128+ bit random `state` per login attempt, store server-side bound to the pre-login browser session + `code_verifier` + `tenant_id`, single-use with 5-10 min expiry, validate with constant-time compare. Fail closed if missing/mismatched/replayed. Use PKCE `S256` even for confidential clients.
**T2: Authorization Code Theft and Replay**
Threat: `code` leaks in access logs, error pages, `Referer: /oauth/callback?code=...` to analytics/CDN, browser history, or is stolen on open network if IdP redirect not HTTPS.
Impact: Attacker replays `code` in their own browser to impersonate victim -> full account takeover.
Mitigation: Require PKCE, never log `code/state/tokens`, set `Referrer-Policy: no-referrer`, make IdP `redirect_uri` exact-match HTTPS, and enforce single-use code exchange server-side. Do not accept `code` in any endpoint other than the callback.
**T3: Open Redirect after login to "tenant dashboard"**
Threat: Callback honors attacker-controlled `?next=`, `?redirect_uri=`, or `state.redirect` like `https://evil.com` or `//evil.com` or `https://legit.saas.com.evil.com`.
Impact: Post-login phishing that looks trusted, theft of session via `Referer`, bypass of allowlists. In multi-tenant, redirect to attacker tenant to steal tokens.
Mitigation: No open redirects. Ignore user-controlled URLs. Redirect only to relative path like `/dashboard` or lookup `tenant_id -> allowlisted URL` server-side. If you must support `next`, allowlist per-tenant exact paths, reject `//`, `\`, `http`, encoded variants.
**T4: Cross-Tenant / Issuer Confusion**
Threat: Attacker swaps `tenant_id` in `state`, uses token issued for `tenant-B` or different `iss/aud` to login to `tenant-A`. E.g. `/oauth/callback?code=...&state=...tenantB...` while victim belongs to `tenantA`, or mixes up IdPs in multi-IdP setup.
Impact: Horizontal privilege escalation, access to another tenant's data - catastrophic for SaaS.
Mitigation: Bind signed/encrypted `state` to `{ nonce, tenant_id, expected_iss, expected_aud }`. After exchange, validate ID Token signature via IdP JWKS, and check `iss`, `aud == your client_id`, `exp/iat/nonce`, then check `email/sub` is actually a member of `tenant_id` in your DB. Never trust tenant from query param.
**T5: Session Fixation + Cookie Over-Scoping**
Threat: App reuses pre-login session ID or sets cookie as `Domain=.saas.com; SameSite=None; Secure=false` or without `__Host-` prefix. Attacker subdomain or network attacker steals/forces session.
Impact: Session hijack across tenants, stays logged in even after OAuth completes.
Mitigation: Regenerate session ID on successful callback, set: `__Host-session=...; HttpOnly; Secure; Path=/; SameSite=Lax` (Strict for dashboard), no `Domain` attribute. Scope session to tenant server-side. Add idle/absolute timeout and logout that revokes server session.
> Note: `HttpOnly` stops `document.cookie` theft only. You still need `Secure + SameSite + __Host-` + server rotation.
### Test Cases
**TEST-STATE-01: State must be bound and single-use**
Steps:
1. `GET /login?tenant=acme` -> capture `Set-Cookie: oauth_state` + `state=GOOD` redirect to IdP.
2. Complete IdP login to get valid `code`.
3. Send: `GET /oauth/callback?code=<valid>&state=EVIL` and `GET /oauth/callback?code=<valid>&state=` (missing) and replay `GET /oauth/callback?code=<valid2>&state=GOOD` a second time.
Expected: All 3 return `400/403`, **no** code exchange with IdP, **no** `Set-Cookie: session`, error logged without logging `code`. Only exact `GOOD` first-use succeeds.
**TEST-REDIRECT-01: Post-login redirect cannot be abused**
Steps:
1. `GET /login?tenant=acme&next=https://evil.com` and variants: `//evil.com`, `https://acme.saas.com.evil.com`, `/\evil.com`, `%2F%2Fevil.com`.
2. Complete flow with valid `code + state`.
Expected: Session is created, but `Location:` is always default `/dashboard` or `https://acme.saas.com/dashboard` from server allowlist, never attacker URL. Test with two tenants to ensure `tenantA` code cannot redirect to `tenantB` dashboard.
{
"id": "resp_6ac7ad07d24591db7a1f43aa",
"object": "response",
"created_at": 1791470855,
"model": "muse-spark-1.3",
"output": [
{
"type": "reasoning",
"id": "rs_6ac7ad07d24591db7a1f43aa:rs_196a2d24-ee7c-402f-87d2-7fd8d5e2a652",
"summary": [],
"status": "completed"
},
{
"type": "message",
"id": "msg_a0fe4664-80b0-418c-935b-be4e53a10b0a",
"role": "assistant",
"content": [
{
"type": "output_text",
"text": "For `GET /oauth/callback?code=...&state=...` in a multi-tenant SaaS, here is a focused model.\n\n**How I’m using terms:**\n* **Threat =** what an attacker can do to you.\n* **Mitigation =** what you build to stop it. They are not the same.\n\n### Explicit Assumptions\n\n1. Authorization Code Flow + OIDC, code exchanged **server-to-server** over TLS with `client_secret` (or private_key_jwt).\n2. Attacker can send the victim links, run their own tenant/subdomain like `evil.saas.com`, and observe/intercept a `code` if it leaks via logs, `Referer`, browser history.\n3. Attacker cannot break TLS, compromise the IdP, or read server-side session store.\n4. Tenants are mutually untrusted. Tenant identity comes from your app, not from a user-controlled query param.\n5. `HttpOnly` alone does not prevent CSRF, XSS exfiltration via API calls, or subdomain cookie abuse.\n\n### 5 Most Important Threats\n\n**T1: Login CSRF / Code Injection via weak `state`**\nThreat: Attacker starts OAuth with their own IdP account, gets `codeA`, then tricks victim into visiting `/oauth/callback?code=codeA&state=victimState` or with no state check. Victim's browser is now logged in as attacker.\nImpact: Victim uploads company data to attacker's account, attacker later logs in to retrieve it. Reverse variant leads to account takeover.\nMitigation: Generate 128+ bit random `state` per login attempt, store server-side bound to the pre-login browser session + `code_verifier` + `tenant_id`, single-use with 5-10 min expiry, validate with constant-time compare. Fail closed if missing/mismatched/replayed. Use PKCE `S256` even for confidential clients.\n\n**T2: Authorization Code Theft and Replay**\nThreat: `code` leaks in access logs, error pages, `Referer: /oauth/callback?code=...` to analytics/CDN, browser history, or is stolen on open network if IdP redirect not HTTPS.\nImpact: Attacker replays `code` in their own browser to impersonate victim -> full account takeover.\nMitigation: Require PKCE, never log `code/state/tokens`, set `Referrer-Policy: no-referrer`, make IdP `redirect_uri` exact-match HTTPS, and enforce single-use code exchange server-side. Do not accept `code` in any endpoint other than the callback.\n\n**T3: Open Redirect after login to \"tenant dashboard\"**\nThreat: Callback honors attacker-controlled `?next=`, `?redirect_uri=`, or `state.redirect` like `https://evil.com` or `//evil.com` or `https://legit.saas.com.evil.com`.\nImpact: Post-login phishing that looks trusted, theft of session via `Referer`, bypass of allowlists. In multi-tenant, redirect to attacker tenant to steal tokens.\nMitigation: No open redirects. Ignore user-controlled URLs. Redirect only to relative path like `/dashboard` or lookup `tenant_id -> allowlisted URL` server-side. If you must support `next`, allowlist per-tenant exact paths, reject `//`, `\\`, `http`, encoded variants.\n\n**T4: Cross-Tenant / Issuer Confusion**\nThreat: Attacker swaps `tenant_id` in `state`, uses token issued for `tenant-B` or different `iss/aud` to login to `tenant-A`. E.g. `/oauth/callback?code=...&state=...tenantB...` while victim belongs to `tenantA`, or mixes up IdPs in multi-IdP setup.\nImpact: Horizontal privilege escalation, access to another tenant's data - catastrophic for SaaS.\nMitigation: Bind signed/encrypted `state` to `{ nonce, tenant_id, expected_iss, expected_aud }`. After exchange, validate ID Token signature via IdP JWKS, and check `iss`, `aud == your client_id`, `exp/iat/nonce`, then check `email/sub` is actually a member of `tenant_id` in your DB. Never trust tenant from query param.\n\n**T5: Session Fixation + Cookie Over-Scoping**\nThreat: App reuses pre-login session ID or sets cookie as `Domain=.saas.com; SameSite=None; Secure=false` or without `__Host-` prefix. Attacker subdomain or network attacker steals/forces session.\nImpact: Session hijack across tenants, stays logged in even after OAuth completes.\nMitigation: Regenerate session ID on successful callback, set: `__Host-session=...; HttpOnly; Secure; Path=/; SameSite=Lax` (Strict for dashboard), no `Domain` attribute. Scope session to tenant server-side. Add idle/absolute timeout and logout that revokes server session.\n\n> Note: `HttpOnly` stops `document.cookie` theft only. You still need `Secure + SameSite + __Host-` + server rotation.\n\n### Test Cases\n\n**TEST-STATE-01: State must be bound and single-use**\nSteps:\n1. `GET /login?tenant=acme` -> capture `Set-Cookie: oauth_state` + `state=GOOD` redirect to IdP.\n2. Complete IdP login to get valid `code`.\n3. Send: `GET /oauth/callback?code=<valid>&state=EVIL` and `GET /oauth/callback?code=<valid>&state=` (missing) and replay `GET /oauth/callback?code=<valid2>&state=GOOD` a second time.\nExpected: All 3 return `400/403`, **no** code exchange with IdP, **no** `Set-Cookie: session`, error logged without logging `code`. Only exact `GOOD` first-use succeeds.\n\n**TEST-REDIRECT-01: Post-login redirect cannot be abused**\nSteps:\n1. `GET /login?tenant=acme&next=https://evil.com` and variants: `//evil.com`, `https://acme.saas.com.evil.com`, `/\\evil.com`, `%2F%2Fevil.com`.\n2. Complete flow with valid `code + state`.\nExpected: Session is created, but `Location:` is always default `/dashboard` or `https://acme.saas.com/dashboard` from server allowlist, never attacker URL. Test with two tenants to ensure `tenantA` code cannot redirect to `tenantB` dashboard.",
"annotations": [],
"logprobs": []
}
],
"status": "completed"
}
],
"status": "completed",
"usage": {
"input_tokens": 127,
"output_tokens": 3327,
"total_tokens": 3454,
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens_details": {
"reasoning_tokens": 1945
}
},
"top_logprobs": 0,
"temperature": 1,
"top_p": 1,
"service_tier": "auto",
"reasoning": {
"effort": "high"
},
"background": false,
"tools": [],
"tool_choice": "auto",
"truncation": "disabled",
"completed_at": 1791470855,
"error": null,
"incomplete_details": null,
"instructions": null,
"parallel_tool_calls": true,
"store": true,
"max_output_tokens": 8192
}
</details>
<details>
<summary>Queue Migration Plan — Create a staged migration plan for replacing a legacy queue without interrupting event processing.</summary>
const response = await env.AI.run(
'meta/muse-spark-1.3',
{
messages: [
{
role: 'system',
content:
'You are a staff engineer planning a zero-downtime migration. Favor observable, reversible phases and identify the rollback trigger for each phase.',
},
{
role: 'user',
content:
'We are replacing a legacy job queue with a partitioned event log. Producers currently publish jobs directly to the old queue and three worker fleets consume them. Design a six-phase migration plan covering dual writes, shadow consumers, cutover, deduplication, lag monitoring, and rollback. State the invariant that must hold before deleting the old queue.',
},
],
max_completion_tokens: 4096,
},
)
console.log(response)
curl https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/ai/run \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"model": "meta/muse-spark-1.3",
"input": {
"messages": [
{
"role": "system",
"content": "You are a staff engineer planning a zero-downtime migration. Favor observable, reversible phases and identify the rollback trigger for each phase."
},
{
"role": "user",
"content": "We are replacing a legacy job queue with a partitioned event log. Producers currently publish jobs directly to the old queue and three worker fleets consume them. Design a six-phase migration plan covering dual writes, shadow consumers, cutover, deduplication, lag monitoring, and rollback. State the invariant that must hold before deleting the old queue."
}
],
"max_completion_tokens": 4096
}
}'
