web-dev-qa-db-ja.com

この「魔法のパラメータ」の例のセキュリティ上の欠陥は何ですか?

私は読んでいます OWASP Testing Guide v

例1:マジックパラメータ

「マジック」という名前と値のペアを受け入れ、次に値を受け入れる単純なWebアプリケーションを想像してみてください。簡単にするため、GETリクエストはhttp://www.Host/application?magic=valueのようになります。

例をさらに簡略化するために、この場合の値は、ASCII文字a〜z(大文字または小文字)および整数0〜9)のみにすることができます。このアプリケーションの設計者は、テスト中に管理バックドアを作成しました、しかし、不用意な観察者がそれを発見できないように難読化しました。値sf8g7sfjdsurtsdieerwqredsgnfg8d(30文字)を送信すると、ユーザーはログインし、アプリケーションを完全に制御する管理画面が表示されます。HTTPリクエスト今です:

http://www.Host/application?magic=sf8g7sfjdsurtsdieerwqredsgnfg8d

他のすべてのパラメーターが単純な2文字と3文字のフィールドだったとすると、約28文字で組み合わせを推測し始めることはできません。 Webアプリケーションスキャナーは、30文字のキースペース全体をブルートフォース(または推測)する必要があります。これは最大30 ^ 28の順列、つまり何兆ものHTTPリクエストです!それはデジタル干し草の中の電子です!

この例のMagic Parameterチェックのコードは、次のようになります。

public void doPost( HttpServletRequest request, HttpServletResponse response)
{
String magic = “sf8g7sfjdsurtsdieerwqredsgnfg8d”;
boolean admin = magic.equals( request.getParameter(“magic”));
if (admin) doAdmin( request, response);
else .... // normal processing
}

コードを調べると、この脆弱性は実質的にページから潜在的な問題として飛び出します。

私は初心者なので、コードの脆弱性はすぐにはわかりません。誰かがコードの何が間違っているのか正確に説明できますか?

4
Alex Popov

ここで、ユーザーがマジックストリングを知っている場合、パラメーター「magic」の値としてストリング「sf8g7sfjdsurtsdieerwqredsgnfg8d」を含むリクエストを送信すると、ユーザーは管理者権限を取得します。

マジッククレデンシャル/文字列は、開発者がテストに使用することがよくあります。多くの場合、アプリケーションを本番段階にデプロイするときにそれらを削除するのを忘れ、その結果脆弱性が発生します。

6
DanielE

実際には、equalsの時定数の実装がないため、タイミング攻撃を使用してmagicを計算することができます。

参照してください http://codahale.com/a-lesson-in-timing-attacks/

public static boolean isEqual(byte[] a, byte[] b) {
    if (a.length != b.length) {
        return false;
    }

    int result = 0;
    for (int i = 0; i < a.length; i++) {
      result |= a[i] ^ b[i]
    }
    return result == 0;
}
10
Steven R.

インジェクションが発生しにくいように見えるため、コードスニペット自体に固有の脆弱性はありません。もちろん、ローカルマジック変数が「通常の処理」コードのどこかに公開されていないと想定しています。コードの品質について議論することはできますが、この場合に何が脆弱になるのかはわかりません。

全体の脆弱性は設計に起因します。

もちろん、だれもが力ずくで魔術の文字列を見つけようとすることはありません。時間がかかり、サーバーのログに記録され、魔術の文字列を推測する統計的機会のはるか前に簡単に発見されます。代わりに、システム全体に対する最も簡単な攻撃は、サーバーの前に(または正当な管理ユーザーとサーバーの間の任意の時点で、管理者が十分に機能しない場合はパブリックWiFiが最善策です)、キャッシュ要求パッケージをサーバー-遅かれ早かれ管理者がログインし、実際にシルバープラッターで魔法の文字列を提供します。

そして、それはすべてサーバー自体が適切に保護されていることを前提としています-アクセスログが漏洩したり、保護されていない場所にアクセスログが戻ったりした場合、ネットワークfooを実行する必要さえありませんマジックストリング。

3
BeagleEagle

もっと早く見たかったのですが、OWASPテストガイドを自分で読んでいます。私にとって、コードスニペットには以下の明らかな欠陥があります。

  • 保存されたパスワードはクリアテキストです。
  • 保存されたパスワードは、ユーザーが提供したクリアテキストのパスワードと比較されます
  • パスワードはソースコードに保存され、バージョン管理に委ねられる可能性があります

これは、ユーザーパスワードをクリアテキストとしてデータベースに保存するようなものです。データベースがハッキングされた(またはソースコードが盗まれた)場合、パスワードはすぐに判明します。クリアテキストのパスワードを保存する理由や理由はありません。ソルトや強力に暗号化されていないパスワードを保存するのは十分に悪いです。

このコードを改善し、テストのために開発者のバックドアを残します...

  • 文字列のソルト/ハッシュバージョンを環境変数として保存します(VCSにコミットされません)
  • 保存された暗号化された文字列を、ユーザーが提供したソルト/ハッシュバージョンのクリアテキストパスワードと比較します。 (標準ログインと同様)

PHPでは、次のようになります。

public function doPost(HttpRequest $request, HttpResponse $response){

    $admin = password_verify($request->get('magic'), $_ENV['ENCRYPTED_STRING']);

    if($admin) {
        $this->doAdmin($request, $response);
    } else {
        // do normal processing of request and response
    }

}

これでも、ログに記録されたり盗聴されたりする可能性のあるクエリ文字列でクリアテキストのパスワードを渡すという問題は残りますが、それは質問の範囲外の問題です。

1
NickB