仕組み:CAPTCHA

Habrが存在してから何年が経ちますか-何年もの間、次のcaptchaの投稿が定期的に表示されます-それは、画像を生成するスクリプト、猫とのcaptchaの新しいアイデアなどです。 人がまったく理解していない最新の例は、captchaがすべて同じように機能する必要があることです(投稿テキストと最近のコメントを参照)が、同時に彼の間違いをコミュニティと共有しています。 ほとんどの開発者にとって、captchaは非常に無知であるという感覚が得られます。「箱から出して」動作することを期待して次のフォームに単純にねじ込む人と、そのようなcaptchaを思い付く人の両方にとっていくつかの写真から猫の写真を選択する必要があります。



この記事には、reCaptchaのようなサードパーティのサービスを信頼する代わりに、サーバーでcaptchaを使用する人に役立つ情報が含まれています。



そしてシードのために-あなたがそのようなキャプチャチェックが機能すると思う場合:

if($_POST['captcha'] == $_SESSION['captcha']) return true;



(ケーススタディ)

その後、あなたは深く誤解されています。





キャプチャ



その定義により、captchaはチューリングの自動化された公開テスト(人はパスできるが、コンピューターはパスできないテスト)です。 記事では、最も一般的な形式の例であるcaptchaの特性を検討します。これは、画像内のテキストですが、書かれたほぼすべてがあらゆる種類のcaptchaに等しく適用できます。



キャプチャの2つの主なプロパティ



キャプチャには2つのプロパティが必要です。これらがないと機能しません。



認識抵抗 -キャプチャをアルゴリズムによる認識から保護するプロパティ-たとえば、テキスト認識システム。 それは、人が写真のテキストを読むことができることを保証しますが、コンピューターはそうしません。

例:標準のphpBB 2.xフォーラムcaptchaにはこのプロパティがありませんでした-認識が比較的容易であるため、スクリプトはすべてのフォーラムを連続してスパムし、ウェブマスターにcaptchaをより安定したものに変更するように強制しました。



推測推測はcaptchaのプロパティであり、少数の試行(1000回未満)でその値を推測することはできません。 キャプチャの可能な値のセットが小さい場合、プログラムは認識ではなく選択を推測するのが難しくありません。

例:「1 + 2」のような算術キャプチャ(1から20までの数字を列挙すると、すぐに結果が得られます)。

反例:猫が描かれている画像をいくつかの画像から選択します。



CAPTCHA CHECK



検証のための値はサーバーに保存され、画像とともにブラウザに送信されるべきではありません。 訪問者とキャプチャの正しい値を比較するには、特定のキーを使用する必要があります。このキーは、キャプチャとともに送信されます(セッション識別子、キャプチャ番号など)

反例:キャプチャ自体とその検証の値(暗号化を含む)を転送する場合、そのようなキャプチャを一度認識し、スクリプトで「応答」-「検証の値」の組み合わせを使用するだけで十分です(投稿の冒頭のリンクのみ)そのような場合)



答えを確認する前に、空でないことを確認する必要があります。 それ以外の場合、攻撃者は画像をアップロードしたり、現在のセッションの識別子を削除したりすることなく、空の値を渡し、キャプチャを渡すことができます。 2つの空の文字列が比較されます(PHPでは、存在しない値は空の文字列に等しくなります)。

if($_POST['captcha'] == $_SESSION['captcha']) return true;



if($_POST['captcha'] == $_SESSION['captcha']) return true;



既に述べたコードif($_POST['captcha'] == $_SESSION['captcha']) return true;





さらに、このコードは経験豊富なプログラマーによって作成されました。



確認後、保存されているcaptcha値を削除する必要があります。 これが行われない場合、攻撃者は何度でもこの値を使用できます。 はい、フォームのあるページが更新されると、captchaも更新されます(フォームの生成時または画像の生成時のいずれか)、スクリプトのみがフォームを再度ロードできません(サイトがフォームにワンタイムcsrfトークンを使用する場合、これは関係ないことに注意してください)

