Skip to content

CVE-2026-48611: Verified Repro With Script Download

CVE-2026-48611: phpBB authentication bypass/account hijacking via OAuth login-link flow with arbitrary auth provider=apache

CVE-2026-48611 is verified against phpbb/phpbb · github. Affected versions: phpBB 3.3.0 through 3.3.16 and 4.0.0-a2 (default configuration, auth_method=db). Fixed in phpBB 3.3.17 released 2026-06-06. Vulnerability class: Auth Bypass. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00223.

REPRO-2026-00223 phpbb/phpbb · github Auth Bypass Variant found Jul 4, 2026 CVE entry ↗ .txt
Severity
CRITICAL
CVSS
9.8
Confidence
HIGH
Reproduced in
22m 9s
Tool calls
214
Spend
$4.83
01 · Overview

What Is CVE-2026-48611?

CVE-2026-48611 is a critical authentication-bypass vulnerability (CWE-305) in phpBB that lets an unauthenticated attacker hijack any known user account, including administrators, via the UCP login-link OAuth flow. Pruva reproduced it (reproduction REPRO-2026-00223).

02 · Severity & CVSS

CVE-2026-48611 Severity & CVSS Score

CVE-2026-48611 is rated critical severity, with a CVSS base score of 9.8 out of 10.

CRITICAL threat level
9.8 / 10 CVSS base
Weakness CWE-305: Authentication Bypass by Primary Weakness

Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.

03 · Affected Versions

Affected phpbb/phpbb Versions

phpbb/phpbb · github versions phpBB 3.3.0 through 3.3.16 and 4.0.0-a2 (default configuration, auth_method=db) are affected.

How to Reproduce CVE-2026-48611

$ pruva-verify REPRO-2026-00223
or curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00223/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-48611

Authorization bypass — reproduced
  • reached the target end-to-end
  • full exploit chain demonstrated
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

auth_provider=apache request parameter plus HTTP Basic Authorization header (PHP_AUTH_USER set to any existing username, e.g. admin); password deliberately wrong (x)

Attack chain
  1. Single unauthenticated POST to ucp.php?mode=login_link&auth_provider=apache&login_link_aikido=1 with header Authorization: Basic base64(admin:x) and body login_username=admin&login_password=x&login=Login
  2. apache provider returns LOGIN_SUCCESS without password check
  3. session_create(admin user_id=2)
Variants tested

