web-dev-qa-db-ja.com

ユーザーエージェント文字列が適切な構文を持っているか、ハッキングの試みであるかどうかを判断する方法は?

私はawstats経由でサーバーをチェックして、誰が私のサイトにアクセスしているかを確認していましたが、次の値のユーザーエージェントがあります。

}__test|O:21:\

いくつかの研究により、誰かが私のサーバーをハッキングしようとしていると信じるようになりました。

このようなことが起こらないようにするために、ユーザーエージェント文字列が100%正当であり、ハッカーが作成した文字列ではないことを判断する際の構文規則は何ですか?たとえば、適切なユーザーエージェント文字列で許可されている/許可されていない文字は何ですか?また、一部の文字は特定の順序にする必要がありますか?

4
Mike

ルールはありません。ユーザーエージェントはanythingになります。

正当なものが多数あり、正当なユーザーを誤ってブロックしたくないため、ユーザーエージェントをホワイトリストに登録する合理的な方法はありません。また、ユーザーエージェントが不良ユーザーを表しているかどうかを判断する標準的な方法がないため、不良ユーザーエージェントをブロックする方法もありません。

不正なボットをブロックしようとする場合、ユーザーエージェントを このデータベース と比較し、それが誰であるかを確認してから、ブロックするかどうかについて半教育的な決定を下すことができます。また、いくつかの 悪いユーザーエージェントのリストを維持する試み がありますが、それらがどれほど最新であり、新しいユーザーエージェントが毎日表示されるかはわかりません。

3
John Conde

ユーザーエージェントは完全にクライアントによって制御されるため、さまざまな攻撃で使用される可能性があるため、それに注意を払うことをお勧めします。

ユーザーエージェントで許可されている文字

適切なユーザーエージェント文字列で許可されている/許可されていない文字と、特定の順序にする必要がある文字

@ Stephen Ostermiller すでにRFC2616にリンクされています。 RFC7231 で更新されましたが、実際には何も変更されていません。

User-Agent = product *(RWS(product/comment))
[...]
product = token ["/" product-version]
製品バージョン=トークン

ただし、コメントがどのように見えるかを指定するために RFC72 にリンクします。

comment = "(" *(ctext/quoted-pair/comment) ")"
ctext = HTAB/SP /%x21-27 /%x2A-5B /%x5D-7E/obs-text
[...]
quoted-pair = "\"(HTAB/SP/VCHAR/obs-text)

これは、ほとんどすべての文字がユーザーエージェントのコメント部分で許可されていることを示す、凝った方法です。 ()\は、自由に配置できない唯一のものです。

tokenは、 RFC72 に見られるように、もう少し制限があります。 (),/:;<=>?@[\]{}は許可されません。

ユーザーエージェントをフィルタリングする方法

ユーザーエージェント文字列が100%正当であり、ハッカーが作成した文字列ではないと判断する際の構文規則は何ですか?

ユーザーエージェントにはほとんどすべての文字を含めることができるため、適切なフィルタリングは不可能です。そして、これは、すべてのクライアントがRFCに従うわけではないことを考慮していません(使いやすさの理由から、フィルタリングはあまり制限的ではないはずです)。

ユーザー入力のフィルタリングは、防御の最前線として優れていますが、入力フィルタリングですべての攻撃を防ぐことは非常に難しいため、これが唯一の防御となることはありません。

安全なコーディングを行う必要があり、一般的な攻撃に対する適切な防御を実装する必要があります。そのため、ユーザーエージェントがエコーされる場合は、XSSを防ぐためにエンコードする必要があります。ユーザーエージェントがデータベースに格納されている場合は、準備済みステートメントを使用してSQLインジェクションを防ぐ必要があります。シリアル化を解除するPHP関数に何かを渡す場合は、オブジェクトインジェクションに留意する必要があります(O:21はテストのように見えるため、言及しています)。等々。

追加の防衛線が必要な場合は、mod_securityなどのWAFの使用を検討できます。

2
tim

User-Agentヘッダーは RFC2616 の一部です。これは RFC1945 の改良版であり、次のように記述されています。

User-Agent request-headerフィールドには、リクエストを発信したユーザーエージェントに関する情報が含まれています。これは、統計目的、プロトコル違反の追跡、および応答を調整して特定のユーザーエージェントの制限を回避するためのユーザーエージェントの自動認識のためです。ユーザーエージェントは、リクエストにこのフィールドを含めるべきです。このフィールドには、複数の製品トークン(セクション3.8)と、ユーザーエージェントの重要な部分を形成するエージェントとサブ製品を識別するコメントを含めることができます。慣例により、製品トークンは、アプリケーションを識別するための重要度順にリストされています。

   User-Agent     = "User-Agent" ":" 1*( product | comment )

productは次のように定義されます。

   product         = token ["/" product-version]
   product-version = token
   token           = 1*<any CHAR except CTLs or separators>

そしてcommentとして:

   comment        = "(" *( ctext | quoted-pair | comment ) ")"
   ctext          = <any TEXT excluding "(" and ")">

ソース: Paulo Santos に対する回答 ブラウザのUser-Agent文字列の標準形式は?

1