「/etc/hosts」ファイルの記述が原因で Substack エディタにエラーが発生
(scalewithlee.substack.com)- Substack エディタで特定のシステムパスを入力すると ネットワークエラー が発生
- Webアプリケーションファイアウォール(WAF) がこうしたパスをブロックするのは、パストラバーサル攻撃 や コマンドインジェクション攻撃 を防ぐため
- セキュリティ と ユーザビリティ のバランスが重要な問題として浮上
- 技術ライター のための、より良い解決策が必要
- 代替パス を使うことで問題を回避できる
/etc/h*sts が Substack エディタを妨げるとき: Webコンテンツフィルタリングの冒険
謎のネットワークエラー
- DNS解決に関する技術記事を執筆中に 予期しないエラー が発生
/etc/h*stsパスを入力すると ネットワークエラー が発生し、自動保存に失敗- Substack のステータスページでは 正常稼働中 と表示
調査開始
- 特定のファイルパスを入力したときに エラー が発生し、パスを変形すると 正常動作
/etc/h*stsのようなパスではエラーが起きる一方、変形したパスでは問題なし
内部で何が起きているのか?
- ブラウザの開発者ツールで 403 Forbidden レスポンスを確認
- Cloudflare が関与
Webアプリケーションセキュリティフィルタを理解する
WAF の簡単な説明
- Webアプリケーションファイアウォール(WAF) は Webサイトの 警備員 のような役割
- 疑わしいリクエストを ブロック する
パストラバーサル攻撃: なぜ警戒されるのか
- パストラバーサル攻撃 は機密性の高いシステムファイルにアクセスしようとする試み
/etc/h*stsのようなパスは 攻撃対象 になりうる
コマンドインジェクション: もう1つのセキュリティ問題
- コマンドインジェクション攻撃 はシステムコマンドの実行を誘発する
- システムパスへの言及があると、フィルタが ブロック する可能性がある
謎は深まる: 歴史的な例
- 他の Substack 投稿で類似のパス使用例を発見
- フィルタリングの挙動がある時点で 変更 された可能性
セキュリティ対ユーザビリティ: 繊細なバランス
- Substack のフィルタは 保護 のためのものだが、技術ライター にとっては 障害 になる
- 改善の余地 がある: 明確なエラーメッセージ、技術的内容の認識、文書化された回避策の提供
HTTPレスポンスを見てみる
- APIレベルで 403 Forbidden ステータスコードを確認
技術コンテンツプラットフォームのための、より良い解決策
- コンテキストに応じたフィルタリング: コードブロックや技術的な議論の中でシステムパスを認識する
- 明確なエラーメッセージ: 「ネットワークエラー」ではなく、セキュリティフィルタによるブロックであることを説明する
- 文書化された回避策: 機微なパスをどう議論するかの方法を提供する
結論: セキュリティと技術ライティングの交差点
-
Substack エディタの問題は、セキュリティ と 技術ライティング における複雑な課題を浮き彫りにしている
-
セキュリティフィルタによって攻撃パターンに見えるものが、実際には 正当なコンテンツ である場合もある
-
代替パス を使うことで問題を解決可能
-
類似のフィルタリング問題を他のプラットフォームで経験したことがあるか、コメントで共有してほしい
1件のコメント
Hacker News の意見
CDN で WAF ルールを設定する人たちは、技術コンテンツを扱うサイトやサービスを十分に理解していないことが多い。これは Cloudflare だけの問題ではなく、Akamai も似たようなもの
データベースについて議論するサイトで基本的な SQL インジェクション防止ルールを有効にするとサイトが壊れ、ファイルインクルードのルールセットは
/etc/hosts、/etc/passwdのような文字列をブロックするセキュリティと使いやすさのバランスという側面もある。どのサービスが脆弱に実装されているかは分からないので、すべての WAF ルールを載せればより安全になる面はある。ただし、安全に実装されたサービスが技術的な概念について議論する必要がある場合、同じルールセットが非常に厄介になる
ルールを細かく調整するにはかなり時間がかかる。クエリパラメータに
/etc/hostsがあるせいでページが表示されないのを直すと、今度はリファラに/etc/hostsが入っていて XHR リソースが表示されず、その次は分析用 JS ライブラリが訪問 URL を Cookie に入れてまた壊れる、という具合で、結局ルールをオフにしたくなる保険会社が「従業員のパスワードを 90 日ごとに変更させなければ保険料を 20% 引き上げる」と言えば、NIST が 10 年以上前に定期的なパスワード変更を推奨しないよう変更しており、それが悪い慣行だといくら正論を言っても保険料は上がる
だからため息をつきながらパスワード有効期限ポリシーを実装し、自分たちを無能だと不満を言う従業員の声を聞くことになる。log4shell があれほど有名になったのだから、今後は保険会社が
/etc/hosts、/etc/passwd、jndi:のようなよくある「ハッキング文字列」をサーバーが拒否するよう求めても驚かないCIO に、これが実際にどんな脅威を防ぐのか尋ねると、ぼんやりした表情が返ってくるだけ
エンジニアの立場では、各入力フォームがどこへ行くのかを理解し、意味のある方法でサニタイズすることに労力を割くインセンティブがない。報酬を得る仕事はチェックボックスを埋めて次へ進むことで、新人もすぐそれを学ぶ。こうした組織はセキュリティを改善するのではなく、侵害事故が起きた後に責任を回避することに集中している
サーバーとの間、あるいはサーバー間でやり取りされる「別のもの」にフィルターを適用するのは筋が通るかもしれないが、ブログコンテンツとして表示される実際の本文テキストをフィルタリングして得られるセキュリティ上の利点はなさそう。かなり明確なバグに近いと思う
https://en.wikipedia.org/wiki/Scunthorpe_problem
バックエンドは入力フィールドの任意のバイト列を処理できるべきで、CDN 層の事前フィルタリングがないからといって SQL インジェクションに脆弱であってはならない
"/etc/hosts"がそのまま入っているだけで発火する WAF なら、かなり明白に壊れているように思うある E コマースプラットフォームの逸話を思い出した。誰かがメモリリークのあるウェブショップを作り、回避策としてログに
"OutOfMemoryException"という文字列が現れたらアプリを再起動するようにしていたすると別の開発者が顧客の検索語をログに残したがり、誰かが検索窓に
"OutOfMemoryException"と入力すると……"system(...)"という文字列を含むメモを残したところ、WAF が PHP インジェクションと判断して IP ブロックをかけた/etc//hostsや/etc/./hostsもブロックするのか気になる。こういうモグラたたきは失敗するに決まっているこういうものを作る人たちは、攻撃者が自分たちより賢く粘り強いことを理解し、検証済みのセキュリティ手法、たとえば信頼できない入力を実行しないことだけに依存すべきだ
以前、SQL データベースを使っていないアプリケーションに対して、SQL インジェクション攻撃を防ぐために WAF が必要だと言われたこともある
反論すると、いつも「多層防御」の講義を聞かされる。毎週木曜の朝に机を一度叩いてその場で 3 回回るほうが効果的だと言うと、本当に頭のおかしい人を見るような目で見られる。毎週そうしてきたし、ハッキングされたこともないのだから、多層防御ではないか。害はないだろう
ワイルドカードの解釈はもっと厄介だが、禁止ファイルのリストがあれば十分可能だ
https://nodejs.org/api/path.html#pathresolvepaths
追記: C の
realpathは挙動が少し違うのでリンクを変えた技術ライターのためにSubstackはこの状況をどう改善できるのかって?
どんなトピックでも、たとえ愚かなWAFをトリガーする文字列であっても扱える記事編集エンドポイントに、石ころ並みに愚かなWebアプリケーションファイアウォールを付けなければいい
Web開発フォーラムがXSSフィルターを付けて、会員がXSSについて話せないようにするのと同じ。コンテンツを適切にエスケープする方法を学ぶべき
これらは愚かで、OWASPの
corerulesetという読みづらいゴミの山を使うだけこの事例がWebセキュリティにおける保護と使いやすさの間の興味深い緊張関係を示している、という意見には同意しにくい。これは単なるバグで、しかも愚かなバグだ。もっと分かっているべき人たちが分かっていないことを示しているだけ
セキュリティと使いやすさの間の緊張関係は実際にあるが、これはそれではない。普通は、優れたセキュリティを実装してユーザーに不便を強いるようなトレードオフのことを指す。二要素認証、3回失敗後のロック、DoS防止のためのレート制限のように、セキュリティを高めるとユーザー体験が悪くなり、ユーザー体験を高めるとセキュリティが下がる関係だ
これはどちらでもない。悪いセキュリティであり、悪いユーザー体験でもある。どこに緊張関係があるのか分からない
もちろんPHPサイトの作者たちはすぐにそれを見抜き、さまざまな回避手法が使われ、全体としてはそうした「浄化」がなかった場合よりも悪い結果を招いた可能性が高い
以前に一度やられたことがあったので、「ネットワークエラー」という言葉を見た瞬間に原因がすぐ浮かんだ
競技プログラミングチームを教えていたとき、クラスの生徒の半分が解答を提出すると空白ページを受け取り、1時間デバッグした末に、コードに現れると403を引き起こすいくつかのC++の型とキーワードに絞り込めたが、それらはすべてJavaScriptでも意味を持つものだった
銀行で働いていたときもPythonファイルを提出しなければならないAPIがあり、ほとんどのPythonファイルは403になり、短いファイルは通った。数時間デバッグした末に、コードに時々現れるキーワード1つに絞り込めた
数か月後、新しいクラウド環境でも同じことが起き、また数時間を費やした。2回目以降、同僚がデプロイスクリプトで403を受け取ったら
"HAHAHA YOU'VE BEEN WAFFED"を出力するようにしてくれて、予想よりずっと頻繁にそのエラーを見たので今でも感謝している私たちのアプリケーションでも似たようなことを経験した。社内のレッドチームがXSSや他のインジェクション攻撃の試行を含むデータを投稿していた
攻撃自体は成功しなかったが、その項目が存在するという理由で、会社のファイアウォールがそのペイロードを含むネットワークリクエストをブロックし、社内管理ページが読み込まれなくなった。結局、失敗したXSS攻撃が効果的なDoS攻撃になってしまった
古いものがまた新しくなったわけだ。昔はこういうものをScunthorpe問題と呼んでいた
https://en.m.wikipedia.org/wiki/Scunthorpe_problem
cockpitという単語がいつもc***pitに変わっていたのを覚えている。かなり笑えた生物学、金融、地質学について書いていたら? 単に運が悪いということだ
賢く善意のある人が作っても、愚かなフィルタリングは十分に有害だ
昨夜、OpenRouterでも似たような問題に遭遇した。OpenRouterは複数のLLMを1つのエンドポイントで使えるようにする「交換機」型のサービスなので素晴らしいのだが、昨夜、生のHTMLをさまざまな方法で処理するのにどのモデルがよいか試し始めた
ところがOpenRouter APIはCloudflareで保護されているため、POSTリクエスト本文に特定の生HTMLとJavaScript断片が入ると、すべてではないが多くのリクエストがブロックされた。同じプロンプトをOpenAIやAnthropicに直接送れば問題ない
無料モデルなら悪用防止を強めにかけるのは理解できるが、これは商用モデルとして課金されるリクエストなので、なおさら気に障る
以前この問題に遭遇し、ものすごく苛立った。
"Network error"のせいで、数か月かけて書いてきた記事を更新できず、編集で記事が長くなったせいだと思って原因を見つけられなかったサポートチームに連絡するのもAIチャットボットのせいで難しく、ようやく人間につながったときも、彼らの「技術サポート」は妥当な時間内に調べる気がなさそうだった
Twitterの誰かが、愚かなセキュリティロジックに触れる魔法の文字列の可能性を示唆してくれて、ようやく問題を見つけ、ついに記事を修正できた