惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
博客园 - 聂微东
Jina AI
Jina AI
Simon Willison's Weblog
Simon Willison's Weblog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
博客园 - 叶小钗
P
Proofpoint News Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
N
Netflix TechBlog - Medium
WordPress大学
WordPress大学
B
Blog
D
Docker
MyScale Blog
MyScale Blog
The GitHub Blog
The GitHub Blog
S
Schneier on Security
G
Google Developers Blog
Microsoft Azure Blog
Microsoft Azure Blog
量子位
Security Latest
Security Latest
S
Secure Thoughts
T
Tor Project blog
E
Exploit-DB.com RSS Feed
D
DataBreaches.Net
N
News and Events Feed by Topic
B
Blog RSS Feed
IT之家
IT之家
N
News | PayPal Newsroom
Attack and Defense Labs
Attack and Defense Labs
C
Check Point Blog
V
V2EX
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Recorded Future
Recorded Future
Martin Fowler
Martin Fowler
S
SegmentFault 最新的问题
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
L
LangChain Blog
Hugging Face - Blog
Hugging Face - Blog
阮一峰的网络日志
阮一峰的网络日志
M
MIT News - Artificial intelligence
Last Week in AI
Last Week in AI
D
Darknet – Hacking Tools, Hacker News & Cyber Security
博客园_首页
The Hacker News
The Hacker News
The Register - Security
The Register - Security
T
Threat Research - Cisco Blogs
腾讯CDC
P
Privacy International News Feed
T
Troy Hunt's Blog
云风的 BLOG
云风的 BLOG
L
LINUX DO - 最新话题

Aikido Security's Blog

