0

私は最近、職場で Web アプリケーション (主に PHP ですが、JavaScript のかなりの部分) の制御を継承しました。私の最優先事項の 1 つは、アプリケーションが安全であることを確認することです。残念ながら、アプリケーションでのデータベース アクセスは現在、MYSQLi や PDO ではなく、カスタム クラスを介して行われています。

PDO に完全に移行するにはしばらく時間がかかりますが、それまでの間、アプリケーションを可能な限り安全にするためにできる限りのことをしたいと考えています。現在、すべての入力はパススルーmysql_real_escape_string()されており、アプリケーションとデータベースがすべて でエンコードされていることを確認しましたUTF8

PDO に完全に切り替える前に、アプリケーションを安全にするために他にできること、またはすべきこと (ベスト プラクティス) はありますか?

あなたのすべての助けに感謝します:)

4

2 に答える 2

1

あなたができることの1つは、イントラネットにそれを隠すことです(もしあれば)。あなたのサイトのサーバーが、もう一方の端にあるエキゾチックな南アメリカの大学で謎の指によってスキャンされる頻度に驚かれるかもしれません。多分。

すべての入力が検証され、期待どおりであることを確認してください。filter_var()FILTER_のsで頑張ってください。mysql_*それ自体は悪ではなく、ただ古いものであり、セキュリティで*_real_escape_string()なく、クエリの整合性に関するものです。

私はこれを行うことが知られています:

switch ($_GET['color']) {
    case 'green':
        $color = 'green';
    break;
    case 'blue':
        $color = 'blue';
    break;
    case 'yellow':
        $color = 'yellow';
    break;
    default:
        $color = NULL;
}

それは不自然ですが、あなたはドリフトを取得します。受け取ったデータに疑いの余地はなく、可能な場合はデータを使用してください。物事を単純に保ちますが、単純ではありません。クエリをPDOするような「ターンキー」アプローチが、サイトの資産(または仕事)を実際に保護するとは思わないでください。

フィールド名を検証する必要がある場合は、次のようなことをしているに違いありません。

$field = preg_replace('/[^a-z_]/', $_POST['field']);

非常識な正規表現に夢中になる...私はそれをシンプルで本当に簡単に保つようにしています。そうでなければ、かゆみを感じます。

PDOとMYSQLIは最新の優れたツールですが、セキュリティ上の懸念に代わるものでも、万能薬でもありません。コアセキュリティの原則と細部への細心の注意は、その仕事をどのように遂行するかです。たとえば、何かが「悪い考え」と見なされる理由がわからない場合は、それがわかるまで調べてください。eval()、悪意のある人は、ナイフのように悪いことをする可能性があります。しかし、「取得」するのは簡単です。セッション固定、またはXRSF/CSRFハックを試してください。それは終わりのないオデッセイです。

(新しい)コードに精通し調査を開始して継続し、あらゆる場所で厳密な検証を実装し、ユーザーランドから何も信頼せず、セキュリティの強化が終わることはないことを尊重します。

可能であれば、ベンダーに支払いをして、サイトを定期的にセキュリティスキャンします。毎月。Nessusの料金は年間1200ドルだと思います。それは絶対確実ではありませんが、まともな侵入テスターが20分で発見できるいくつかの不器用な低ぶら下がりの問題に悩まされるよりはましです。

右?


また、このコードで想像される問題に焦点を絞ったり、他の重大な懸念を無視したりしないでください。継承しているこのコードがPHP4.1を実行している場合、世界中に公開されている古いphpMyAdmin(psst、弱いパスワード)があり、サーバー管理が無視されるか、不適切に実行されると、問題が発生します。

あなたがそのようなサーバーを持っているなら、誰がSQLインジェクションの懸念を必要としますか。わからない場合はsshトンネリングする必要があります。

ポートを保護し(閉じて監視することにより)、ソフトウェアパッケージのアップグレードを維持し、SUHOSINを使用し(更新されなくなりましたが)、リバースプロキシ(Varnish)やFail2banなどの他のツールを調べます。インフラストラクチャへの脅威を管理します。コードがそこにあることに依存していない限り、セーフモードや魔法の引用符のような「テクニック」に依存しないでください。


古いメンテナと話をしている場合は、彼が心配していることを聞いてください。私は8年間維持していたサイトをひっくり返しました。話をしましたlooong...


  1. http://www.hardened-php.net/suhosin/(まだ維持されていますか?)
  2. http://sectools.org/
  3. http://h-online.com/security
  4. http://security.stackexchange.com
  5. http://www.schneier.com/
于 2013-03-08T05:46:58.793 に答える
1

あなたの質問には 2 つの仮定がありますが、実際には重大な妄想にすぎません。
あなたはそれを仮定しています

  • 「すべての入力は mysql_real_escape_string() を介して渡されます」はセキュリティを意味します
  • 「完全に PDO に切り替える」はセキュリティを意味します

どちらも真実ではありません。
どちらの mysqli も PDO も、存在するだけで「安全なアプリケーション」を意味しません。
これは単なる迷信であり、PHP 関係者の間で広まっています。

  • 彼らの懸念がデータソースのみ (つまり「ユーザー入力」) である場合、彼らは危険にさらされていることを理解する必要があります。
  • 「PDOに切り替える」だけでは何の役にも立たないことを理解する必要があります
  • mysql_real_escape_string() は文字列のみを保護でき、それ以外は保護できないことを理解する必要があります。
  • PDO のプリペアド ステートメントは、文字列と、大したことですが、数値を保護できることを理解しておく必要があります。他のすべてのクエリ部分はこれまでどおり脆弱なままにします
  • 適切に作成されたカスタム クラスは、生の mysqli や PDO よりもはるかに安全 (かつ便利) であることを理解する必要があります。とにかくカスタムクラスは必須です。

コードを安全にできるのは知識だけですが、使用している API はそうではありません。
したがって、コードを書き直す前に、安全な SQL のための 2 つのルールを次に示します。

  1. 動的にクエリに入るすべてのクエリ部分は、適切にフォーマットされたplaceholderを通過する必要があります。例外なく
  2. プレースホルダーを介して配置できないものはすべて、ホワイトリストに登録する必要があります。つまり、スクリプトにハードコードされたバリアントのリストに対して検証されます。
于 2013-03-08T06:46:02.690 に答える