Web開発
ブログにリアルタイムチャットを追加したら、攻撃に使われた
I added a real-time chat to my blog, people used it to attack me (en.andros.dev)
要約
著者がブログにリアルタイムチャット機能を実装したところ、悪意のあるユーザーによって攻撃や中傷、コード注入の試みに利用された体験談。この機能はDjango LiveViewで構築され、リアルタイムでの接続者数表示とメッセージ交換を可能にしていたが、攻撃者はこれを悪用してサイトの評判を落とそうとした。著者は単語フィルターや文字数制限、そして何よりも「反応しない」という対策で対応し、リアルタイムモデレーションの難しさとエフェメラル(一時的)なメッセージの利点を学んだ。
全文翻訳
プロジェクトの最も無関係に見える部分が、その絶対的な主役になることがあります。
私のブログには、片側に浮いている小さなソーシャルウィジェットがあります。デスクトップでは右側、モバイルでは左側に表示されます。
これは、サイトをリアルタイムで読んでいる人数を表示し、そこにいる他の全員が見ることができる短いメッセージを投稿できるようにするものです。
非常に基本的な機能です。履歴はなく、アカウントやプロフィールを作成する必要もありません。
メッセージが表示され、数秒後に消えます。
それは装飾であり、ウィンクであり、金曜日の午後に何も期待せずに加えるような詳細です。
驚いたことに、それは私を信用させないため、そして私が共有した記事を検閲するために使われました。
状況を説明しましょう。
私は、なぜTailwind CSSを推奨しないのかについて記事を書き、それをHacker Newsで共有しました。
数分以内に、テキストボックスは攻撃的で挑発的なメッセージでいっぱいになり、中には私になりすまそうとするものもありました。
仕組み
私はほとんど何もする必要がありませんでした。汚い仕事はサイトのアーキテクチャによって行われました。
私のサイトは、サーバー上でHTMLをレンダリングし、WebSocket経由でブラウザに送信するSPAです(私はDjango LiveView、私自身のフレームワークを使用しています)。
このように作業すると、リアルタイムで接続している人数を知ることは無料で手に入ります。
各訪問者は接続を維持するため、ライブ接続のテーブルがあるだけです。
誰かが参加または離脱すると、その新しい番号をそこにいる全員にブロードキャストし、カウンターは自動的に更新されます。
そこから、入力フィールドを追加して、誰かが書いたものを全員に中継することは小さな一歩です。
カウンターに使用したのと同じチャネルが、メッセージにも役立ちます。
私は古典的な制限を設けました。それほど洗練されたものではありません。
メッセージあたりの最大文字数。
テキストは数秒後に画面から消えます。
メッセージを連続して送信することはできません。1つと次のメッセージの間には最小間隔があります。
原則として、それはかなり堅牢に見えます。
プレーンな一時テキストのみをブロードキャストするボックスが、私にどのような害を及ぼす可能性があるでしょうか?
あなたは、私もそう思っていたことを考えているでしょう。私は狂っていませんよね?
攻撃
判明したのは、すべての読者に一度に接続された公開テキストボックスは、創造性を刺激する抵抗できないおもちゃであるということです。
侮辱とヘイトスピーチ。
人種差別と様々な挑発。
目標は、読んでいる人を不快にさせることと、アグリゲーターや共有されているネットワークの前で記事を悪く見せることの2つだったと思います。
標的を絞った挑発。
特定の社長が、死の脅迫とともにかなり言及されました。
特定のソーシャルネットワークやコミュニティを狙っていたのだと思います。
コンテンツを隠蔽する。
文字、#、@を連続して使用した非常に長いメッセージで、テキストを下に押し出し、画面を散らかす。
モバイルでは驚くほど効果的でした。
私になりすます。
彼らは私になりすましてメッセージを書き始め、人々を特定のリンクに誘導したり、スパムを落としたりしました。
常にノイズから利益を得たい人がいます。
コードの注入。
多くの人がJavaScriptを忍び込ませようとして、それが他の全員のブラウザで実行されるようにしました。
彼らは決して成功しませんでしたが、その試みは興味深いです。
サーバーがHTMLをレンダリングしてエスケープしてからブロードキャストするため、<script>は不活性なテキストとして移動し、隣人の画面には、コードではなく、文字の羅列として届きます。
チャットを簡単にするのと同じアーキテクチャが、それをこれに対して免疫にしています。
私を直接信用させない。
そして最も簡単なもの:私やブログに対する軽蔑のメッセージ。それが定着するかどうかを確認するためだけです。
一度に多くの人を怒らせたに違いありません。なぜなら、その波は一日中続いたからです。
継続的な攻撃。
おそらくAIやボットによって実行されたのでしょう。私にはわかりません。
その規模は、プライベートで警告を受け始めたほどでした。
前代未聞です!
対策
最初で最も明白なものは、不適切な単語や表現のフィルターでした。
理由により、どの単語や表現か、またはその仕組みについては説明しませんが、それは非常に効果的です。
機械はヒューリスティックにあります。
2番目に、最も自然なのは、文字数を大幅に減らすことでした。
スペースが少ないほど、コンテンツを隠すための弾薬が少なくなり、リンクを隠すためのスペースも少なくなります。
残りは、最も難しい対策です。忍耐と、餌に食いつかないこと。
トロールは反応を求めています。
システムが打撃を静かに吸収し、あなたが応答しない場合、攻撃者にとってゲームは楽しくなくなります。
トロールに餌を与えないでください。
私が学んだこと
簡単な結論は、「暇すぎる人がたくさんいる」でしょう。
そしてそれは真実です。
しかし、あまり明白ではないことが2つあります。
証明されるまで、すべての入力は敵対的です。
これは、私たち開発者が繰り返し言うマントラであり、このようなことを経験した日にすぐに内面化されるものです。
リアルタイムモデレーションは異なる問題です。
コメントのモデレーションは快適です。それらは到着し、待ち、レビューし、決定します。
即座にブロードキャストされる一時的なメッセージには、そのような余裕はありません。
ミリ秒単位で動作する自動フィルターを信頼するか、遅すぎます。
攻撃者は数秒で即興できますが、対策には数時間または数日が費やされるため、非対称性は壊滅的です。
エフェメラリティはあなたの味方です。
メッセージが自動的に消えること、履歴がないこと、プロフィールやカルマが残らないことは、トロールのインセンティブをほとんど奪います。
話を締めくくるために、私はそれを実装したことを後悔していないと言いたいだけです。
大多数の人は挨拶するためにそれを使用しており、一度に10人の見知らぬ人が同じページにいるのを見るのは、まだ魔法のようなものがあります。
誰か一緒にいますか?挨拶するチャンスを掴むか、友情を始めることさえできます。
画面の向こう側に誰がいるかは決してわかりません。
仕組み
攻撃
対策
私が学んだこと
この作品は、Attribution-NonCommercial-NoDerivatives 4.0 Internationalライセンスの下で提供されています。
私が決して公開しないものを読みたいですか?
記事に収まらないものを送信します。完全な設定、乱雑なメモ、そして私が現在テストしているもの。
スパムなし、セールスファネルなし。
件名をSUBSCRIBEとしてnewsletter@andros.devにメールを送信すると、登録できます。
メールで購読
購読解除するには、同じアドレスにUNSUBSCRIBEを送信してください。
コーヒーを一杯いかがですか?
広告やペイウォールなしで書き続ける方法です。
もちろん、私にお任せください!
コメント
コメントはまだありません。
他のサイトからの2件の言及
lemmy.bestiver.se 2026年8月6日
news.ycombinator.com 2026年8月6日
python django django channels websockets django liveview Django LiveView vs Phoenix LiveView: a real benchmark
python django django channels websockets django liveview Django LiveView vs Phoenix LiveView: a real benchmark
web python django htmx django channels django liveview htmxからDjango LiveViewへ