<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Cpe:2.3:a:openwebui:open_webui:*:*:*:*:*:*:*:* — CraftedSignal Threat Feed</title><link>https://feed.craftedsignal.io/cpes/cpe2.3aopenwebuiopen_webui/</link><description>Trending threats, MITRE ATT&amp;CK coverage, and detection metadata. Fed continuously.</description><generator>Hugo</generator><language>en</language><managingEditor>hello@craftedsignal.io</managingEditor><webMaster>hello@craftedsignal.io</webMaster><lastBuildDate>Thu, 14 May 2026 20:31:48 +0000</lastBuildDate><atom:link href="https://feed.craftedsignal.io/cpes/cpe2.3aopenwebuiopen_webui/feed.xml" rel="self" type="application/rss+xml"/><item><title>Open WebUI Stored XSS Vulnerability via OAuth Profile Picture</title><link>https://feed.craftedsignal.io/briefs/2026-05-open-webui-xss/</link><pubDate>Thu, 14 May 2026 20:31:48 +0000</pubDate><author>hello@craftedsignal.io</author><guid isPermaLink="true">https://feed.craftedsignal.io/briefs/2026-05-open-webui-xss/</guid><description>Open WebUI is vulnerable to stored cross-site scripting (XSS) via OAuth profile picture handling, allowing an attacker to inject malicious SVG code and potentially takeover user accounts by exfiltrating JWT tokens.</description><content:encoded><![CDATA[<p>Open WebUI versions 0.9.4 and earlier are vulnerable to a stored cross-site scripting (XSS) attack due to improper validation of profile images when users sign in via OAuth. The application fetches a URL provided in the OAuth <code>picture</code> claim, infers the MIME type from the URL extension, and stores it as a data URI without proper sanitization. Specifically, an attacker can host a malicious SVG file and set their profile picture URL to that file. When a victim clicks the link to the attacker&rsquo;s profile image, the browser executes the SVG code, potentially leading to account takeover by exfiltrating the victim&rsquo;s JWT token. This vulnerability is similar to CVE-2025-64496 and CVE-2025-64495, which highlights trust boundary errors in Open WebUI.</p>
<h2 id="attack-chain">Attack Chain</h2>
<ol>
<li>The attacker crafts a malicious SVG file containing JavaScript code to exfiltrate <code>localStorage.token</code>.</li>
<li>The attacker hosts the malicious SVG file on a publicly accessible server (e.g., <code>https://attacker.example/p.svg</code>).</li>
<li>The attacker configures their OAuth profile picture URL to point to the malicious SVG file.</li>
<li>The attacker signs in to Open WebUI via OAuth, triggering the application to fetch and store the SVG data URI as their profile image.</li>
<li>The attacker crafts a URL to their profile image endpoint (e.g., <code>https://target.example/api/v1/users/&lt;attacker-user-id&gt;/profile/image</code>) and shares it with a victim.</li>
<li>The authenticated victim clicks on the link.</li>
<li>The server serves the attacker-controlled SVG with <code>Content-Type: image/svg+xml</code> and <code>Content-Disposition: inline</code>.</li>
<li>The victim&rsquo;s browser renders the SVG, executes the embedded JavaScript, and exfiltrates the victim&rsquo;s JWT token to the attacker&rsquo;s server.</li>
</ol>
<h2 id="impact">Impact</h2>
<p>Successful exploitation can lead to account takeover of any authenticated user who clicks the malicious link. The attacker can then access the victim&rsquo;s chats, API keys, and potentially achieve remote code execution (RCE) via installed tools if the victim has the <code>workspace.tools</code> permission. Furthermore, the lack of SSRF protection allows an attacker to potentially read internal resources by pointing the <code>picture</code> claim at internal URLs.</p>
<h2 id="recommendation">Recommendation</h2>
<ul>
<li>Implement server-side MIME type validation in <code>_process_picture_url</code> (<code>utils/oauth.py:1336-1345</code>) to only allow <code>image/png</code>, <code>image/jpeg</code>, <code>image/gif</code>, and <code>image/webp</code>. Use the <code>Content-Type</code> response header instead of the URL extension.</li>
<li>Enforce a MIME whitelist in <code>get_user_profile_image_by_id</code> (<code>routers/users.py:504-528</code>) before building the <code>StreamingResponse</code>.</li>
<li>Apply the <code>validate_profile_image_url</code> validator at the model layer (<code>Users.update_user_profile_image_url_by_id</code>), not just at the Pydantic form layer, to ensure all profile image updates are validated.</li>
<li>Enable <code>X-Content-Type-Options: nosniff</code> and set a default Content Security Policy (CSP) to mitigate XSS attacks by setting the appropriate environment variables.</li>
</ul>
]]></content:encoded><category domain="severity">high</category><category domain="type">advisory</category><category>xss</category><category>stored-xss</category><category>oauth</category><category>open-webui</category></item></channel></rss>