{"schema":"threatline.record/2","record":{"id":"GHSA-rg4w-2j3r-2hhp","aliases":["GHSA-rg4w-2j3r-2hhp"],"summary":"Keycloak implicit account linking allows takeover of existing local accounts","details":"### Summary\r\n\r\nAn unlinked Keycloak identity can be mapped to an existing phpMyFAQ account by matching `preferred_username` or email. The external subject is then bound and authenticated as that local user, potentially a superadmin.\r\n\r\nThis also occurs when `keycloak.autoProvision` is disabled.\r\n\r\n### Details\r\n\r\n`KeycloakAuthenticationController::resolveLocalLogin()` first checks `keycloak_sub`, but falls back to an existing local username or email. The callback authenticates that account and stores the attacker's Keycloak subject when the local binding is empty.\r\n\r\nNo proof exists that the local user authorized this account link. The email fallback also does not require an `email_verified` claim.\r\n\r\n### PoC\r\n\r\n1. Install phpMyFAQ 4.2.0-beta.\r\n2. Enable Keycloak and set `keycloak.autoProvision=false`.\r\n3. Keep an existing local superadmin named `admin` with an empty `keycloak_sub`.\r\n4. Create or control a Keycloak user whose `preferred_username` is `admin`.\r\n5. Log in through `/auth/keycloak/authorize`.\r\n6. Observe that the session is authenticated as the local superadmin.\r\n7. Observe that the local account is now bound to the attacker's Keycloak subject.\r\n\r\n### Impact\r\n\r\nA low-privileged Keycloak user who can obtain a colliding username or email can take over an existing local account and inherit all of its privileges, including full administrative access.","categories":["Unclassified"],"product":"thorsten/phpmyfaq","vendor":"","ecosystem":null,"affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/thorsten/phpMyFAQ/security/advisories/GHSA-rg4w-2j3r-2hhp","source_modified_at":"2026-10-03T11:34:30Z","fetched_at":"2026-10-23T21:14:28.314422Z","package":{"ecosystem":"composer","name":"thorsten/phpmyfaq"},"range":"4.2.0-alpha.2"}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/thorsten/phpMyFAQ/security/advisories/GHSA-rg4w-2j3r-2hhp","source_modified_at":"2026-10-03T11:34:30Z","fetched_at":"2026-10-23T21:14:28.314422Z","package":{"ecosystem":"composer","name":"thorsten/phpmyfaq"},"version":"4.2.0-beta"}],"cvss":7.5,"severity":"High","kev":{"listed":false},"epss":{"probability":null,"percentile":null,"score_date":null},"published_at":"2026-10-03T11:34:30Z","modified_at":"2026-10-03T11:34:30Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/thorsten/phpMyFAQ/security/advisories/GHSA-rg4w-2j3r-2hhp","fetched_at":"2026-10-23T21:14:28.314422Z","source_modified_at":"2026-10-03T11:34:30Z"}],"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-03T11:34:30Z","content_hash":"9187307560df3f06c0711511121c1336157934dee70f0d97cb045e751971c406"}}
