HTML を解析できるからといって、HTML を安全に表示できるわけではありません
この記事では、BeautifulSoup がセキュリティ浄化器ではなくパーサーとしてのみ位置付けられていることを明確にし、ホワイトリスト戦略を通じてスクリプト イベントと危険な URL を削除する方法を示します。実行可能なメモリ クリーニングのチュートリアル コード、境界テスト ケース、手動レビューのトリガー基準を提供し、OmniDoc を文書翻訳ワークフローに統合して混合コンテンツ処理機能を評価する正しい方法を説明します。
BeautifulSoup は正常に解析しますが、HTML が安全であることを意味するものではありません。この記事では、外部 HTML を処理する必要がある開発者とドキュメント チーム向けに、パーサーとピュリファイアーを別々に検討する必要がある理由を説明し、一連のホワイトリスト クリーニングのアイデア、テスト ケース、および手動レビュー基準を示します。
この記事の例は合成サンプルであり、処理方法を説明するためにのみ使用されます。コードは隔離された環境でサンプル チェックされていますが、実際のすべてのファイルまたは製品で動作することが保証されているわけではありません。重要な文書を処理する前に、原本を保管し、文書内の境界と受理項目に従って 1 つずつ確認してください。
一文で結論: 分析後は個別にクリーニングを行う必要があります
<img src=x onerror=alert(1)> のような危険な属性は、BeautifulSoup による解析後の出力にそのまま残ります。クリーニングは、解析後に重ねられるビジネス ロジックの追加レイヤーである必要があります。
| あなたの状況 | 推奨される実践方法 | 理由 |
|---|---|---|
| HTML からデータを抽出または変更するだけ | BeautifulSoup を使用した解析とトラバース | BS4 はツリー構造を抽出および変更するように設計されています |
| 外部 HTML を内部システムに埋め込んだり、成果物を翻訳したりするには | 解析後にホワイトリスト クリーニング レイヤーを追加する | BS4 はタグと属性が安全かどうかを判断しません |
onclick、javascript:、または data: などのプロパティの検出 | 属性を削除するか、href を空白のままにしておきます | これらのプロパティには実行可能なコンテンツが含まれる場合があります |
| 生産準備完了 | 専用のサニタイズ ライブラリ (bleach など)を使用し、ホワイトリストを外部化する | サンプル コードでは、複数値の属性、大文字と小文字の正規化、エンティティのエンコードなどの詳細については説明していません。 |
| クリーニング結果が異常になったり、文字が急に小さくなったりします。 | 手動レビューに移動 | 自動化されたルールは現実世界の状況をすべてカバーできるわけではありません |
分析能力と安全責任の間の不一致
BeautifulSoup 公式文書は、ツリー構造のナビゲーション、検索、変更に重点を置いた「HTML および XML ファイルからデータを抽出するためのライブラリ」と定義しています。したがって、コンテンツの意味論的なセキュリティについては中立です。 <a href="javascript:void(0)">Click</a> が入力されると、BS4 は href 属性を持つ Tag オブジェクトを正しく構築しますが、プロトコルが許可されるかどうかは判断しません。
文書処理では、この中立性には長所と短所があります。利点は、さまざまな不規則な履歴マーカーを処理できることです。リスクとしては、開発者が「BS4 処理済み」=「サニタイズ済み」とみなした場合、未検証の HTML がプレビュー インターフェイスや翻訳成果物に直接組み込まれる可能性があることです。
実際のセキュリティ クリーニングには、明示的な ホワイトリスト戦略 が必要です。既知の安全なタグ名と属性名のみを保持し、属性値の形式を確認して、残りを削除します。これは BS4 の組み込み機能ではなく、ユーザーが自分でオーバーレイする必要があるロジックです。
合成例の境界入力
クリーニングの必要性を説明するために、典型的な攻撃ベクトルと正当なコンテンツをカバーする一連の合成サンプルを以下で使用します。これらの入力は境界条件のデモンストレーションのみを目的としており、実際のトラフィック統計ではなく、業界標準のしきい値を表すものでもありません。実際のドキュメントをテストするには、まずビジネス データの感度を解除して、個人情報と機密リンクを削除します。
正しく入力してください
<p>See <a href="https://example.com/doc">reference</a>.</p>
p と a はホワイトリストに登録されており、href は HTTPS プロトコルを使用するため、予期される出力では段落とリンクがそのまま残されるはずです。
境界入力 1: イベント ハンドラー
<div onclick="steal()">Safe text</div>
たとえテキストが無害であっても、onclickはイベントハンドラ属性に属し、完全に削除しなければならず、<div>Safe text</div>だけが残ります。 divがタグホワイトリストに含まれていない場合、タグ全体をプレーンテキストの内容に置き換えるべきです。
境界入力2:データ:プロトコル
<a href="data:text/html,<script>alert(1)</script>">Link</a>
data: URIは実行可能なコンテンツを搭載できます。 たとえタグ自体が有効であっても、hrefは空のままにするか削除すべきです。 クリーナーはプロトコルプレフィックスがhttpかどうかだけでなく、デコードされたコンテンツがネスト実行コンテキストを構成するかどうかも検証します。
これらの事例は、セキュリティの決定が解決後の属性レベルレビュー段階で行われることを示しています。 BS4は文字列をトラバース可能なオブジェクトに変換し、クリーニングロジックはどのオブジェクトを保持できるかを決定します。
ホワイトリストに基づくメモリクリーンアップ
以下のPythonの例は、このプロセスをメモリ上で完了する方法を示しています。 このコードはデモンストレーションの教育用であり、マルチバリュー属性、ケース正規化、エンティティエンコーディング、その他の詳細には触れていません。本番環境での直接使用は厳しく禁止されています。 beautifulsoup4によって異なるので、自分でインストールする必要があり、バージョンをロックすることが推奨されます。 このコードはネットワークリクエストを開始せず、ファイルシステムへの読み書きも行いません。 これらの主張は期待される挙動を表しているに過ぎず、実際の結果は環境や依存関係に依存します。
# 教学示例:演示BS4配合白名单清洗原理,非生产级实现
from bs4 import BeautifulSoup, Comment
import re
ALLOWED_TAGS = {'p', 'a', 'b', 'i', 'ul', 'li'}
ALLOWED_ATTRS = {'href'}
SAFE_URL_PATTERN = re.compile(r'^https?://', re.IGNORECASE)
def sanitize_html(raw: str) -> str:
soup = BeautifulSoup(raw, 'html.parser')
# 移除注释
for comment in soup.find_all(string=lambda t: isinstance(t, Comment)):
comment.extract()
# 遍历所有标签
for tag in soup.find_all(True):
if tag.name not in ALLOWED_TAGS:
tag.unwrap() # 保留子节点,移除标签本身
continue
# 清理属性
attrs_to_remove = [k for k in tag.attrs if k not in ALLOWED_ATTRS]
for attr in attrs_to_remove:
del tag[attr]
# 校验剩余安全属性值
if 'href' in tag.attrs:
href = tag['href']
if not isinstance(href, str) or not SAFE_URL_PATTERN.match(href.strip()):
del tag['href']
return str(soup)
# 合成测试用例(仅用于理解原理)
safe = '<p>Hello <a href="https://ok.com">link</a></p>'
unsafe_event = '<p onclick="x()">text</p>'
unsafe_uri = '<a href="javascript:alert(1)">bad</a>'
assert sanitize_html(safe) == '<p>Hello <a href="https://ok.com">link</a></p>'
assert 'onclick' not in sanitize_html(unsafe_event)
assert 'href' not in sanitize_html(unsafe_uri)
本番環境では、専用のクリーンアップライブラリ(例えばbleach)を使い、コード外にホワイトリスト設定を配置することを検討できます。 重要なのは、浄化の論理は「何が許されているか」を明示すべきであり、「禁止されているもの」を列挙しようとするのではなく、
手動審査の受理基準とトリガーポイント
コード内のアサートは、あらかじめ設定されたルールが実行されているかどうかを検証するのみであり、すべての現実世界の異常をカバーすることはできません。 以下の表は、実際の文書処理における一般的な状況と、自動処理と人間の介入の境界を示しています。
| 現象を観察してください | 自動処理決定 | 手動審査が必要かどうか | 注記 |
|---|---|---|---|
| タグ名はホワイトリストには含まれていませんが、重要なテキストが含まれています | アンラップはテキストを保持します | いいえ | 意味論が失われないようにする |
| hrefは相対経路またはMailtoです: | href属性を削除してください | はい | 有効なビジネスリンクで、手動確認が必要な場合もあります |
| プロパティ値はHTMLエンティティによってエンコードされたJSを含みます | ストリングマッチによるリジェクト | はい | 過失致死かどうかを確認する必要があります |
| 深すぎる層の入れ子は解像度のタイムアウトを引き起こします | クリップをカットするかスキップしてください | はい | DoS(DoS)は防げますが、コンテンツを失う可能性があります |
| クリーニング後にテキストの長さが>30%大幅に短縮されました | マークは怪しい | はい | 構造化された情報を過度に削ぎ落としてしまう可能性があります |
「コードデモ合格」は「エンドツーエンド効果が信頼できる」という意味ではありません。 表に「はい」と表示されたプロジェクトでは、自動化プロセスを一時停止し、手動レビューに引き継ぐべきです。 翻訳の納品シナリオでは、過度な整理が用語の引用区切りや無効な書式の原因となることがあります。
📊 コア比較
| 方法 | 何ができるのでしょうか? | 何にも代わってくれない |
|---|---|---|
| 美しいスープの解析 | HTMLをトラバース可能で修正可能な木構造に変える | セキュリティ判断、属性、プロトコルは現状維持されます |
| ホワイトリストクリーニングレイヤー | 許可されたラベルや属性を明示的に宣言し、残りは削除します | 手動確認、境界の状況はまだ確認が必要です |
専用の精製チャンバー(例:bleach) | 生産グレードの浄化を行い、外部構成をサポートします | ご自身のビジネスホワイトリストの分類と受け入れ |
🎯 どの方法があなたに合いますか?
データだけを抽出すればいいのに
BeautifulSoupを直接使い、消毒されたかのように出力を表示しないでください。
外部または歴史的遺産HTMLを表示したい場合は
まずホワイトリストのクリーニングレイヤーを設定し、その後、受け入れシートに従って各アイテムをテストします。
もしあなたが制作に入る準備をしているなら
bleachのような専門ライブラリの使用を検討し、ホワイトリストを外部で設定し、手動レビュートリガールールを保持することを検討してください。
もし文書の翻訳と配達をしたいなら
本文、リンク、コード、構造を別々に確認し、表に記載された項目については手動で確認を手配してください。
❓ よくある質問(FAQ)
1. BeautifulSoftで解析・再シリアライズした後、悪意のあるコードは消えますか?
いいえ。 論文の例は、解析とシリアライズ後も<img src=x onerror=alert(1)>が出力に完全に保持されていることを示しています。
2. ホワイトリスト外のタグや属性の扱い方は?
ホワイトリストにタグがなければ、そのテキストを保持するためにアンラップできます。 onclickのようなイベントプロセッサ属性は完全に削除すべきです。
3. サンプルコードは本番環境で直接利用できますか?
いや、できない。 例は教育用のデモンストレーション用であり、マルチバリュー属性、ケース正規化、エンティティエンコーディングなどの詳細には触れていません。 本番環境ではbleachを考慮でき、ホワイトリストは外部で設定可能です。
4. コードデモンストレーションが合格した場合、処理効果は信頼できるのでしょうか?
そういう解釈はできない。 フォームが授与され手動審査が必要な場合は、自動処理を停止し、手動審査を許可すべきです。
5. 実際のファイルで直接テストできますか?
まずはビジネスデータの感度を鈍感にし、個人情報や機密リンクを削除し、その後、受け入れ基準に従ってテストを行うことが推奨されます。
文書翻訳にはチェックリストを使う
ウェブページの本文、リンク、コード、構造は別々に扱うべきです。 受理チェックリストに保護されたセクションを含め、翻訳後の可読性やページ表示を評価する。
OmniDoc(製品エントリー)はマルチフォーマットの文書翻訳ポータルを提供しており、公式ウェブサイトではOCR、用語集、バイリンガルの参照機能を導入しています。 ファイルから直接読み始めたいチームにとっては、実際のサンプルを使って評価する価値のある道です。 アップロード許可を得た匿名ファイルを使用し、この記事のチェックリストで結果を検証してください。 これは、OmniDocがこの記事で言及されたオープンソースライブラリや内部アルゴリズムを使用していることを主張するものではなく、例が製品性能テストの代替でもあるわけではありません。
📝 概要
解析は「HTMLはどのような見た目か?」という回答のみを得ます。セキュリティはホワイトリスト登録と手動検証に依存します。 まず、ロックされた依存環境で例を実行し、受け入れシートに従って脱感作されたサンプルで各項目をテストし、最後に正式なプロセスに統合するかどうかを決定します。