反例:キャプチャを1回正しく入力し、スクリプトでパスワードを選択するだけで十分な仮想ログインフォーム。サーバーでのキャプチャの再生成を回避します。



防弾キャプチャ



過剰な保護。 キャプチャが認識に耐性があるが、列挙にはあまり耐性がない場合(たとえば、3桁から4桁だけを読み取る必要がある場合)、「1つのIPから」/「1つのログイン用」などの不正解の数を制限することをお勧めします。 そのような制限は、キャプチャ自体をチェックする前にチェックする必要があります(つまり、正しく入力されたキャプチャの場合でも、制限がある場合、それは合格と見なされるべきではありません)。そうしないと、検索に干渉しません。



DoS保護。 サーバーでcaptchaを生成する場合、これはDoS攻撃(DDoSとは異なり、どの学生でも手配できる)にとって便利なベクトルであることを理解する必要があります。 保護のために、1つのIPに対するキャプチャ生成の数、キャッシュキャプチャなどを制限できます。 これについての詳細



認識保護。 キャプチャを選択した場合、または突然自分でキャプチャする場合は、どのキャプチャが認識からより保護されているかを理解することをお勧めします。 OCRの原則に従って動作する既製のユニバーサルキャプチャ認識スクリプトがあります。サイトがスパマーに興味がある場合、キャプチャ用のスクリプトを使用/作成するリスクがあります。 後者の真実は、Yandexまたはvkレベルのサイトにさらに当てはまりますが、一般的なOCRから保護するオプションを提供することをお勧めします。



アンチゲートに対する保護。 正式に言えば、アンチゲートから保護するためにチューリングテストとしてのキャプチャは必要ありません。この場合、人はそれを認識するからです。 実用的な観点から、この問題は非常に関連性が高く、何らかの形で自分を守る必要があります。

「ゴールドスタンダード」はありません(この場合、アンチゲートはそのサポートを実装するため)。したがって、アンチゲートを介した認識を不可能にするために、キャプチャに任意のトリックを追加できます。 例:

-非標準のキャプチャ(パズルコレクション、画像の回転、写真の領域をクリックなど)。

-キリル文字のキャプチャ-最も簡単な解決策ですが、いくつかの欠点があります。ロシア語を話す聴衆を持つプロジェクトにのみ適しています。キリル文字をサポートするアンチゲートがあります。

-非標準文字または数字を入力するためのキャプチャの横にある仮想キーボードの使用(モバイルユーザーにとっては不便かもしれません)。



使いやすさ



自分の前に人がいるとすでに確信している場合は、キャプチャを要求しないでください。 ただし、ここでは、人がキャプチャを1回入力した後、スクリプトでフォームを無制限に使用できないように注意する必要があります。

例:登録フォーム。 どこかに登録して、「郵便番号」フィールドの入力を忘れたが、キャプチャを正しく入力した場合-新しいものを表示する必要はありません。 生きている人が現在この特定のフォームに記入しようとしていることを家のどこかに保つために10分かかります。



人が認識しやすくするために、キャプチャで文字と数字を同時に使用したり、大文字と小文字の両方を使用したり、類似した文字を除外したりしないでください。



キャプチャの使用の拒否



最高のキャプチャは、キャプチャがないことです。 あなたがそれを使用することを拒否できる場所-これは行われなければなりません。 追加の制限とチェックを実装する必要があるかもしれませんが、ユーザーはあなたに感謝します。

しかし、ここでは非常に注意する必要があります。 例:アクティベーションレターが届く電子メールフィールドを含むキャプチャなしの登録フォーム。 追加のセキュリティ対策なしでは、そのようなフォームは「左」アドレスで圧倒される可能性があり、あなたのサイトは郵便サービスのブラックリストに含まれます。 この場合、captchaなしで実行できますが、ip制限など、別の保護ラインがある場合に限ります。



一部の人にとっては、このトピックの情報は明らかなように思えますが、経験豊富な仲間の開発者を含め、これらの単純な原則の誤解の例に出会わなければ、このテキストを書くのに時間を浪費することはなかったでしょう。



All Articles