我在我的博客里添加了实时聊天功能,结果人们用它来攻击我。
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 转义——保护了读者免受恶意代码注入的影响。为了缓解骚扰,他实施了严格的自动关键词过滤,缩减了字符限制,并采取了“不理会喷子”的策略。 这次经历凸显了一个残酷的现实:任何用户输入本质上都是具有敌意的。作者得出的结论是,由于缺乏审核窗口,实时审核比常规评论审核要困难得多。尽管如此,他仍致力于保留这一功能,并指出消息的即时销毁属性降低了恶意攻击者的动力,而对于大多数用户而言,该组件确实提供了一种奇妙的人际连接感。

一位博主最近在自己的网站上增加了一个实时聊天功能,却随即遭到访问者的骚扰和谩骂。随后在 Hacker News 上引发的讨论中,充斥着怀疑、实用的建议以及愤世嫉俗的幽默。 许多评论者指出,未经审核的匿名实时聊天天生容易受到滥用,一些人认为,所需的审核成本远超该功能带来的微薄价值。针对博主,人们提出的建议包括:启用强力的自动过滤机制、设置聊天冷却时间、对恶意用户进行“隐形封禁”(shadow-ban),或是将自由输入改为预设按钮以限制滥用。 另一些人则将这次尝试视为对互联网文化的一次严酷教训,并指出“所有输入默认为恶意”。虽然也有用户为这种试图在 Substack 等平台之外建立互动空间的做法进行辩护,但普遍的共识是:除非进行严格审核,否则该功能不可避免地会滋生毒性,最终迫使博主不得不在高压审查与彻底移除功能之间做出抉择。
相关文章

原文

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