この記事は、Huawei クラウド コミュニティ「[セキュリティの攻撃と防御] 実践的なトピックを簡単に説明 - 特殊文字の検証」から共有されたものです。」、著者:MDKing。
特殊文字検証の背景
- SQL インジェクションや XSS などの一般的なセキュリティ攻撃シナリオでは、いくつかの特殊文字が使用されます。特に、インターフェイス入力ボックスや API インターフェイスが文字列の入力をサポートしている場合、不明なソースからのユーザー入力に対する予防策が講じられていない場合、セキュリティ上の問題が発生しやすくなります。
- 正しいアプローチは、ビジネス プロセスに従って各リンクに適切なセキュリティ保護と処理ロジックを追加することです。たとえば、入力文字列パラメータに対して特定のパラメータ検証を実行し、SQL 操作の実行に関連するパラメータをプリコンパイルし、エコーのコンテキスト フィールドに従ってインターフェイス エコーに参加するパラメータをエンコードします。
- ビジネス プロセスが異なれば、特殊文字に対するセキュリティ保護も異なり、対応する設計と実装のコストが高くなるため、通常、誰もが防御の第一線 (パラメータの検証) でほとんどの問題を解決し、後続のプロセスの作業負荷と困難さを軽減する傾向があります。処理。したがって、この記事は、パラメータ検証フェーズ、特に特殊文字に関連する検証における信頼できない文字列の検証とフィルタリングを設計する方法を分析し、議論することを目的としています。
特殊文字検証の原則
Huawei Webアプリケーションセキュリティ開発仕様を参照してください: 入力データに許可された文字セットのみが含まれており、違法な危険な文字が含まれていないことを確認してください。可能な限り、入力検証には「ホワイトリスト」方式を使用してください。
一般的な考え方は、次の 2 つの状況があるということです。
- XXid、XXname、電子メール、携帯電話番号など、明確な範囲のフィールドを入力します。許可される入力範囲を明確にリストし、ホワイトリスト検証方法を使用できます。たとえば、ユーザー名に文字、数字、アンダースコアのみを含めることが許可されている場合は、正規表現を使用して入力をホワイトリストに登録できます: ^[0-9A-Za-z_]+$
- 注記やリッチテキストコンテンツなど、入力範囲が広く、特殊文字(キーボードで直接入力できるもの、キーボードで直接入力できないものを含む)が多く内容が不明確な項目の場合単純なホワイトリスト列挙方式で正当な文字の範囲を列挙する場合、業務プロセスに応じて該当する危険文字を選択し、ブラックリストフィルタリングと検証を行う必要があります。たとえば、ユーザーが保存した後にインターフェイスに表示され、他のユーザーが見ることになるコメント フィールドがあります。この時点では、XSS に焦点を当てる必要があります。次の定期的なチェックを使用して、文字列が保存されているかどうかを確認できます。指定された危険な文字 ^[^"'()<>/&=]+$ は含まれていません。
拡張:パラメータの検証は、ほとんどの問題を低コストで一度に解決することのみを目的としていることに注意してください。このリンクの検証に完全に依存することはできません。また、強制することもできません。この検証には、潜在的に危険な文字をすべて含めてください。例えば、上記の例の発言で、業務上(,)や=などの記号の入力が必要な場合はどうすればよいでしょうか?単に入力が許可されていないだけでしょうか?それも無理がある。したがって、XSS インジェクション保護の究極の解決策は、セキュリティ上の問題を引き起こすことなくほとんどの文字の入力をサポートできるように、レンダリング前に文字エンコーディングを実行することです。したがって、他のセキュリティ保護 (文字エンコーディング、SQL プリコンパイルなど) と組み合わせて、最も一般的で危険な少数の特殊文字のみを特殊文字検証用に選択することをお勧めします。
一般的な安全シナリオに対応する危険な特殊文字の表
使用上のガイダンス: セキュリティ評価を行う場合、文字、数字、漢字、およびセキュリティ攻撃シナリオのない文字を安全な最小セットとして使用できます。カスタム スプライシング SQL が関与しない場合、最初の列は無視できます。
特殊文字 |
SQLインジェクション攻撃 |
XSS |
コマンドインジェクション |
ファイルインクルード攻撃 |
XXE |
URLエンコード攻撃 |
CSVインジェクション |
、 |
フィルタリングが必要 |
||||||
。 |
フィルタリングが必要 |
||||||
? |
|||||||
! |
フィルタリングが必要 |
フィルタリングが必要 |
|||||
: |
|||||||
; |
フィルタリングが必要 |
フィルタリングが必要 |
フィルタリングが必要 |
||||
「 |
フィルタリングが必要 |
フィルタリングが必要 |
フィルタリングが必要 |
||||
' |
フィルタリングが必要 |
フィルタリングが必要 |
フィルタリングが必要 |
||||
( |
フィルタリングが必要 |
フィルタリングが必要 |
フィルタリングが必要 |
||||
) |
フィルタリングが必要 |
フィルタリングが必要 |
フィルタリングが必要 |
||||
[ |
フィルタリングが必要 |
||||||
] |
|||||||
{ |
|||||||
} |
|||||||
<; |
フィルタリングが必要 |
フィルタリングが必要 |
フィルタリングが必要 |
フィルタリングが必要 |
|||
> |
フィルタリングが必要 |
フィルタリングが必要 |
フィルタリングが必要 |
フィルタリングが必要 |
|||
- |
フィルタリングが必要 |
フィルタリングが必要 |
|||||
_ |
フィルタリングが必要 |
||||||
/ |
フィルタリングが必要 |
フィルタリングが必要 |
フィルタリングが必要 |
フィルタリングが必要 |
フィルタリングが必要 |
フィルタリングが必要 |
|
\ |
フィルタリングが必要 |
フィルタリングが必要 |
フィルタリングが必要 |
||||
| |
フィルタリングが必要 |
フィルタリングが必要 |
|||||
@ |
フィルタリングが必要 |
フィルタリングが必要 |
|||||
# |
|||||||
$ |
フィルタリングが必要 |
||||||
% |
フィルタリングが必要 |
フィルタリングが必要 |
|||||
^ |
フィルタリングが必要 |
||||||
& |
フィルタリングが必要 |
フィルタリングが必要 |
フィルタリングが必要 |
||||
* |
フィルタリングが必要 |
||||||
+ |
フィルタリングが必要 |
フィルタリングが必要 |
フィルタリングが必要 |
||||
= |
フィルタリングが必要 |
フィルタリングが必要 |
フィルタリングが必要 |
||||
~ |
フィルタリングが必要 |
||||||
` |
フィルタリングが必要 |
||||||
空間 |
フィルタリングが必要 |
フィルタリングが必要 |
|||||
改行 |
フィルタリングが必要 |
特殊文字の練習
半角/全角の違い
デフォルトで全角である漢字を除いて、文字、数字、句読点などの多くの文字は、半角と全角に分けられます。最も一般的なのは半角と全角です。幅はあまり使用されません。しかし、ブラック リストとホワイト リストの通常のルールを作成する場合、その違いを理解していないと間違いを犯すことになります。
UEではバイト長を表示することができますが、文字、数字、句読点をそれぞれ半角(1バイト幅)、全角(2バイト幅)で入力して比較すると以下のようになります。
以下の検証により、^[a-zA-Z0-9,.]+$ は半角文字のみに一致し、全角文字には一致しないことがわかります。
全角の文字と数字を一致させたい場合は、 ^[\uFF21-\uFF3A\uFF41-\uFF5A\uFF10-\uFF19]+$ を使用できます。実際の検証は次のとおりです。
キャリッジリターン/ラインフィードの違い
キャリッジ リターン (\r): CR (キャリッジ リターンの略、ASCII コードは 13、16 進数は 0D に相当)、タイプライターに「プリント ヘッドを行の先頭に配置する」ように指示します。
ライン フィード (\n): LF (ライン フィードの略、ASCII コードは 10、16 進数は 0A に相当)、タイプライターに「印刷用紙を 1 行下に移動する」ように指示します。
第二次世界大戦中に米国で使用されたタイプライターに起源を持ち、電子コンピュータの出現後、これら 2 つの概念も同時に導入されました。メモリは高価であるため、各行の末尾に 2 文字を追加するのは無駄が多すぎると考える科学者もいます。1 文字を追加すれば十分です。それ以来、コンピューター コミュニティは分裂してきました。
- Microsoft Windows システム: 各行の末尾に「<Enter><改行>」、つまり「\r\n」があります。
- Unix/Linux システム: 各行の末尾には「<newline>」、つまり「\n」のみがあります。
- Apple Mac システム: 各行の末尾には「<Enter>」、つまり「\r」のみがあります。
これらの概念についてよく理解していないと、間違った正規表現を作成する可能性があります。 Windows システムと Linux システムにそれぞれ、内容 AB{newline}AB のファイルを作成します。以下のとおり、肉眼では違いがわかりません。
UE で Ctrl+H を押してバイナリを表示します。以下に示すように、ウィンドウ ファイルの改行文字は実際には 0D 0A、つまり \r\n です。
Linux ファイルの改行文字には 0A が 1 つだけあり、それは \n
正規表現を使用してコードを介してファイルの内容を読み取り、判断を行ったところ、^[AB\nAB]+$ は Linux 環境でのみファイルと正常に一致することがわかりました。
デバッグを通じて、2 つのファイルから読み取られた特定の内容を確認することもできます。
![cke_157.png](https://img-blog.csdnimg.cn/img_convert/882ac83a2bc192e077b3412b8c703902.png)