GHSA-pm37-62g7-p768: AVideo Vulnerable to Reflected XSS via Unsanitized plugin Parameter in YPTWallet Stripe Payment Page
SummaryThe YPTWallet Stripe payment confirmation page directly echoes the `$_REQUEST['plugin']` parameter into a JavaScript block without any encoding or sanitization. The `plugin` parameter is not included in any of the framework's input filter lists defined in `security.php`, so it passes through completely raw. An attacker can inject arbitrary JavaScript by crafting a malicious URL and sending it to a victim user.The same script block also outputs the current user's username and password hash via `User::getUserName()` and `User::getUserPass()`, meaning a successful XSS exploitation can immediately exfiltrate these credentials.DetailsThe Stripe confirmation page renders the `plugin` parameter directly into a `<script>` block:This appears inside a `$.ajax()` data object within a `<script>` tag. Because the value is injected into a JavaScript string context (not HTML), standard HTML entity encoding would not be sufficient even if it were applied. However, no encoding of any kind is performed.The `plugin` parameter is not present in any of the sanitization or filtering arrays in `security.php`, so it arrives completely unmodified.Immediately adjacent to the injection point, the script also exposes user credentials:No Content-Security-Policy headers are configured on the application, so inline script execution is unrestricted.Proof of ConceptThe XSS is reachable through the `addFunds.php` page which includes the vulnerable `confirmButton.php` template:The injected value closes the JSON string and the `$.ajax()` call, then executes `alert(document.domain)`. The response contains the payload unencoded in the script block:Credential exfiltration payload:Simplified credential theft using the same-page credential leak:Reproduction steps:Navigate to the basic XSS URL above (substitute your target instance).Observe the JavaScript alert box confirming code execution.View the page source to confirm that `User::getUserName()` and `User::getUserPass()` are present in the same script block.Use the credential exfiltration payload to demonstrate data theft.ImpactAn attacker can execute arbitrary JavaScript in the context of any authenticated user who clicks a crafted link. The impact is amplified by the credential leak on the same page:**Immediate credential theft**: The page already renders the victim's username and password hash in the script block. The XSS payload can read and exfiltrate these values without any additional requests.**Session hijacking**: Steal session cookies and impersonate the victim.**Payment manipulation**: Since this is a payment confirmation page, the attacker can modify payment amounts, redirect payment confirmations, or trigger unauthorized transactions.**Account takeover**: Combine the stolen password hash with the username for offline cracking or direct replay.The lack of CSP headers means there are no browser-side mitigations against the injected scripts.**CWE**: CWE-79 (Cross-Site Scripting - Reflected)**Severity**: High (CVSS 8.1)Recommended FixApply `htmlspecialchars()` to the `plugin` parameter at `plugin/YPTWallet/plugins/YPTWalletStripe/confirmButton.php:116`:*Found by [aisafe.io](https://aisafe.io)*
CVSS v3.1: 8.2