
Next.js Middleware Authentication Bypass (CVE-2025-29927)
Classic XML External Entity (XXE) injection
This combination ultimately allowed me to read system files and retrieve the flag from the server.
🔍 Recon – The Starting Point
We were given the URL:
Visiting the site showed a clean interface with a mysterious Admin section. Clicking it led to a login page that required a secret key. Instead of trying to brute-force the key, I opted for some recon.
⚙️ Wappalyzer to the Rescue
I used Wappalyzer to identify the technologies behind the app. It revealed that the application is built using Next.js.
Immediately, a recent CVE came to mind: CVE-2025–29927 – A vulnerability in Next.js middleware that allows bypassing authentication by injecting a special header:
X-Middleware-Subrequest: middleware
Bypassing Auth with Next.js Middleware Vulnerability
I opened Burp Suite, navigated to the https://hackdonalds.intigriti.io/admin
page, and captured the request using Burpsuite. As expected, the server redirected me to /login
due to the missing secret key
So I added the magic header: X-Middleware-Subrequest: middleware
Then forwarded the request.
🎉 Boom! I was in. The middleware treated the request as internal and let me bypass the authentication entirely.
🔁 Making Auth Persistent (No Intercepting Every Time)
While this worked, refreshing the page removed the header — and I got logged out again. To fix this: I went to Burp Suite → Proxy → Match and Replace
Left the Match field empty
Set Replace to: X-Middleware-Subrequest: middleware then saved the rule
Now every request included the bypass header automatically.
Exploring the Ice Cream Machine
Inside the admin panel, I found an endpoint called /ice-cream-machine
This page showed machine statuses (Online/Offline). Clicking on an online machine revealed a custom XML input form that let you query machine data.
Any time I see XML input as a security researcher, my radar pings 🔔 Intigriti Blog for XXE
XXE Attack: Reading /etc/passwd
My instinct told me this XML parser might be vulnerable to XXE. So I tested with a payload like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE machine [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<machine>
<id>1</id>
<name>&xxe;</name>
<temperature>-18</temperature>
<mixLevel>75</mixLevel>
<lastMaintenance>2025-03-15</lastMaintenance>
<cleaningSchedule>Daily</cleaningSchedule>
</machine>
🚨 It worked! The contents of /etc/passwd were returned in the response — confirming XXE vulnerability.
🏁 Final Step – Locating the Flag
While /etc/passwd
proved file read worked, the flag wasn’t there. So I thought if this is a MERN stack app, then core content is often stored under /app
, and most devs keep /app
as there main application directory and in MERN a single file that always exists package.json
file. so I decided to check the package.json
file content first.
I updated the payload to:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE machine [
<!ENTITY xxe SYSTEM "file:///app/package.json">
]>
<machine>
<id>1</id>
<name>&xxe;</name>
<temperature>-18</temperature>
<mixLevel>75</mixLevel>
<lastMaintenance>2025-03-15</lastMaintenance>
<cleaningSchedule>Daily</cleaningSchedule>
</machine>
📦 Boom again! The file was fetched and displayed the flag, completing the challenge.
🧠 What We Learned
Vulnerability Impact
- ✅ CVE-2025-29927 Bypassed middleware auth
- ✅ XXE Injection Local file disclosure
- ✅ Logical guesswork Found and read package.json
- 🔐 Just because modern frameworks are in use doesn’t mean old-school bugs like XXE can’t sneak in!
🚀 Thanks for Reading!
If you enjoyed this writeup, feel free to connect or leave a comment.
Happy hacking! 🐱💻🔓 ~ Vinit Prajapati**
Want to write a blog?
Unfold your thoughts and let your ideas take flight in the limitless realm of cyberspace. Whether you're a seasoned writer or just starting, our platform offers you the space to share your voice, connect with a creative community and explore new perspectives. Join us and make your mark!