我在我的博客里添加了实时聊天功能,结果人们用它来攻击我。
I added a real-time chat to my blog, people used it to attack me

原始链接: https://en.andros.dev/blog/b6c32a90/i-added-a-real-time-chat-to-my-blog-people-used-it-to-attack-me/

在为自己的博客添加了一个旨在让读者互致问候的简易实时社交小组件后,作者遭遇了一波大规模且协同一致的恶意攻击。起因是他发布了一篇关于 Tailwind CSS 的争议性文章,攻击者利用该组件向网站大量发送仇恨言论、垃圾信息、冒充信息以及各种干扰内容,试图对他进行诋毁。 尽管攻击十分激烈,但作者在架构上的选择——特别是服务端 HTML 转义——保护了读者免受恶意代码注入的影响。为了缓解骚扰,他实施了严格的自动关键词过滤,缩减了字符限制,并采取了“不理会喷子”的策略。 这次经历凸显了一个残酷的现实:任何用户输入本质上都是具有敌意的。作者得出的结论是,由于缺乏审核窗口,实时审核比常规评论审核要困难得多。尽管如此,他仍致力于保留这一功能,并指出消息的即时销毁属性降低了恶意攻击者的动力,而对于大多数用户而言,该组件确实提供了一种奇妙的人际连接感。

一位开发者在个人博客中添加了实时匿名聊天功能,以展示其技术项目。结果是即时且可预见的:聊天室迅速被垃圾信息、机器人、仇恨言论及跨站脚本攻击(XSS)所淹没。 Hacker News 的评论者们对此大多并不感到惊讶,他们引用了“大互联网混蛋理论”(Greater Internet Fuckwad Theory),并指出互联网上的一个长期现实:任何开放网络中未经审核的匿名用户输入框,最终都不可避免地会被滥用。许多人认为,开发者的惊讶反映出其缺乏网络管理经验,因为此类行为自 20 世纪 90 年代以来就是互联网的常态。 尽管开发者尝试实施基础的过滤和字符限制,但用户指出这些措施极易被绕过。社区达成的共识是:如果没有强有力的审核、身份验证或“增加成本”的机制(如速率限制或声誉系统),此类功能除了引来喷子外毫无用处。一些人建议作者放弃该项目、实施影子封禁或转向经过管理的平台,而另一些人则指出,这些“攻击”只是人性在互联网上的一种不可避免、尽管令人不快的表现。
相关文章

原文

Sometimes the most irrelevant piece of a project becomes its absolute protagonist.

My blog has a small social widget floating on one side. You can see it on the right on desktop, on the left on mobile. It tells you how many people are reading the site in real time, and it lets you drop a short message for everyone else who is present to see. It is very basic. There is no history, and you do not need to create an account or a profile. A message appears and a few seconds later it is gone. It is an ornament, a wink, the kind of detail you add on a Friday afternoon and expect nothing from. To my surprise, it was used against me to discredit me and to censor an article.

Let me put you in context. I wrote an article on why I don't recommend Tailwind CSS and shared it on Hacker News. Within minutes, the text box filled with offensive and provocative messages, some even trying to impersonate me.

How it works

I barely had to do anything, and the dirty work was done by the site's architecture.

My site is an SPA that renders the HTML on the server and sends it to the browser over WebSockets (I use Django LiveView, my own framework). When you work this way, knowing how many people are connected in real time comes for free. Each visitor keeps an open connection, so I just have a table with the live connections. When someone joins or leaves, I broadcast the new number to everyone present and the counter updates on its own.

From there, adding an input and relaying what someone writes to everyone else is a small step. The same channel I already use for the counter serves me for the message.

I gave it the classic limits, nothing overly sophisticated:

  • A maximum number of characters per message.
  • The text disappears from the screen after a few seconds.
  • You cannot send messages back to back: there is a minimum interval between one and the next.

In principle it seems pretty solid. What harm could a box that only broadcasts plain, ephemeral text do to me? You're thinking the same thing I was, I'm not crazy, right?

The attacks

It turns out that a public text box connected to every reader at once is an irresistible toy that sparks creativity:

  • Insults and hate speech. Racism and assorted provocations. The goal, I suppose, was twofold: to make whoever was reading uncomfortable and to make the article look bad in front of the aggregators and networks where it was being shared.
  • Targeted provocations. A certain president was mentioned quite a bit, with death threats. I suppose it was aimed at a specific social network or community.
  • Covering the content. Very long messages with repeated characters, # and @ in a row, to push the text down and clutter the screen. On mobile it was surprisingly effective.
  • Impersonating me. They started writing messages pretending to be me, inviting people to visit certain links or dropping spam. There is always someone who wants to profit from the noise.
  • Injecting code. Many tried to sneak in JavaScript so it would run in everyone else's browser. They never managed it, but the attempt is interesting. Since the server renders and escapes the HTML before broadcasting it, a <script> travels as inert text and reaches your neighbor's screen as what it is, a few letters, not as code. The same architecture that makes the chat trivial is what makes it immune to this.
  • Discrediting me head-on. And the simplest one: messages of contempt toward me or the blog, just to see if it stuck.

I must have annoyed a lot of people at once, because the wave lasted a whole day. Continuous attacks. Perhaps carried out by AIs or bots, I don't know.

Such was the scale that I started getting warnings in private. Something unheard of!

The countermeasures

The first and most obvious one was a filter of inappropriate words and expressions. I won't explain which ones or how it works inside, for obvious reasons, but it is quite effective. The machinery is in the heuristics.

The second, and most natural, was to cut the maximum number of characters way down. Less room is less ammunition to cover content and less space to hide a link.

The rest is the hardest countermeasure of all: patience and not taking the bait. A troll is after a reaction. If the system absorbs the blow in silence and you don't respond, the game stops being fun for the attacker. Don't feed the trolls.

What I learned

The easy conclusion would be "there are a lot of people with too much free time." And it's true. But there are a couple of less obvious things I take away.

Every input is hostile until proven otherwise. It's a mantra we developers repeat, and one you internalize all at once the day you live through something like this.

Real-time moderation is a different problem. Moderating comments is comfortable: they arrive, they wait, you review them, you decide. An ephemeral message that is broadcast instantly gives you no such margin. Either you trust an automatic filter that acts in milliseconds, or you are too late. The asymmetry is brutal, since an attacker improvises in seconds, but the countermeasure takes hours or days.

Ephemerality plays in your favor. The fact that the message disappears on its own, that there is no history, that no profiles or karma are left to farm, takes away almost all the incentive for a troll.

To wrap up the story, I just want to say that I don't regret having it. The vast majority use it to say hi, and seeing ten strangers coincide on the same page at once still has something magical about it.

Do you have company? Take the chance to say hello, or even start a friendship. You never know who is on the other side of the screen.

联系我们 contact @ memedata.com