GlassWorm goes native: New Zig dropper infects every IDE on your machine Aikido Attack finds multiple 0-days in Hoppscotch The cybersecurity doomerism around Mythos doesn't match what we see on the ground axios compromised on npm: maintainer account hijacked, RAT deployed Popular telnyx package compromised on PyPI by TeamPCP Aikido × Lovable: Vibe, Fix, Ship CanisterWorm Gets Teeth: TeamPCP's Kubernetes Wiper Targets Iran TeamPCP deploys CanisterWorm on NPM following Trivy compromise Security testing is validating software that no longer exists Aikido Recognized by Frost & Sullivan with the 2026 Customer Value Leadership Award in ASPM GlassWorm Hides a RAT Inside a Malicious Chrome Extension fast-draft Open VSX Extension Compromised by BlokTrooper Glassworm Strikes Popular React Native Phone Number Packages Glassworm Is Back: A New Wave of Invisible Unicode Attacks Hits Hundreds of Repositories How Security Teams Fight Back Against AI-Powered Hackers Introducing Betterleaks, an open source secrets scanner by the author of Gitleaks Trump’s 2026 cybersecurity strategy: From compliance to consequence How does AI pentesting work with compliance? What continuous pentesting actually requires Rare Not Random: Using Token Efficiency for Secrets Scanning Persistent XSS/RCE using WebSockets in Storybook’s dev server Why Determinism Is Still a Necessity in Security WAF vs. RASP vs. ADR Introducing Aikido Infinite: A new model of self-securing software How Aikido secures AI pentesting agents by design Astro Full-Read SSRF via Host Header Injection How to Get Your Board to Care About Security (Before a Breach Forces the Issue) What is Slopsquatting? The AI Package Hallucination Attack Already Happening SvelteSpill: A Cache Deception Bug in SvelteKit + Vercel Top 6 Wiz Code Alternatives Aikido recognized as Platform Leader in Latio Tech's 2026 Application Security Report From detection to prevention: How Zen stops IDOR vulnerabilities at runtime npm backdoor lets hackers hijack gambling outcomes Introducing Upgrade Impact Analysis: When breaking changes actually matter to your code Why Trying to Secure OpenClaw is Ridiculous Claude Opus 4.6 found 500 vulnerabilities. What does this change for software security? Introducing Aikido Expansion Packs: Safer defaults inside the IDE International AI Safety Report 2026: What It Means for Autonomous AI Systems Self-Securing Software: What It Is, Why It Matters, and How It Works npx Confusion: Packages That Forgot to Claim Their Own Name What Is Continuous Pentesting? Introducing Aikido Package Health: a Better Way to Trust Your Dependencies AI Pentesting: Minimum Safety Requirements for Security Testing Secure SDLC for Engineering Teams (+ Checklist) Fake Clawdbot VS Code Extension Installs ScreenConnect RAT G_Wagon: npm Package Deploys Python Stealer Targeting 100+ Crypto Wallets Gone Phishin': npm Packages Serving Custom Credential Harvesting Pages Malicious PyPI Packages spellcheckpy and spellcheckerpy Deliver Python RAT Top 10 AI Security Tools For 2026 Agent Skills Are Spreading Hallucinated npx Commands Understanding Open-Source License Risk in Modern Software The CISO Vibe Coding Checklist for Security Top 6 Graphite alternatives for AI code review in 2026 From “No Bullsh*t Security” to $1B: We Just Raised Our $60m Series B Critical n8n Vulnerability Allows Unauthenticated Remote Code Execution (CVE-2026-21858) Top 14 VS Code Extensions for 2026 AI-Driven Pentesting of Coolify: Seven CVEs Identified Top Continuous Pentesting Tools in 2026 SAST vs SCA: Securing the Code You Write and the Code You Depend On JavaScript, MSBuild, and the Blockchain: Anatomy of the NeoShadow npm Supply-Chain Attack How Engineering and Security Teams Can Meet DORA’s Technical Requirements IDOR Vulnerabilities Explained: Why They Persist in Modern Applications Shai Hulud strikes again - The golden path MongoBleed: MongoDB Zlib Vulnerability (CVE-2025-14847) and How to Fix It First Sophisticated Malware Discovered on Maven Central via Typosquatting Attack on Jackson The Fork Awakens: Why GitHub’s Invisible Networks Break Package Security Top 10 Cyber Security Tools For 2026 SAST in the IDE is now free: Moving SAST to where development actually happens AI Pentesting in Action: A TL;DV Recap of Our Live Demo The Top 7 Threat Intelligence Tools in 2026 React & Next.js DoS Vulnerability (CVE-2025-55184): What You Need to Fix After React2Shell OWASP Top 10 for Agentic Applications (2026): What Developers and Security Teams Need to Know DAST vs Pentesting v AI Pentesting: Why DAST Cannot Replace Modern Pentesting PromptPwnd: Prompt Injection Vulnerabilities in GitHub Actions Using AI Agents Top 7 Cloud Security Vulnerabilities Critical React & Next.js RCE Vulnerability (CVE-2025-55182): What You Need to Fix Now How to Comply With the UK Cybersecurity & Resilience Bill: A Practical Guide for Modern Engineering Teams Shai Hulud 2.0: What the Unknown Wonderer Tells Us About the Attackers’ Endgame SCA Everywhere: Scan and Fix Open-Source Dependencies in Your IDE Safe Chain now enforces a minimum package age before install Shai Hulud Attacks Persist Through GitHub Actions Vulnerabilities Shai Hulud Launches Second Supply-Chain Attack: Zapier, ENS, AsyncAPI, PostHog, Postman Compromised CORS Security: Beyond Basic Configuration Revolut Selects Aikido Security to Power Developer-First Software Security The Future of Pentesting Is Autonomous How Aikido and Deloitte are bringing developer-first security to enterprise Secrets Detection: A Practical Guide to Finding and Preventing Leaked Credentials Invisible Unicode Malware Strikes OpenVSX, Again AI as a Power Tool: How Windsurf and Devin Are Changing Secure Coding Building Fast, Staying Secure: Supabase’s Approach to Secure-by-Default Development OWASP Top 10 2025: Official List, Changes, and What Developers Need to Know Top 10 JavaScript Security Vulnerabilities in Modern Web Apps The Return of the Invisible Threat: Hidden PUA Unicode Hits GitHub repositorties Top 7 Black Duck Alternatives in 2026 What Is IaC Security Scanning? Terraform, Kubernetes & Cloud Misconfigurations Explained AutoTriage and the Swiss Cheese Model of Security Noise Reduction Top Software Supply Chain Security Vulnerabilities Explained The Top 7 Kubernetes Security Tools Top 10 Web Application Security Vulnerabilities Every Team Should Know What Is CSPM (and CNAPP)? Cloud Security Posture Management Explained
Multiple Cross-Site Scripting (XSS) Vulnerabilities in Mailcow
Jorian Woltjer · 2026-04-17 · via Aikido Security's Blog

