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

推荐订阅源

Google DeepMind News
Google DeepMind News
Simon Willison's Weblog
Simon Willison's Weblog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Proofpoint News Feed
A
Arctic Wolf
T
Threat Research - Cisco Blogs
Apple Machine Learning Research
Apple Machine Learning Research
V
Visual Studio Blog
博客园 - Franky
Cyberwarzone
Cyberwarzone
宝玉的分享
宝玉的分享
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
Tailwind CSS Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Scott Helme
Scott Helme
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
Cisco Blogs
罗磊的独立博客
Stack Overflow Blog
Stack Overflow Blog
AWS News Blog
AWS News Blog
IT之家
IT之家
MongoDB | Blog
MongoDB | Blog
人人都是产品经理
人人都是产品经理
The Cloudflare Blog
Know Your Adversary
Know Your Adversary
腾讯CDC
Microsoft Security Blog
Microsoft Security Blog
博客园_首页
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Vercel News
Vercel News
Recorded Future
Recorded Future
Engineering at Meta
Engineering at Meta
D
Darknet – Hacking Tools, Hacker News & Cyber Security
博客园 - 司徒正美
C
Check Point Blog
T
The Exploit Database - CXSecurity.com
I
Intezer
P
Palo Alto Networks Blog
爱范儿
爱范儿
The Hacker News
The Hacker News
Microsoft Azure Blog
Microsoft Azure Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
S
Securelist
Security Latest
Security Latest
The GitHub Blog
The GitHub Blog
H
Help Net Security
B
Blog RSS Feed
量子位
Martin Fowler
Martin Fowler
I
InfoQ

Matthias Ott

Hello Again, World This, Still Not for Everyone The Shape of Friction WeissKlang L1 – Punching Above Its Weight Continvoucly Morged Value Webspace Invaders To Affinity and Beyond The Mystery of Storytelling Amateurs! Echoes of Connection Linear() Is Not (That) Linear View Transitions: The Smooth Parts Adding AVIF and WebP Support to My Craft CMS Site Challenge Acoustic Room Treatment and Building Sound Panels, Part 1: Planning Play On Overshoot The HTML Output Element Listening Closely Compressed Fluid Typography The Lifeblood of the Web What Could Go Wrong? That’s My Rank Making Space CSS :is() :where() the Magic Happens Visual Regression Testing for External URLs With Playwright Jane Goodall’s Famous Last Words European Tech Alternatives 🇪🇺 Independent Type Foundry Advent Calendar – Day 24: NaN Independent Type Foundry Advent Calendar – Day 23: Typotheque Independent Type Foundry Advent Calendar – Day 22: 205TF Independent Type Foundry Advent Calendar – Day 21: HvD Fonts Independent Type Foundry Advent Calendar – Day 20: Frere-Jones Type Independent Type Foundry Advent Calendar – Day 19: Fontwerk Independent Type Foundry Advent Calendar – Day 18: Vectro Independent Type Foundry Advent Calendar – Day 17: Studio René Bieder Independent Type Foundry Advent Calendar – Day 16: R-Typography Independent Type Foundry Advent Calendar – Day 15: David Jonathan Ross Independent Type Foundry Advent Calendar – Day 14: Interval Type Independent Type Foundry Advent Calendar – Day 13: Newglyph Independent Type Foundry Advent Calendar – Day 12: Swiss Typefaces Independent Type Foundry Advent Calendar – Day 11: Sharp Type Independent Type Foundry Advent Calendar – Day 10: Colophon Foundry Independent Type Foundry Advent Calendar – Day 9: Commercial Type Independent Type Foundry Advent Calendar – Day 8: Letters from Sweden Independent Type Foundry Advent Calendar – Day 7: Lineto Independent Type Foundry Advent Calendar – Day 6: Ohno Type Company Independent Type Foundry Advent Calendar – Day 5: Milieu Grotesque Independent Type Foundry Advent Calendar – Day 4: TypeMates Independent Type Foundry Advent Calendar – Day 3: Klim Type Foundry Independent Type Foundry Advent Calendar – Day 2: Dinamo Independent Type Foundry Advent Calendar – Day 1: Grilli Type The Independent Type Foundry Advent Calendar 2022 A Conversation With ChatGPT ChatGPT, please explain websites in the words of William Shakespeare Transient Frameworks Leaving Twitter Behind Converting Your Twitter Archive to Markdown The Wrong Question It Wasn’t Written Syndicating Posts from Your Personal Website to Twitter and Mastodon Suspension None of Your Business Doing Our Part Patch That Package Brain Dump Generating Accessibility Test Results for a Whole Website With Evaluatory The CSS Cascade, a Deep Dive Updates About Updates How to Delete Your Commit History in Git Unblocking Your Writing Blocks, Part 2: I’m Not an Expert nor a “Thought Leader” Connections No Wrong Notes Better Options Design Debt Finite and Infinite Games Don’t Assume, Validate. Necessity Is the Ultimate Teacher One Egg Go Deep There Is No Secret Code Balancing Risk Blue Eyes, Brown Eyes The Shortcut Boomerang My RSS Feed Collection of Personal Websites Frequency The Illusion of Control The Decisions Journey Write It Down Nownownow Into the Personal-Website-Verse Considering the Opposite What is it for? Unlimited Bowling. Never done. We Are Team Internet. We Need to Save #NetNeutrality. Progressive Search Data loss (also) by JavaScript Books I Will Definitely Maybe Read in 2017 Starting to Write Notes
Buckle Up
Matthias Ott · 2026-05-06 · via Matthias Ott

