1

卒業論文では、準備済みステートメントを使用して SQL インジェクションの脆弱性を自動的に検出し、修正を提案するプログラムを開発しました。具体的には、PHP の mysqli 拡張機能です。SO コミュニティに対する私の質問は次のとおりです。PHP ソース コード内の SQL を検出するために、どのようなアプローチをお勧めしますか?

を含む列挙型を使用しSQL keywords (SELECT, INSERT, ...)、基本的に各行を解析し、列挙型を繰り返し処理して、SQL が存在するかどうかを判断しました。さらに、パーサーが html を誤って検出していないことを確認する必要がありました (たとえば、<\select>)。

私にとっては、このソリューションはうまく機能しましたが、今はもう少し時間があり、コードをリファクタリングして、よりエレガントな (そして効率的な) ソリューションを使用することを考えています。私がプログラムを書いたのはC#の使用に限定してください。

4

6 に答える 6

1

あなたの解決策は私にはうまくいくようです。もう 1 つの方法は、PHP の文法を使用して Lex/Yacc パーサーで PHP ファイルを解析することです。Coco/R と呼ばれる優れた C# 文法解析ツールがあり ます http://www.ssw.uni-linz.ac.at/ココ/ .

ただし、言語を解析すると、追加の結果が得られないために (開発とコンピューティングで) 非常に多くの時間を費やすことになると思います。

私はあなたの日和見主義的なアプローチに固執しますが、さまざまな PHP コードに対してテストし、考えられるすべてのケースをカバーするように微調整します。

于 2008-08-21T16:49:51.760 に答える
1

おそらく、たとえばSQL92のBNFに対してテキスト行を解析し、フラグメントが文法にどれだけ一致しているかについて各行をスコアリングすることには、いくらかのマイレージがあります。

しかし、何か重いものを持ち上げているように聞こえます。あなたの単純なアプローチは、すでに現実世界のケースの大部分を捉えています。

于 2008-08-21T16:53:00.427 に答える
1

私は C# の変数の詳細を知らないので、PHP を使用するために私を許すか反対票を投じる必要がありますが、70% の確率で私の SQL クエリはそのような変数に入ります

$sql = "SELECT * FROM table;";

それを超えて、あなたがすでに持っているものを改善するためにあなたができることは何も考えられません.

複数の行にわたって作成され、文字列内で変数を使用するステートメントを考慮していますか? (下の例)

$sql = "SELECT * FROM table WHERE fname = $fname OR snmae = $sname";
于 2008-08-21T16:54:27.770 に答える
1

SQL自体を探すのではなく、関数呼び出しを探すのが最善だと思います。PHP パーサーを変更して、準備済みクエリではない SQL クエリを実行する関数呼び出しを探すようにします。

于 2008-08-21T19:28:46.357 に答える
0

関数で使用されるすべての CRUD sql ステートメントを検出する単純な正規表現 ($script に php スクリプト全体が含まれていると仮定)

preg_match_all('/\(\s*?"(?:SELECT|INSERT|UPDATE|DELETE) .*?"\s*?\)\s*?;/is', 
               $script, $matches);

SELECT、INSERT、UPDATE、DELETE ステートメントが括弧と二重引用符で囲まれている場合、すべての可能なステートメントに一致する必要があります。大文字と小文字が区別されず、複数行にまたがるステートメントにも一致する必要があります。

編集#1:文字列の割り当てなどのCRUDステートメントに一致するための正規表現。

preg_match_all('/\$\w+\s*?=\s*?"(?:SELECT|INSERT|UPDATE|DELETE) .*?"\s*?;/is', 
               $script, $matches);

編集#2:

// $variable detecting version of #1 regex
preg_match_all('/\(\s*?"(?:SELECT|INSERT|UPDATE|DELETE) .*?(?:\$\w+){1}.*?"\s*?\)\s*?;/is', 
                   $script, $matches);
于 2008-08-21T17:28:59.030 に答える
0

私は C# の変数の詳細を知らないので、PHP を使用するために私を許すか反対票を投じる必要がありますが、70% の確率で私の SQL クエリはそのような変数に入ります..

ええ、私の最初のアプローチは、ほとんどの人が使用しているため、 $sql 変数を探すことでしたが、いくつかの PHP アプリに対してテストした後、一部の開発者がいくつかのファンキーな変数名を使用しているため、すぐにそのソリューションを破棄しました...

複数の行にわたって作成され、文字列内で変数を使用するステートメントを考慮していますか? (下の例)

うん。また、条件付きで生成されたステートメントを処理しようとしましたが、常にうまくいくとは限りませんでした。;)

于 2008-08-21T17:06:48.803 に答える