Mailcow is a widely used self-hosted and open source email server that hosts everything you'd need to manage mailboxes yourself. To assess its security, we set up a local instance and ran our AI pentesting agents against it. We found three XSS vulnerabilities, including a critical vulnerability that allowed unauthenticated attackers to take over administrator accounts while looking at their logs in the UI. These have since been assigned CVE-2026-40872, CVE-2026-40873, and CVE-2026-40875.

Gaining access to a mailbox can have a serious security impact. Sensitive data found within emails can be captured, but access also enables attackers to use the password reset functionality to compromise the victim’s other connected accounts. This is exactly what would have been possible if someone had exploited these vulnerabilities.

All vulnerabilities were responsibly disclosed to Mailcow, and have been fixed since version 2026-03b (released March 31st 2026). We’d like to thank the maintainer, FreddleSpl0it, for the smooth process and quick fix.

Unescaped Autodiscover logs (CVE-2026-40872)

Reported on GitHub as GHSA-f9xf-vc72-rcgm, this vulnerability allowed unauthenticated attackers to send an Autodiscover request containing a malicious email address, which would show up in the logs. When an admin later views these logs, the email address field is displayed without being escaped, allowing for HTML injection and XSS.

Let's start at the sink. Mailcow allows viewing Autodiscover logs in a table on the admin panel, which is rendered using DataTables in dashboard.js. This library has the common pitfall of interpreting any data values as HTML by default. All values need to be properly escaped beforehand.

