12

私は、2007 年に開始され、オリジナルのmysqlモジュールを使用する PHP コードベースの保守と拡張を担当しています。すべてのユーザー入力は、数値であると予想される値のキャストを使用してエスケープされ、文字列には一重引用符を使用して引用され、フィールドまたはフィールドに対してmysql_real_escape_string()さらにフィルター処理される可能性があります。制約のないすべての文字列フィールドは、 HTML を出力するときにまたはを介し​​て渡されます。値が外部キーを表す場合、そのキーが最初に存在することが確認されます。 これらの手順に厳密に従うことで、アプリはインジェクションやその他の形態の攻撃に対して可能な限り安全であると信じています. (ボーナスポイント:私は正しいですか?そうでない場合、何が欠けていますか?)in_array()ENUMarray_intersect()SEThtmlspecialchars()htmlentities()

このアプリをmysqliPDO に変換するのは、かなり大きな作業になります (また、偶発的な破損を避けるため、自動化する必要はありません)。最後に質問です。古いモジュールを使用しているときに緩和できない特定の脆弱性はありmysqlますか?新しいモジュールへの移行が必要になりますか?

報奨金情報:
明確にするために、私は CVE 番号のリスト、または PHP 開発者から、このmysqlモジュールが特定の日付の時点ですべての既知の脆弱性に対してパッチを適用されているという声明を期待しています。また、モジュールを使用する際に現在のベスト プラクティスに従うことで、追加の攻撃ベクトルにさらされることはないと想定しています。BCP には、新しいステートメントに挿入する前にデータベースから取得したエスケープ データが既に含まれています。それについて何度も続けることは、実際には問題に対処していません。

4

4 に答える 4

7

私は2つの異議しかありません

  • All user input is escaped二次注入につながる重大な障害です。「SQL のすべての動的データ」は正しいアプローチと言い回しです
  • あなたの投稿には識別子が記載されていませんが、2007 年以降、動的識別子を使用したクエリがコードに含まれていないとは信じられません。

ちょっとした不便もあります: 数年 (おそらく 3 ~ 4 年) で、PHP は E_DEPRECATED レベルのエラーを発行し始めます。しかし、それらは単にオフにすることができます。

とにかく、ある API から別の API に機械的に移動するだけではあまり意味がありません。
SQL 処理コードをリファクタリングして、ORM、AR、QueryBuilder など、生の API 呼び出しをアプリケーション コードから消去する何らかの抽象化メカニズムを利用します。これにより、コードの肥大化が軽減されるだけでなく、将来 PHP 開発者を襲う気まぐれからコードを独立させることもできます。

編集された質問に答える。

古い mysql ext には本質的な脆弱性はありません。一般的に使用される唯一の方法は、脆弱でエラーが発生しやすい方法です。
したがって、モジュールの歪みを探すのではなく、コードをより適切に監査してください。プリペアド ステートメントを使用してデータベースとやり取りするための集中型ライブラリを使用していない場合は、脆弱である可能性が高くなります。

于 2013-03-18T09:25:46.867 に答える
1

私はあなたの質問に明確に答える資格があるとは思わないので、私が提供する情報を慎重に使用してください. AFAICS ただし、あなたの発言が真実であれば、あなたのステートメントは XSS と SQL インジェクションからあなたを保護するはずです。

私は最近、大規模なアプリケーション全体を mysql_ から mysqli_ に移行するプロセスを開始しました。その際、すべてのユーザー入力が準備済みステートメントを通過するという目標も設定しました。

以下の YC の公正なコメントに応じて編集します。ユーザーデータの再挿入は信頼性が低く、システム関数は自動生成されたインデックスに依存する傾向があるため、可能であれば使用を避けています。

公平を期すために、ページは短い (1000 行以内) ため、1 ページあたりの修正に時間がかからず、クエリも少ないため、パフォーマンスの低下は目立たず、元のコードを書いて以来、サーバー テクノロジの改善によって確実に食い尽くされています。 . 重要かどうかを確認する必要がありますが、エスケープなどの削減が prep ステートメントのパフォーマンスへの影響をはるかに上回ることがわかると思います。

このレビューを行っている間に自分のコードにいくつの脆弱性を見つけたのかがっかりしました (私はコードを書いたときに可能な限りセキュリティを含め、自分自身と同じようにルールを設定しました)、最終的には大きなコード チャンクを書き直す必要があることに気付きました。セキュリティを向上させます。エクスペリエンスの向上とコードの微調整の結果、パフォーマンスが著しく向上しました。

変更について私が行っている方法は、データベース ヘッダー ファイルに mysqli 接続を追加することです。新しいコードはすべてこれを使用します。時間を見つけて、古いコードを更新し、古い mysql 接続を持たないヘッダー ファイルを使用して各ページをテストしています。開発環境でそのように見逃したビットを見つけるのは非常に迅速であり、各ページの更新に数分しかかからず、ブレインフェード中に実行できるため、そうでなければ無駄になる時間を使用するのに非常に良い方法です。ピリオド。

ところで、これは私が組み込んだ最も一般的な脆弱性であったため、二次注入に関するメモ:

ほとんどの SQL インジェクション防止は、インジェクション攻撃がログイン時にのみ発生し、一度失敗した悪意のある未登録ユーザーが二度と戻ってこないこと、および登録ユーザーが信頼できることを前提としています。そうではありません。

コードが保護を介して挿入され、後で使用される可能性があります。不器用なデータベースとアプリケーション設計に大きく依存しているため、これが機能する可能性はほとんどありませんが、世界で最も賢い人々の一部はハッカーです. なぜ彼らの生活を楽にするのですか?

SQL が単純で、アプリケーションが以前にデータベースから取得したデータを使用してサブクエリを実行する場合、攻撃の可能性が高くなります。覚えておいてください

' OR 1=1 gets converted to
\' OR 1=1 by mysql_real_escape_string but is stored as 
' OR 1=1 in the db 

したがって、取得してPHP変数に配置し、SQLクエリでエスケープせずに使用すると、エスケープされていない場合と同じように問題が発生する可能性があります。すべてのクエリに prep ステートメントを使用するだけで、リスクは完全になくなりますが、prep ステートメントには依然として悪意のあるコードが保存されるため、入力したデータを次に使用する必要がある場合は、準備済みステートメントを再度使用する必要があることに注意してください。

このブログでは適切な説明と例が提供されているため、これ以上詳しく説明することはしませんが、クエリの一部として使用する場合、すべてのユーザー入力データが準備されたステートメントを介して渡されることを確認すると、デシベル、あなたは安全なはずです。

繰り返しになりますが、貴重なセキュリティに関する議論を行っているOWASP サイトと親しくなることも価値があります。

于 2013-08-04T10:41:23.953 に答える