You might know that I – with the generous help from Brandon Kelly on the Craft 5 version – wrote and maintain a Webmention plugin for Craft CMS. Today, I shipped version 1.3.0. It’s a security and abuse hardening release, and if you’re running the plugin, you should upgrade.

The backstory of this one is, at least to me, kind of interesting.

Back in March, I added a new feature to the plugin: a Failed Webmentions view in the Craft control panel. The reason was simple. Building a Webmention endpoint that both sends and receives reliably is genuinely hard. There’s a lot of sifting through specs and documentation involved. You have to handle a wide range of markup flavours, work around different interpretations of microformats, and add fallbacks for all the times when somebody didn’t implement something the way you’d expect, the parser falls over, and you still want to recover gracefully. The whole thing is supposed to follow the robustness principle: be conservative in what you send, be liberal in what you accept. And to me, Webmentions have always felt a bit like a black box. Rough and uncharted territory.

As it turns out, adding the Failed Webmentions view was a pretty good idea.

Because what it revealed was this: unlike a few years ago, when nobody outside our little corner of the Web really knew about Webmentions, bad actors have caught up. They’ve started probing the endpoint.

I first noticed it on my way to IndieWebCamp Düsseldorf, the weekend before beyond tellerrand, while looking for something to work on at the Sunday coding session. I opened the Failed Webmentions view – and was flabbergasted. (What a great word, by the way. 😁)

Screenshot Webmention plugin failed webmentions view

Line after line of automated probing, with the fingerprints of tools like sqlmap all over it:

  • Time-based blind SQL injection in every flavour of database – MySQL sleep(15), PostgreSQL pg_sleep, Oracle DBMS_PIPE.RECEIVE_MESSAGE, MSSQL WAITFOR DELAY – stuffed into the source field, the target field, sometimes both at once.
  • Boolean payloads like -1' OR 5*5=25 -- and the more elaborate -1' OR 2+99-99-1=0+0+0+1.
  • Double-URL-encoded escape characters like %2527%2522\'\", fingerprinting how my input filter decodes things.
  • Classic XSS patterns: random tokens trailed by <'"> to see if anything would reflect back.

And the sheer volume of it! One short sentinel had been retried against a single note 693 times. Another, 451. Most of these were never going to work. Craft itself is a really secure CMS – Pixel & Tonic have put a lot of care into sensible defaults: parameterized queries, output escaping, CSRF protection, all the foundation work that means a stray apostrophe in an input field won’t take you anywhere interesting. But the plugin layer still is mine, and I’d rather not rely solely on the framework catching things downstream.

So I sat down and hardened the plugin. I completed a few small fixes at the IndieWebCamp and a few more over the last couple of days. URLs are now validated at both ends – when they’re stored and when they’re rendered – so anything that isn’t http:// or https:// is rejected outright, along with whitespace, embedded credentials, illegal hosts, and anything longer than 2048 characters. The public endpoint now has a per-IP rate limit, configurable with a sensible default, and a failure-backoff threshold so that the same broken or malicious source/target pair doesn’t get retried forever. Identical submissions arriving within a five-minute window are deduplicated at the controller of the plugin, so a flood can’t amplify outbound HTTP fetches. There’s also a new trustedSourceHosts setting that lets a host like brid.gy bypass the rate limit, so a viral wave of mentions through Bridgy doesn’t get dropped on a busy day. I might add a few more exceptions over time.

Again, if you are using the plugin in production, I recommend you update the plugin as soon as possible. Although I am not aware of any successful exploits, it will definitely harden your setup. And if you run into any issues, let me know or open an issue.

We are now living in wild times when it comes to infosec. Earlier this year, I wrote about how my site was being hammered into oblivion by LLM crawlers, to the point where I had to move to a VPS and harden the whole setup. Two weeks ago, Bastian shipped a security release for Kirby CMS that really challenged the small team. And every week there’s a new round of advisories, vulnerable dependencies, and reports landing in the inboxes of maintainers.

A lot of this has to do with LLMs getting more capable, month after month. The whole offensive playbook – recon, payload generation, evasion, writing custom tooling – is getting cheaper to run. The bad actors are using Opus 4.7, too.

So if you maintain a small plugin, an open endpoint, client websites, or your own little corner of the Web: time to buckle up and secure your stuff.

~

2 Webmentions

2 Likes

ⓘ Webmentions are a way to notify other websites when you link to them, and to receive notifications when others link to you. Learn more about Webmentions.