var table = $('#autodiscover_log').DataTable({
  ...
  ajax: {
    type: "GET",
    url: "/api/v1/get/logs/autodiscover/100",
    dataSrc: function(data){
      return process_table_data(data, 'autodiscover_log');
    }
  },

The process_table_data() function attempts to escape user input in each row. For Autodiscover logs,  item.ua (User Agent) is correctly escaped using escapeHtml (dashboard.js):

} else if (table == 'autodiscover_log') { 
   $.each(data, function (i, item) { 
     if (item.ua == null) { 
       item.ua = 'unknown'; 
     } else { 
       item.ua = escapeHtml(item.ua); 
     } 
     item.ua = '<span style="font-size:small">' + item.ua + '</span>';

However, one column, item.name, is not escaped. This is the email address sent in the Autodiscover request.

The most dangerous part? An Autodiscover request is unauthenticated by design, and in this case, the email address is not validated. It will end up in the logs, and once an admin views them, it will be passed through these vulnerable functions to be rendered as arbitrary HTML.

Below is an example request that to injects <img src=x onerror=alert(origin)> into the table:

POST /Autodiscover/Autodiscover.xml HTTP/2
Host: 127.0.0.1
Content-Type: text/xml
Content-Length: 384

<?xml version='1.0' encoding='utf-8'?>
<Autodiscover xmlns='http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006'>
  <Request>
    <EMailAddress>&lt;img src=x onerror=alert(origin)&gt;</EMailAddress>
    <AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema>
  </Request>
</Autodiscover>

When an administrator now views the Autodiscover logs (found at Dashboard -> Logs -> Autodiscover), the JavaScript executes and shows an alert pop-up, proving XSS in the Mailcow origin.

On the localhost copy of mailcow, there's a popup that reads "localhost says https://localhost

Since this hits only administrators, attackers can access any user's mailbox and reconfigure the instance. This gave the vulnerability a critical severity.

This issue was fixed by adding an escapeHtml() call around item.user while processing the rows.

Injecting quarantine attachment filenames (CVE-2026-40872)

Reported as GHSA-2xjc-rg88-jvpp, this vulnerability lives in Mailcow's Quarantine feature, where administrators can investigate flagged attachments. The filenames of those attachments were displayed without HTML escaping, opening the door to XSS on any admin who viewed them. Exploiting this required no authentication on the attacker's side, though it did require the Quarantine feature to be enabled on the target instance.

The sink is clear this time. Inside quarentine.js, there is a bit of code concatenating HTML with dynamic data:

$.each(data.attachments, function(index, value) { 
   qAtts.append( 
     '<p><a href="/inc/ajax/qitem_details.php?id=' + qitem + '&att=' + index + '" target="_blank">' + value[0] + '</a> (' + value[1] + ')' + 
     ' - <small><a href="' + value[3] + '" target="_blank">' + lang.check_hash + '</a></small></p>' 
   ); 
 });

If any of these are user-controlled, it could result in HTML injection again. These values are file name, mime type, file size and virustotal sha256, respectively. From these, the filename seems most likely to contain user input, since the attacker can send an email with an attachment that has a special filename consisting of HTML tags. 

When testing, it turns out that, as expected, no strict validation takes place on this filename. It can contain <> characters, which is all that's needed to inject an XSS payload. The remaining challenge is getting the email into the quarantine queue in the first place, so an admin will open and inspect it. The attacker solves this by attaching an EICAR antivirus test file, which is a standardized string that every antivirus engine is guaranteed to flag. This reliably routes the email to quarantine without requiring the attacker to send actual malware.

The code below generates an attachment with the EICAR string as content, and an XSS payload as the filename (see advisory for a full script):

# Malicious filename attachment with EICAR to trigger quarantine
att = MIMEApplication(b'X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*', _subtype='octet-stream')
att.add_header('Content-Disposition', 'attachment', filename='<img src=x onerror=alert(origin)>.exe')
msg.attach(att)

After sending the email to Mailcow and it getting quarantined, the admin can open the Quarantine page to see it. Once they click on Show item, our filename is rendered and the XSS triggers:

Note that this also does not require authentication on Mailcow to exploit. All that's needed is sending a maliciously crafted email to the Mailcow domain, and for the administrator to investigate it. From here, the whole instance could be taken over using JavaScript, reading mailboxes again, and configuring the instance.

This issue was fixed by adding escapeHtml() calls around the attachment values.

Elevating a Self-XSS in IP listed in Login History (CVE-2026-40875)

The last XSS vulnerability, reported as GHSA-jprq-w83q-q62h, was more technically interesting to exploit. The XSS payload is stored under the attacker's own account, meaning normally on its own, only the attacker would ever trigger it (a "Self-XSS" with no real impact). The attack becomes dangerous when combined with a Login CSRF, which forces a victim's browser to log into the attacker's account, putting the stored payload in front of the wrong person.

The vulnerability starts with another simple HTML concatenation sink at user.js:

var real_rip = item.real_rip.startsWith("Web") ? item.real_rip : '<a href="https://bgp.tools/prefix/' + item.real_rip + '" target="_blank">' + item.real_rip + "</a>";

The real_rip (Real Remote IP) is rendered in the table of recent logins without being escaped. Normally, this shouldn't be a problem; IP addresses follow a very strict format with no room for XSS payloads.

However, IP addresses aren't validated by Mailcow and come directly from the X-Real-IP: header by default. Some proxies set this header to the remote IP of the user, but if no such proxy exists, any value given to it will be trusted. Therefore, you can log in while setting X-Real-IP: "><img src onerror=alert(origin)> which saves the value to the recent login entries. When viewed (via /user), the XSS payload renders and executes the alert.

POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
X-Real-Ip: "><img src onerror=alert(origin)>

login_user=attacker&pass_user=attacker

This isn't the end of the story, though. Because a victim won't log in with this fake IP header, or log in to the attacker's account out of nowhere. For now, it is Self-XSS.

Two pieces of this vulnerability make escalation possible. First, the payload is stored persistently under the attacker's account. Second, the login request has no CSRF protection, meaning it can be triggered cross-site. An attacker can host a form on their own domain that automatically submits the attacker's credentials, logging the victim in without any interaction beyond visiting the page.

An attacker can host the following form on their malicious domain:

<form action="http://mailcow.local/" method="POST">
    <input type="text" name="login_user" value="attacker">
    <input type="text" name="pass_user" value="attacker">
</form>
<script>
    document.forms[0].submit();
</script>

Once a victim opens this hosted form on the malicious website, they are automatically logged into the attacker’s account. We can then redirect them to /user to trigger the XSS we stored earlier. But wait a second, the victim is now logged in to the attacker's account, so how can the attacker steal the victim’s data?

Here, the attacker can use a clever trick: keep the victim's mailbox open until after the Login CSRF & XSS, then read from it using same-origin access.

The new flow will look like this:

  1. Victim browses to our malicious page (tab 1)
  2. Tab 1 opens a second malicious page (tab 2) that contains the login CSRF form, with a slight delay before it runs
  3. Tab 1 redirects to the victim’s mailbox, loading the data the attacker wants to steal
  4. Tab 2 submits the login CSRF form, opening a new tab 3 that logs the victim into the attacker's account
  5. Tab 2 redirects itself to /user, where the Stored XSS is triggered
  6. The XSS in tab 2 uses a reference to opener to read and exfiltrate document.body.innerHTML in tab 1, where the victim's mailbox is still open

Diagram shows three boxes representing browser tabs. 1. Mailbox 2. XSS 3. CSRF. The latter two belong to the attacker.

This makes it possible to read emails from the victim's account because they were fetched while still logged into their account!

See the advisory for full details on how the exploit flow works in practice. Multiple HTML files with precise control over the flow allow an attacker to steal emails in just two clicks (required for opening the two extra tabs).

This issue was fixed by adding escapeHtml() calls around the IP rendering.

Remediation

Update Mailcow to version 2026-03b or later, released March 31st 2026. All three XSS vulnerabilities are patched in this release. If you use Aikido, vulnerable Mailcow instances are automatically flagged in your surface monitoring feed as a critical finding.

Aikido dashboard showing a score of 95: Critical for Mailcow. It also contains a TL;DR and steps to fix it.

Not on Aikido yet? Create a free account to get started — no credit card required.

Conclusion

A pattern we've seen during these disclosures is that concatenating HTML strings remains a bad idea. Modern HTML templating engines have made great improvements in most applications, but older applications without safe frameworks don't have this luxury. Sometimes they revert to concatenating strings in JavaScript, which, as seen here, quickly leads to forgetting to escape user input.

Mailbox applications contain highly sensitive information, so they should be treated with a lot of care. Such applications should be audited rigorously, since the compromise of one can lead to password reset mechanisms, resulting in the compromise of many other connected accounts.

In Mailcow, we found three vulnerabilities, tracked under the following CVE identifiers:

  • CVE-2026-40872 (GHSA-f9xf-vc72-rcgm): Stored XSS via unescaped Autodiscover logs. CVSS v4.0: 8.9.
  • CVE-2026-40873 (GHSA-2xjc-rg88-jvpp): Stored XSS via unescaped quarantine attachment filenames. CVSS v4.0: 8.9.
  • CVE-2026-40875 (GHSA-jprq-w83q-q62h): Stored XSS via unescaped login history IP, escalated through Login CSRF. CVSS v4.0: 7.0.

All three are patched in Mailcow version 2026-03b.

Aikido Attack (AI pentesting) finds these kinds of vulnerabilities in applications, completely automated. If seeing these results has you wondering about XSS vulnerabilities in your own applications, sign up or get in touch!