Variant/bypass analysis for CVE-2026-48611 (phpBB login-link auth bypass via attacker-steerable auth_provider=apache). A systematic matrix of 4 materially-distinct entry/data paths (register-flow residual attacker-steerable get_provider(), auth_provider forwarded through the login_link redirect, direct controller link…

How the agent worked 506 events · 214 tool calls · 22 min
22 minDuration
214Tool calls
130Reasoning steps
506Events
2Dead-ends
Agent activity over 22 min
Support
22
Hypothesis
2
Repro
238
Judge
19
Variant
115
Coding
105
0:0022:09

Root Cause and Exploit Chain for CVE-2026-48611

Versions: phpBB 3.3.0 through 3.3.16, and 4.0.0-a2. Default

CVE-2026-48611 is a critical unauthenticated authentication-bypass in phpBB 3.3.0–3.3.16 (and 4.0.0-a2). The UCP "login-link" flow (ucp.php?mode=login_link) lets an attacker choose which authentication provider handles the login via a fully attacker-controlled auth_provider request parameter. By selecting the bundled apache provider and sending an HTTP Basic Authorization header that carries any existing username (e.g. admin), an unauthenticated remote attacker obtains a valid phpBB session as that user — including administrators — without knowing the password. The apache provider trusts PHP_AUTH_USER from the Basic header and returns LOGIN_SUCCESS after a database lookup without ever validating the password, after which ucp_login_link calls $user->session_create(). The flaw is present in the default auth_method=db installation; OAuth does not need to be configured. Fixed in phpBB 3.3.17 (2026-06-06).

  • Package/component affected: phpBB/includes/ucp/ucp_login_link.php (attacker-controlled provider selection) combined with phpBB/phpbb/auth/provider/apache.php (password-less login()).
  • Affected versions: phpBB 3.3.0 through 3.3.16, and 4.0.0-a2. Default auth_method=db boards are vulnerable out of the box.
  • Risk level and consequences: Critical (CVSS 9.8). A single unauthenticated HTTP request hijacks any known account. Logging in as an administrator yields full board control (ACP access, user management, extension installation, persisted backdoors). Usernames are public on phpBB boards, so admin/moderator accounts are trivially targetable.

Impact Parity

  • Disclosed/claimed maximum impact: Unauthenticated remote account hijacking of arbitrary known accounts (including administrators) → full board compromise; no password, no prior access, no user interaction.
  • Reproduced impact from this run: Full parity. Against a real running phpBB 3.3.16 (Apache 2.4 + mod_php 8.2 + SQLite, default auth_method=db, installed via the official CLI installer) a single unauthenticated POST to ucp.php?mode=login_link&auth_provider=apache&login_link_aikido=1 with Authorization: Basic admin:x (password x deliberately wrong) returned a 302 response that set the session cookie phpbb3_..._u=2 (the administrator account, user_id=2, user_type=USER_FOUNDER). Reloading index.php with that stolen session rendered the page as the admin user and showed the Administration Control Panel link (adm/index.php) — an admin-only UI element — confirming a genuine administrator session. The same request against phpBB 3.3.17 left the session as anonymous (_u=1) and produced no admin session.
  • Parity: full.
  • Not demonstrated: N/A — the claimed impact (authz bypass / admin account takeover) was demonstrated end-to-end on the real product.

Root Cause

Two cooperating defects form the exploit chain:

  1. Attacker-controlled auth provider. In ucp_login_link::main() the provider is resolved from the request:

    // phpBB/includes/ucp/ucp_login_link.php (3.3.16)
    $provider_collection = $phpbb_container->get('auth.provider_collection');
    $auth_provider = $provider_collection->get_provider($request->variable('auth_provider', ''));
    

    The auth_provider value is taken verbatim from the request (GET or POST), so an attacker can force the use of any registered provider class under phpbb/auth/provider/, not only the board's configured auth_method.

  2. Password-less apache provider. phpbb/auth/provider/apache.php::login() decodes PHP_AUTH_USER/PHP_AUTH_PW from the HTTP Basic Authorization header, requires that PHP_AUTH_USER === $username, looks the user up in the database, and — for an active user — returns LOGIN_SUCCESS without comparing PHP_AUTH_PW to the stored password hash. This is intentional only when Apache itself is the authenticating proxy (.htpasswd); the provider simply trusts the username the proxy forwards. By driving this provider through the login-link flow, the attacker's own HTTP client becomes the "trusted proxy" and supplies any username it wants.

    Back in ucp_login_link::main(), a LOGIN_SUCCESS result with no error leads directly to:

    $user->session_create($login_result['user_row']['user_id'], false, false, true);
    $this->perform_redirect();
    

    i.e. a fully authenticated session for the chosen user is created and the browser is redirected to the index — all from one unauthenticated POST.

The login-link gate (get_login_link_data_array() requiring a non-empty login_link_* GET parameter) is trivially satisfied with dummy data such as login_link_aikido=1, so it provides no meaningful protection.

Fix (phpBB 3.3.17, ticket/17659). The login-link handling was moved out of ucp.php/ucp_login_link.php into a dedicated controller phpbb/ucp/controller/oauth.php. In ucp.php the login_link mode now redirects to that controller (phpbb_redirect_to_controller(...)), and the controller resolves the provider without the attacker-controlled argument:

// phpBB/phpbb/ucp/controller/oauth.php (3.3.17), link_account()
$auth_provider = $this->auth_collection->get_provider();   // no argument -> configured auth_method (db)

With the default db provider, login() actually verifies the password hash, so the wrong password (x) is rejected and no session is created. The auth_provider=apache trick is therefore no longer reachable. Key commits in release-3.3.16..release-3.3.17: 12c4cf6f78, c05603cc3a, 4a2962bfc8 ([ticket/17659] series — "Add new oauth link controller" / "Make account linking work via controller" / "Move login linking for oauth to controller").

Reproduction Steps

  1. Script: bundle/repro/reproduction_steps.sh (self-contained, idempotent; run with PRUVA_ROOT=<bundle dir> bash bundle/repro/reproduction_steps.sh).
  2. What it does:
    • Reuses (or creates) git worktrees of phpBB at release-3.3.16 (vulnerable) and release-3.3.17 (fixed) from the durable project cache mirror.
    • Builds a Docker image per version on php:8.2-apache (gd/intl/zip extensions, mod_rewrite, AllowOverride All) and runs the official phpBB CLI installer (install/phpbbcli.php install) with a SQLite backend and an admin/adminadmin founder account (user_id=2).
    • Starts each image as a running Apache+mod_php service and sends the real exploit through it (HTTP requests are issued from inside each container against 127.0.0.1:80, because the sandbox blocks host→container port publishing; this still crosses the genuine Apache/PHP request boundary and populates PHP_AUTH_USER/PHP_AUTH_PW via mod_php):
      POST /ucp.php?mode=login_link&auth_provider=apache&login_link_aikido=1
      Authorization: Basic base64(admin:x)
      Content-Type: application/x-www-form-urlencoded
      login_username=admin&login_password=x&login=Login
      
    • Asserts the vulnerable build sets the session cookie *_u=2 and that the index page, loaded with the stolen session, shows the admin username and the ACP link. Asserts the fixed build leaves the session anonymous (*_u=1) for the same request (both via ucp.php and directly via the new controller /app.php/user/oauth/link_account).
  3. Expected evidence: The vulnerable response is a 302 Found whose Set-Cookie headers include phpbb3_...._u=2 and a Location to the index; the fixed response is a 301 redirect to the controller (ucp.php path) / a 200 login-link form with a class="error" block and phpbb3_...._u=1 (controller path). The script exits 0 only when the vulnerable build hijacks admin and the fixed build blocks it.

Evidence

  • bundle/logs/reproduction_steps.log — full annotated run log (two consecutive successful runs).
  • bundle/logs/vuln_exploit_response.txt / bundle/logs/vuln_setcookie_summary.txt — vulnerable 3.3.16 exploit response. Excerpt:
    HTTP/1.1 302 Found
    Set-Cookie: phpbb3_c6ct2_u=1; ...; HttpOnly
    Set-Cookie: phpbb3_c6ct2_u=2; ...; HttpOnly          <-- admin user_id=2
    Location: http://localhost/index.php?sid=e7988db9...
    
  • bundle/repro/artifacts/vuln/index_with_session.htmlindex.php loaded with the stolen cookie; contains username-coloured">admin and the admin-only Administration Control Panel / adm/index.php link.
  • bundle/repro/artifacts/vuln/cookies.txt — Netscape cookie jar with phpbb3_..._u = 2.
  • bundle/logs/fixed_exploit_ctrl_response.txt / bundle/logs/fixed_setcookie_summary.txt — fixed 3.3.17 controller response. Excerpt: only Set-Cookie: phpbb3_9wg5u_u=1 (anonymous) and a <div class="error">...not available. Please restart the login process.</div> block; no _u=2, no redirect to the index.
  • bundle/repro/artifacts/fixed/exploit_ucp_response.txt — fixed ucp.php path returns 301 Moved Permanently to /app.php/user/oauth/link_account?... (no apache-provider login).
  • bundle/repro/runtime_manifest.json — runtime evidence manifest (entrypoint_kind=api_remote, service_started=true, healthcheck_passed=true, target_path_reached=true).
  • Environment: Docker php:8.2-apache (Apache/2.4.67, PHP/8.2.32, mod_php), phpBB release-3.3.16 and release-3.3.17, SQLite3 backend, default auth_method=db, board installed via php install/phpbbcli.php install.

Recommendations / Next Steps

  • Patch immediately. Upgrade every phpBB instance to 3.3.17 or later. This is the only complete fix.
  • Temporary workaround (pre-3.3.17, only if Apache/LDAP auth is unused): remove phpbb/auth/provider/apache.php and phpbb/auth/provider/ldap.php from the board root, and disable OAuth in the ACP until upgraded (per the phpBB team's urgent advisory).
  • Defense-in-depth: authentication providers must never be selectable from untrusted request input; provider resolution should always use the board-configured auth_method. The apache provider's trust model (proxy authenticated the user) should be gated to boards that actually configure Apache/LDAP front-auth, and should not be exposed through flows designed for OAuth.
  • Detection: hunt request logs for mode=login_link together with auth_provider=apache (in either query string or POST body); also watch for the body-only variant where mode=login_link and auth_provider=apache are in the POST body while the query string carries login_link_*=1.
  • Testing: add a regression test asserting that ucp.php?mode=login_link never honors an attacker-supplied auth_provider, and that the apache provider cannot grant LOGIN_SUCCESS without external-auth configuration.

Additional Notes

  • Idempotency: reproduction_steps.sh was executed twice consecutively; both runs exited 0 with identical verdicts. The script reuses cached worktrees and Docker images on subsequent runs (only container start/stop and the HTTP exploit are re-executed), so re-runs complete in a few seconds.
  • Surface match: the claimed surface is api_remote (HTTP endpoint). The proof drives the real Apache+mod_php endpoint ucp.php (and the fixed controller) with the actual exploit request, satisfying the api_remote/endpoint requirement; runtime_manifest.json records service_started, healthcheck_passed, and target_path_reached all true.
  • Sandbox networking note: host→container port publishing is blocked in this environment, so the script issues exploit traffic from inside each container via docker exec curl http://127.0.0.1:80/.... This still crosses the genuine Apache + mod_php request boundary (PHP_AUTH_USER/PHP_AUTH_PW are populated by mod_php from the Authorization: Basic header), and is equivalent to an external attacker hitting the deployed forum over HTTP.
  • Negative control: the identical exploit request against 3.3.17 does not create an admin session (_u=1), and ucp.php?mode=login_link is reduced to a redirect to the new OAuth controller, confirming the patch closes the attack path.

Variant Analysis & Alternative Triggers for CVE-2026-48611

Versions: versions as tested: phpBB release-3.3.16

No bypass or materially-distinct alternate trigger of CVE-2026-48611 was found on the fixed phpBB 3.3.17. The CVE's root cause is two cooperating defects: (1) an attacker-steerable auth-provider selection (provider_collection::get_provider($request->variable('auth_provider', ''))) and (2) the password-less apache provider login() that returns LOGIN_SUCCESS for any existing username carried in the HTTP Basic Authorization header without validating the password, after which the caller invokes $user->session_create(user_id) → unauthenticated account hijack. The 3.3.17 fix deleted includes/ucp/ucp_login_link.php, redirected ucp.php?mode=login_link to a new phpbb/ucp/controller/oauth.php controller, and changed provider resolution in that flow to get_provider() with no argument (→ board-configured auth_method, default db), so the apache password-less sink is no longer reachable from request-steered provider selection. A systematic variant matrix (4 materially-distinct entry/data paths + the original-exploit control) was executed against both the vulnerable 3.3.16 and the fixed 3.3.17 builds: the fixed build blocks every candidate (*_u=1, anonymous, no admin session), while the 3.3.16 control still hijacks admin (user_id=2) with the ACP link present. One residual instance of the anti-pattern (attacker-steerable get_provider() in includes/ucp/ucp_register.php) survives the fix, but it does not reach the password-less login() sink and produces no account hijack on either version, so it is a defense-in-depth gap, not a bypass.

Fix Coverage / Assumptions

  • Invariant the fix relies on: "Authentication providers must never be selectable from untrusted request input; provider resolution should always use the board-configured auth_method." The new oauth controller enforces this by calling $this->auth_collection->get_provider() with no argument in link_account(), authenticate(), and login().
  • Code paths explicitly covered: ucp.php?mode=login_link (now a redirect), the new controller routes /oauth/link_account, /oauth/authenticate/{svc}, /oauth/login/{svc} (the latter additionally guarded by an instanceof \phpbb\auth\provider\oauth\oauth check that throws HTTP 401 for non-oauth-configured boards).
  • What the fix does NOT cover: includes/ucp/ucp_register.php still resolves the provider with get_provider($request->variable('auth_provider', '')) when login_link_* POST data is present. This is the same request-steerable pattern that was the root cause, and it was left untouched. Decisively, though, the register flow uses that provider only for login_link_has_necessary_data() and link_account() — it never calls ->login() on it, and its only session_create() is for the newly registered user. So the dangerous sink is not reachable from this residual instance.

Variant / Alternate Trigger

Four materially-distinct candidate entry/data paths were tested against the fixed 3.3.17 (each also run against 3.3.16 for parity/control):

  • V1 — Residual attacker-controlled provider in the REGISTER flow. Entry point: POST ucp.php?mode=register&auth_provider=apache with login_link_aikido=1 in the body + registration fields (and, on the vuln build, an Authorization: Basic admin:x header). Code path: includes/ucp/ucp_register.php::main() (~line 120) get_provider($request->variable('auth_provider', ''))apache::login_link_has_necessary_data() (inherits base::login_link_has_necessary_data() → returns 'LOGIN_LINK_MISSING_DATA') and apache::link_account() (inherits base::link_account() → no-op). Result: no admin session on either version (*_u=1). The register flow never calls ->login() on the selected provider, so the password-less sink is unreachable. Not a variant of the auth-bypass.

  • V2 — auth_provider forwarded through the login_link redirect. Entry point: POST ucp.php?mode=login_link&auth_provider=apache&login_link_aikido=1. ucp.php forwards all GET params (incl. auth_provider) to /app.php/user/oauth/link_account via phpbb_redirect_to_controller(). Code path: the controller link_account() calls get_provider() with no argument and never reads auth_provider. Result on fixed: 301 Moved Permanently → controller → *_u=1. The forwarded auth_provider is ignored. Blocked.

  • V3 — Direct controller hit with auth_provider=apache in the query string. Entry point: POST /app.php/user/oauth/link_account?auth_provider=apache&login_link_aikido=1

    • Authorization: Basic admin:x + login_username=admin&login_password=x. Code path: oauth::link_account()get_provider() no-arg → dbdb::login('admin','x') verifies the password hash → rejects. Result on fixed: 200 login-link form with a class="error" block, *_u=1. auth_provider in the query is never read by the controller. Blocked.
  • V4 — The new oauth LOGIN controller with a Basic header. Entry point: GET /app.php/user/oauth/login/apache + Authorization: Basic admin:x. Code path: oauth::login('apache')get_provider() no-arg → dbif (!$provider instanceof \phpbb\auth\provider\oauth\oauth) throw 401. Result on fixed: 401 Unauthorized, *_u=1. The instanceof guard rejects the default db-configured board. Blocked.

  • V5 — Original exploit (CONTROL). Entry point: POST ucp.php?mode=login_link&auth_provider=apache&login_link_aikido=1 + Authorization: Basic admin:x. Result on 3.3.16: 302, Set-Cookie *_u=2, ACP link present → admin hijack confirmed (parity with the repro). Result on 3.3.17 (ucp.php path): 301 → controller → *_u=1; (controller path): 200 form + error, *_u=1. Fixed build blocks the original exploit.

A whole-repo search in 3.3.17 for get_provider($request->variable('auth_provider' returns exactly one hit (ucp_register.php:120, analyzed as V1). Every other get_provider( call site (in auth.php, session.php, functions.php, ucp_auth_link.php, and all three oauth.php controller actions) passes no argument. There is no remaining request-steerable get_provider() that is followed by a ->login() + session_create() chain.

  • Package/component affected (by the residual anti-pattern): phpBB/includes/ucp/ucp_register.php (attacker-steerable provider selection) — but the dangerous sink (apache::login()session_create() for an arbitrary existing user) is not reachable from it.
  • Affected versions as tested: phpBB release-3.3.16 (commit 555f0aaa6b892efb2e6b6edd2362302a3ef8b339) and release-3.3.17 (commit 3508484fdc18cd97eeab229da830055c79fcc59e).
  • Risk level and consequences of the residual gap: Low / defense-in-depth only. No account hijack is achievable through it today. It is a latent inconsistency with the fix's stated invariant that should be closed to prevent a future regression from turning it into a real bypass.

Impact Parity

  • Disclosed/claimed maximum impact (parent CVE): Unauthenticated remote account hijacking of arbitrary known accounts (including administrators) → full board compromise; no password, no prior access, no user interaction.
  • Reproduced impact from this variant run: None on the fixed build. The fixed 3.3.17 blocked every candidate (V1–V4) with *_u=1 (anonymous) and no admin session. The 3.3.16 control (V5) reproduced the parent impact (_u=2 + ACP link) confirming the test harness is sound and the original exploit still works on the vulnerable version.
  • Parity: none (no bypass / no alternate trigger reproducing the CVE impact on the fixed build).
  • Not demonstrated: No admin-session creation via any path other than the original ucp.php?mode=login_link&auth_provider=apache exploit on the vulnerable 3.3.16.

Root Cause

The CVE's exploitable chain requires both (1) a request-steerable get_provider($request->variable('auth_provider', '')) and (2) a subsequent ->login() on the selected provider whose result feeds session_create() for an existing user. The 3.3.17 fix eliminates (1) from the login-link flow by switching to get_provider() with no argument, so on a default db board the only provider reachable is db, whose login() verifies the password hash and rejects the wrong password. The single surviving request-steerable get_provider() (in ucp_register.php) is not followed by a ->login() call — it is followed only by login_link_has_necessary_data() (which the apache provider inherits as a hard-coded 'LOGIN_LINK_MISSING_DATA' error) and link_account() (a no-op for apache) — so defect (2) is not reachable from it. Therefore the same underlying bug cannot still be reached on the fixed build via any of the materially-distinct entry/data paths examined.

Fix commits (in release-3.3.16..release-3.3.17): 12c4cf6f78, c05603cc3a, 4a2962bfc8 ([ticket/17659] series).

Reproduction Steps

  1. Script: bundle/vuln_variant/reproduction_steps.sh (self-contained, idempotent; run with PRUVA_ROOT=<bundle dir> bash bundle/vuln_variant/reproduction_steps.sh). It reuses the Docker images (phpbb-cve2026-48611:vuln / :fixed) built by the repro stage.
  2. What it does: starts both containers, then issues real HTTP requests from inside each container against the running Apache+mod_php service:
    • V5 control: original exploit on 3.3.16 (expect admin hijack) and on 3.3.17 via both ucp.php and the controller (expect blocked).
    • V1: register flow with auth_provider=apache + login_link_* on both builds (expect no admin session on either).
    • V2: auth_provider forwarded via the ucp.php?mode=login_link redirect on 3.3.17 (expect 301*_u=1).
    • V3: direct controller /oauth/link_account?auth_provider=apache on 3.3.17 (expect form + error, *_u=1).
    • V4: oauth login controller /oauth/login/apache with a Basic header on 3.3.17 (expect 401, *_u=1).
    • Verdict: exit 0 if any fixed-build path mints an admin session (_u=2); exit 1 if every candidate is blocked (the actual outcome).
  3. Expected evidence: bundle/logs/vuln_variant.log shows vuln_hijack=yes; fixed_original_blocked=yes; fixed_variant_hit=no and RESULT: NO BYPASS. Per-candidate response captures live under bundle/logs/vv_*.txt (e.g. vv_fixed_v3_resp.txt shows the controller rendered the login-link form with Set-Cookie *_u=1 and a class="error" block; vv_fixed_v4_resp.txt shows 401 Unauthorized; vv_vuln_v5_resp.txt shows the 302 + Set-Cookie *_u=2 hijack on 3.3.16).

Evidence

  • bundle/logs/vuln_variant.log — annotated run log (two consecutive runs, identical verdicts).
  • bundle/logs/vv_vuln_v5_resp.txt — 3.3.16 original exploit: 302 Found + Set-Cookie: phpbb3_..._u=2 (admin) → hijack confirmed (control/parity).
  • bundle/logs/vv_fixed_v5ctrl_resp.txt — 3.3.17 controller path: 200 form with class="error" + Set-Cookie: phpbb3_..._u=1 (anonymous) → original exploit blocked.
  • bundle/logs/vv_fixed_v1_register_resp.txt — 3.3.17 register flow with auth_provider=apache: agreement/form page, *_u=1, no admin session.
  • bundle/logs/vv_fixed_v3_resp.txt — 3.3.17 controller with auth_provider=apache in query: 200 form, Set-Cookie *_u=1, class="error" block (controller ignores auth_provider).
  • bundle/logs/vv_fixed_v4_resp.txt — 3.3.17 oauth login controller: 401 Unauthorized, *_u=1 (instanceof oauth\oauth guard).
  • bundle/vuln_variant/runtime_manifest.json — runtime evidence manifest (entrypoint_kind=api_remote, service_started=true, healthcheck_passed=true, target_path_reached=true, bypass_found=false).
  • bundle/vuln_variant/artifacts/ — raw per-candidate cookie jars + response captures for both builds.
  • Environment: Docker php:8.2-apache (Apache/2.4.67, PHP/8.2.32, mod_php), phpBB release-3.3.16 (commit 555f0aaa...) and release-3.3.17 (commit 3508484f...), SQLite3 backend, default auth_method=db, board installed via php install/phpbbcli.php install. Exact tested revisions resolved via git rev-parse <tag>^{commit} and recorded in bundle/vuln_variant/source_identity.json.

Recommendations / Next Steps

  • No emergency action beyond the 3.3.17 upgrade is needed for the auth-bypass itself — the fix closes the account-hijack path on default db boards.
  • Close the residual anti-pattern for defense-in-depth / future-proofing: change includes/ucp/ucp_register.php (~line 120) to call $provider_collection->get_provider(); (no argument) instead of get_provider($request->variable('auth_provider', '')), so provider selection in the register flow also uses the board-configured auth_method. This aligns the register flow with the fix's stated invariant and removes the latent risk that a future refactor adds a ->login() call on the request-steered provider.
  • Add a regression test asserting that no unauthenticated UCP entry point (login_link, register, the oauth controllers) ever honors an attacker-supplied auth_provider, and that the apache provider cannot return LOGIN_SUCCESS without external-auth configuration.
  • Optional hardening: gate the apache provider's trust model (PHP_AUTH_USER is trusted) to boards that actually configure Apache/LDAP front-auth, and refuse to honour it through flows designed for OAuth/db logins.

Additional Notes

  • Idempotency: reproduction_steps.sh was executed twice consecutively; both runs exited 1 (no bypass) with identical verdicts (vuln_hijack=yes; fixed_original_blocked=yes; fixed_variant_hit=no). Re-runs reuse the cached Docker images and only re-start containers and re-issue HTTP requests, completing in a few seconds.
  • Bounded search justification: the variant search was bounded by a whole-repo scan for the combination that defines the root cause — a request-steerable get_provider($request->variable('auth_provider', '')) that is followed by a ->login() + session_create() chain. In 3.3.17 that combination exists in zero places: the only request-steerable get_provider() left (ucp_register.php) is not followed by ->login(). The other request-facing get_provider() call sites all pass no argument. Additional "attempts" beyond V1–V4 would be the same root cause/surface under a different name (e.g. calling link_account vs authenticate on the same controller that already uses no-arg get_provider()), so they are not materially distinct candidates.
  • Negative control integrity: the 3.3.16 build still hijacks admin via the original exploit (_u=2 + ACP link), proving the test harness reaches the real Apache+mod_php boundary and that the "blocked" results on 3.3.17 are due to the fix, not a broken exploit.
  • Sandbox networking: host→container port publishing is blocked, so exploit traffic is issued from inside each container via docker exec curl http://127.0.0.1:80/..., which still crosses the genuine Apache + mod_php request boundary (mod_php populates PHP_AUTH_USER/PHP_AUTH_PW from the Authorization: Basic header) and is equivalent to an external attacker hitting the deployed forum over HTTP.

CVE-2026-48611 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:001:17
0:00
session startedaccounts/fireworks/routers/glm-5p2-fast · CVE-2026-48611 · REPRO-20
0:02
0:04
web search
0:06
web search
0:09
0:14
0:16
web search
0:19
0:20
web search
0:22
0:27
0:28
web search
0:30
web search
0:48
0:48
extract_facts
no facts extracted
0:49
0:50
0:50
supportrepro
1:07
1:09
1:09
1:09
1:10
1:10
1:10
1:12
1:12
1:13
1:17

Artifacts and Evidence for CVE-2026-48611

Scripts, logs, diffs, and output captured during the reproduction.

bundle/ticket.md1.1 KB
bundle/ticket.json2.2 KB
bundle/AGENTS.repro.md0.5 KB
bundle/docker/Dockerfile2.3 KB
bundle/docker/apache-site.conf0.3 KB
bundle/docker/install-config.yml0.7 KB
bundle/repro/artifacts/vuln/exploit_response.txt0.8 KB
bundle/repro/artifacts/vuln/cookies.txt0.3 KB
bundle/repro/artifacts/vuln/index_with_session.html15.4 KB
bundle/repro/artifacts/fixed/exploit_ucp_response.txt1.4 KB
bundle/repro/artifacts/fixed/cookies_ucp.txt0.3 KB
bundle/repro/artifacts/fixed/exploit_ctrl_response.txt11.6 KB
bundle/repro/artifacts/fixed/cookies_ctrl.txt0.3 KB
bundle/repro/runtime_manifest.json1.0 KB
bundle/repro/validation_verdict.json1.0 KB
bundle/logs/reproduction_steps.log2.5 KB
bundle/logs/vuln_exploit_response.txt0.8 KB
bundle/logs/fixed_exploit_ctrl_response.txt11.6 KB
bundle/logs/vuln_setcookie_summary.txt0.2 KB
bundle/logs/fixed_setcookie_summary.txt0.2 KB
bundle/logs/vuln_variant.log4.3 KB
bundle/logs/vv_vuln_v5_resp.txt0.8 KB
bundle/logs/vv_fixed_v5ctrl_resp.txt11.6 KB
bundle/logs/vv_fixed_v1_register_resp.txt12.1 KB
bundle/logs/vv_fixed_v3_resp.txt11.7 KB
bundle/logs/vv_fixed_v4_resp.txt9.7 KB
bundle/vuln_variant/artifacts/vuln/v5_cookies.txt0.3 KB
bundle/vuln_variant/artifacts/vuln/v5_cookies.txt.resp.txt0.8 KB
bundle/vuln_variant/artifacts/vuln/v5_index.html15.5 KB
bundle/vuln_variant/artifacts/vuln/v1_form_cookies.txt0.3 KB
bundle/vuln_variant/artifacts/vuln/v1_form_cookies.txt.resp.txt0.5 KB
bundle/vuln_variant/artifacts/vuln/v1_submit_cookies.txt0.3 KB
bundle/vuln_variant/artifacts/vuln/v1_submit_cookies.txt.resp.txt12.1 KB
bundle/vuln_variant/artifacts/fixed/v5_ucp_cookies.txt0.3 KB
bundle/vuln_variant/artifacts/fixed/v5_ucp_cookies.txt.resp.txt1.4 KB
bundle/vuln_variant/artifacts/fixed/v5_ctrl_cookies.txt0.3 KB
bundle/vuln_variant/artifacts/fixed/v5_ctrl_cookies.txt.resp.txt11.6 KB
bundle/vuln_variant/artifacts/fixed/v1_form_cookies.txt0.3 KB
bundle/vuln_variant/artifacts/fixed/v1_form_cookies.txt.resp.txt0.5 KB
bundle/vuln_variant/artifacts/fixed/v1_submit_cookies.txt0.3 KB
bundle/vuln_variant/artifacts/fixed/v1_submit_cookies.txt.resp.txt12.1 KB
bundle/vuln_variant/artifacts/fixed/v2_cookies.txt0.3 KB
bundle/vuln_variant/artifacts/fixed/v2_cookies.txt.resp.txt1.4 KB
bundle/vuln_variant/artifacts/fixed/v3_cookies.txt0.3 KB
bundle/vuln_variant/artifacts/fixed/v3_cookies.txt.resp.txt11.7 KB
bundle/vuln_variant/artifacts/fixed/v4_cookies.txt0.3 KB
bundle/vuln_variant/artifacts/fixed/v4_cookies.txt.resp.txt9.7 KB
bundle/vuln_variant/artifacts/.resp.tmp9.7 KB
bundle/vuln_variant/runtime_manifest.json0.9 KB
bundle/vuln_variant/patch_analysis.md11.3 KB
bundle/vuln_variant/variant_manifest.json5.5 KB
bundle/vuln_variant/validation_verdict.json5.0 KB
bundle/vuln_variant/source_identity.json1.9 KB
bundle/vuln_variant/root_cause_equivalence.json3.0 KB
bundle/logs/verify_fix.log1.2 KB
bundle/logs/verify_build_patched.log13.2 KB
bundle/coding/verify_artifacts/testA_response.txt11.6 KB
bundle/coding/verify_artifacts/testA_cookies.txt0.3 KB
bundle/coding/verify_artifacts/testB_response.txt0.8 KB
bundle/coding/verify_artifacts/testB_cookies.txt0.3 KB
bundle/coding/verify_artifacts/testB_index_with_session.html15.5 KB
bundle/coding/verify_artifacts/control_response.txt0.8 KB
bundle/coding/verify_artifacts/control_cookies.txt0.3 KB
bundle/coding/verify_result.json0.7 KB
bundle/repro/reproduction_steps.sh15.0 KB
bundle/repro/rca_report.md12.1 KB
bundle/vuln_variant/reproduction_steps.sh16.9 KB
bundle/vuln_variant/rca_report.md15.3 KB
bundle/coding/proposed_fix.diff1.8 KB
bundle/coding/verify_fix.sh13.2 KB
bundle/coding/summary_report.md12.8 KB
08 · How to Fix

How to Fix CVE-2026-48611

Upgrade phpbb/phpbb · github to phpBB 3.3.17 released 2026-06-06 or later.

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-48611 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-48611

How does the phpBB auth_provider=apache bypass attack work?

An attacker sends a request to ucp.php?mode=login_link&auth_provider=apache with an HTTP Basic Authorization header carrying a known username (e.g. admin). The apache provider matches PHP_AUTH_USER against the submitted username, confirms the user exists in the database, and returns success — after which ucp_login_link calls $user->session_create() for that account, giving the attacker a valid session without knowing the password.

Which phpBB versions are affected by CVE-2026-48611, and where is it fixed?

phpBB 3.3.0 through 3.3.16 and 4.0.0-a2, in the default auth_method=db configuration, are affected. It is fixed in phpBB 3.3.17, released 2026-06-06.

How severe is CVE-2026-48611?

Critical — a single unauthenticated HTTP request hijacks any known account, and logging in as an administrator yields full board control (ACP access, user management, extension installation, persisted backdoors).

How can I reproduce CVE-2026-48611?

Download the verified script from this page and run it in an isolated environment against phpBB 3.3.0-3.3.16 with default auth_method=db. It sends an unauthenticated request to ucp.php?mode=login_link with auth_provider=apache and a Basic Authorization header naming a known username, then confirms a valid session is created for that account.
11 · References

References for CVE-2026-48611

Authoritative sources for CVE-2026-48611 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.