I reported a bug in CursorTouch's Windows-MCP, and the advisory is now published.
Ask its registry tool to delete one key, and it can delete a different one instead. There is no confirmation step, and the tool reports success either way.
In my test, I named a folder called Keys[Old]. The command deleted its neighbour, KeysO, and left Keys[Old] alone. I ran it on PowerShell 7.6.4, using folders as a stand-in for the registry, and the advisory says so.
The project already escapes input properly, so this isn't code injection. PowerShell reads the brackets as a pattern instead of part of the name. The fix is a one-word swap in four functions: -LiteralPath instead of -Path.
Receipts over promises.
github.com/CursorTouch/Windo…
mcp-authscan 1.1.8 is on PyPI today, and every exit code it returns now means exactly one thing.
The NSA AI Security Center's guidance on MCP servers (U/OO/6030316-26) covers vulnerability scanning and monitoring. When a scanner runs in CI, the pipeline reads its exit code. If two different problems return the same number, nothing downstream can tell them apart.
So the contract is written down in EXIT_CODES.md, one code per condition:
0 clean
1 finding at or above --fail-on
2 arguments or setup error
3 target validation
4 scan error
5 zero testable probes, or NOT_OBSERVED present
6 egress refusal
A mistyped flag comes back as 2. A blocked host comes back as 6. Every report stamps the contract id, the condition that fired and the resulting code, and all three sit inside the report hash, so the number can't drift away from the report that produced it.
Today's run against my own decoy authorization server on 127.0.0.1:9100:
4 PASS
1 FAIL: token-cache-control, LOW, no Cache-Control on the token response
4 EXCLUDED, each naming the missing prerequisite
coverage 5 of 5 testable
exit 0
The footer says clean of the threshold it was measured against, not just "clean", because that line sits right under a LOW finding. Exit 0 here means nothing crossed --fail-on. It doesn't mean nothing was found.
A clean report means the properties I tested held on a running server. It has never meant the system is safe.
Day 13 of 30 Days of @boardyai.
Receipts over promises.
github.com/LHMisme420/mcp-au…
In May, the NSA's Artificial Intelligence Security Center put MCP servers on the list of systems that need assessing. The controls its guidance speaks to are access enforcement, vulnerability scanning and monitoring.
The most basic access enforcement question is whether the server asks who you are at all. As of today, if the answer is no, mcp-authscan reports it as CRITICAL and exits 1, so a CI pipeline stops on it.
I ran it against my own FastMCP 4.1.4 server on 127.0.0.1:8000, with one tool and no authentication:
[CRITICAL] ZERO-AUTH Unauthenticated MCP endpoint
POST /initialize responded with HTTP 200 without authentication
exit=1
That means any client could call its tools, resources and prompts. The report's remediation is to turn on OAuth 2.1 with a registered client and answer unauthenticated /initialize requests with a 401.
Zero-auth is a known category, and this was my own server, so the run shows the check working end to end.
A finding on someone else's endpoint takes written authorization and a redacted report they're happy to publish.
The NSA guidance is U/OO/6030316-26. It also lists four MCP scanning tools: MCP Scanner, Ramparts, CyberMCP and Proximity.
Day 12 of 30 Days of @boardyai.
Receipts over promises.
github.com/LHMisme420/mcp-au…
Three MCP security scanners, one auth-gated server, one morning.
Ramparts (highflame-ai): spotted the Bearer requirement straight away and gave me the metadata URL. With a hand-minted token it ran clean, 0 tools, 0 findings, YARA rules off.
Nova Proximity (Thomas Roccia): reported no endpoints and "scan completed successfully", exit 0. With a token it hit an error, logged it in its own report, and still exited 0.
mcp-authscan: 9 probes, 6 pass, 1 fail, 2 excluded, and an exit code that means something.
None of that says the other two are bad tools. They answer a different question: what a server exposes, not whether anyone got in. But a scanner that exits 0 when it couldn't reach the server is a green light on nothing, and that's the part of MCP tooling I think is worth fixing.
I pointed Cisco AI Defense's mcp-scanner at one of my own test servers tonight. It came back with "Server returned an error response."
That's the right answer.
The server is built to refuse me. It answers with a 401, tells me where its authentication details live, and never publishes a tools list. Cisco's scanner works by reading tool descriptions and looking for bad patterns in them. With no tools published, it had nothing to read. It didn't call the server clean, and it didn't claim it found nothing. I ran it locally, with no API key and no LLM.
My scanner starts where that one stops. For me, the refusal is the thing under test. Does the endpoint really require authentication? Does it tell a client how to authenticate? Does its metadata match the endpoint it describes? A server that never lets me in isn't a dead end. It's the subject.
The two tools answer different questions, and they don't replace each other. One asks what a server does with the tools it advertises. The other asks whether the server enforces anything at all. Anyone deciding whether to ship an MCP server into a deal needs the second answer, and most have only been offered the first.
Day 11 of 30 Days of @boardyai.
Receipts over promises.
github.com/LHMisme420/mcp-au…
If you run an MCP server, here's everything I need from you before I scan it. Four things, in writing.
Day 10 of 30 Days of @boardyai.
1. Written authorization naming the host of an endpoint you control.
2. The endpoint URLs in scope, and the ones that aren't.
3. Whether you can issue a registered OAuth client. Without one, two of the nine OAuth checks can't run: PKCE with S256 and exact redirect_uri matching. The report marks those two EXCLUDED and names what was missing. They never get scored as passes.
4. Permission to publish a redacted result, or at least to say publicly that the scan happened.
What you get back:
- findings by severity
- the checks that came back clean
- any checks I couldn't run, and why
- a written list of what I didn't test, including source code, dependency CVEs and MCP resource endpoint behaviour
Tokens, cookies, API keys and email addresses are redacted. Raw headers stay in the JSON so anyone can check a finding.
Heath Weaver gave me exactly this for twigl.it on October 20. His report is public.
A one-line reply naming your host is enough for me to start.
Receipts over promises.
github.com/LHMisme420/mcp-au…
My scanner was telling me servers were fine when they hadn't answered at all.
I found a probe that returned PASS for endpoints that didn't respond to CORS headers. That's worse than a FAIL. A clean report with no findings would ship to a customer as reassurance that's not there.
The bug: absent CORS headers returned the same verdict as properly restricted headers. Both looked like compliance. Neither was.
The fix: test-first. I wrote the failing case (501 with no ACAO, 200 with no ACAO) before touching the probe. Ran it. Watched it fail. Then applied four-branch verdict logic to distinguish "we have no CORS headers" from "we have restrictive headers."
Running the test again under the fixed logic showed the fixture verdicts flipped. Proof that it worked.
The broader story: MCP server security assessment tool. Resource probes, OAuth probes, a NIST alignment framework; all built on receipts, not promises. This false PASS was the last place the resource probes contradicted themselves.
The tool is stricter now. The report under the new logic shows the same findings (6 PASS / 1 FAIL / 2 EXCLUDED on the twigl.it scan). That's confidence: the findings are robust to the detection change.
Open source: github.com/LHMisme420/mcp-au…
#SecurityResearch #MCP #OAuth #NIST #GovernmentSecurity #ReceiptsOverPromises
Three MCP implementations patched the same auth hole, and all three advisories say the same thing: upgrading alone doesn't close it.
The finding, in one line: a client fetches the authorization server's metadata and never checks that the issuer in the document matches where it came from. What follows is where the check still fails after the fix, and what to do about it.
The advisories:
- Python MCP SDK: github.com/modelcontextproto…
- TypeScript MCP SDK: github.com/advisories/GHSA-6…
- FastMCP, the one I reported: github.com/PrefectHQ/fastmcp…
Four places the check still fails
One. The parameter was missing. That's the original bug.
Two. The parameter is optional. Every fix keeps "no issuer" working for compatibility, so a default install stays unbound. On the Python SDK the warning is a plain DeprecationWarning, which Python hides by default.
Three. Credentials already at rest. Anything stored before the upgrade has no issuer recorded against it. The TypeScript advisory says tokens and client info saved earlier still go to whichever authorization server was named at first use. FastMCP discards refresh credentials from reloaded tokens for the same reason.
Four. Gaps the fixes name themselves. A fresh interactive sign-in still goes to the authorization server the MCP server names, so only complete sign-ins for servers you trust. Calling refreshAuthorization or exchangeAuthorization directly is still exposed. In the Python SDK, the no-metadata fallback and the 403 insufficient_scope step-up are still open in 2.x.
Absence is the exploit path
The Python SDK advisory is blunt about this. The attacker wins either by naming its own authorization server in the resource metadata, or by publishing none and serving metadata that presents the real authorization server as the issuer.
The second path is the one to watch. The client doesn't have to accept a wrong issuer. It just has to find nothing to compare and keep going. A comparison only fires when there's a value to compare.
What to do
- Upgrade: Python SDK 1.30.0 or 2.2.0, TypeScript SDK 1.31.0 or client 2.2.0, FastMCP 4.1.2.
- Set the issuer explicitly. Upgrading alone is not enough.
- Clear stored OAuth credentials so they get re-bound, or add the issuer to the record.
- If a client may have connected to an untrusted MCP server, rotate the client secret or signing key and revoke the tokens.
Where my tool stops
I test running MCP servers, not clients. This flaw lives on the client side, so scanning your server won't find it. What mcp-authscan can show you is whether your authorization server publishes an issuer and whether your resource metadata matches your endpoint. That removes one leg of the attack. The vulnerability stays where it was.
A clean report means the properties I tested held on a running server. It has never meant the system is safe.
Receipts over promises.
github.com/LHMisme420/mcp-au…
Leroy H. Mason (Elior Malak) retweeted
a Dirty Dozen is filling up with researchers, red teamers, and trainers.
But we need more.
Call for (more) trainers.
Who we're after:
→ Red teamers: jailbreaks, prompt injection, getting models to misbehave.
→ Blue teamers: guardrails, detection, hardening.
→ Evals & alignment people: how you actually measure what a model does.
→ Real-world systems people: where AI meets hardware, firmware, field crews and a regulator on a bad day. The stuff no jailbreak tutorial covers.
Format's up to you: a one-off session, a study group, a short lecture series, office hours. You set the depth and the pace.
No teaching pedigree required: same rule as everything here.
If you can do it and explain it, you can teach it.
Straight about the deal: this is volunteer right now, we're a community before we're anything else, and what you get is:
You shape people the field keeps shutting out, your name sits on the work, the community vouches for it, and when the guild starts negotiating paid work, the people who built the place are first in line.
If you've got something worth passing on, I want to hear from you. Thank you!
DM me, or link in bio.🤘
#AISafety #AIRedTeaming #AISecurity #Alignment #Evals #aDirtyDozen #Cybersecurity
Leroy H. Mason (Elior Malak) retweeted
The door’s shut and you don’t have the key. That’s how it goes for a lot of good people in AI security: wrong background, no pedigree, no way in.
A Dirty Dozen is the other way in: you get in on the work, not the CV.
Come the back way. 🤘
Discord in the first comment.
#AISafety #AISecurity #AIResearch #Cybersecurity #Alignment #ADirtyDozen
Best advice today: ask AI engineers what's breaking before building anything else.
Day 8 of 30 Days of @boardyai.
It came from Shoumik Chandra, a security researcher @boardyai set me up with. He's offered to review mcp-authscan.
Receipts over promises.
github.com/LHMisme420/mcp-au…
When you feel under, stand. When you stand is the moment that understanding is within the realm of possibilities.
Understanding does not arrive while we are under emotionally or in our feelings. The moment we stand, the same weight that held us under can be seen, measured, carried differently or set down as the upright position allowed us to overcome.
🤖 Made with AI
Three separate MCP implementations shipped the same auth hole, and it's still turning up.
Day 7 of 30 Days of @boardyai.
Over the last few weeks I kept finding one pattern in different MCP clients. The client fetches the authorization server's metadata from one URL and never checks that the issuer the document declares is the one it actually fetched. So a client secret, or a refresh token reloaded from an unverified token, can get sent to an auth server an attacker advertises.
The one I reported in fastmcp was published as GHSA-vqqp-x5qm-5qp4, Moderate, fixed in 4.1.2. The advisory itself says it's the same vulnerability class as GHSA-qx49-fqc8-xw99 in the Python MCP SDK and GHSA-6qxp-vccf-f47h in the TypeScript MCP SDK. I sent a third report to a different agent SDK vendor, and they acknowledged it.
A lot of attention goes to exotic AI-native attacks. This one is the same tired auth mistake web apps have been making for twenty years, showing up again in a new protocol.
If you're on fastmcp, upgrading alone doesn't close it. 4.1.2 adds an issuer parameter, but leaving it out is still supported for compatibility, so a default install is still unbound. You have to set it. Anything already sent to an untrusted endpoint should be rotated.
The check for any MCP client: does it verify that the authorization server's declared issuer matches the URL it fetched the metadata from? If it accepts a document with no issuer at all, it isn't bound to anything.
That's why I look at what the running client does, not what version it says it is.
Still zero outside users. Nov 18 is the deadline.
Receipts over promises.
github.com/LHMisme420/mcp-au…
Let’s change the game!
We help you get your bone. 🦴
That's what The Dirty Dozen is about.
Not pedigree, nor credentials. Not who let you in.
Just people giving each other the lift needed to reach something they couldn't quite get to alone.
Researchers. Red teamers. Builders. Breakers. Self-taught misfits. Seasoned pros.
We learn together, share our work, and help each other level up.
Come get your bone.
🤘










