0

ユーザー入力を受け取り、それを MySQL 正規表現として使用する簡単な Perl スクリプトを作成しています。ボビーテーブルのナンセンスなしで合格できるようにしたいと思います。特に、あらゆる種類の特殊文字を許可し、引用自体から抜け出す可能性のあるものはすべて拒否したいと考えています。

コードは次のようなものです。

my $myRegex = join(' ', @ARGV);
# ...other code...
sendToSQL("select blah from foo where bar regexp '$myRegex'");

特に、\(...\)andのような構造を維持する必要があります。それらをand\.に変更することはできません。これはすでに存在しているはずの単純なもののように感じます-私はここで車輪を再発明しないようにしています.\\\(...\\\)\\.

このスクリプトは、SSH 経由で信頼できるユーザー (私を含む 3 人のうちの 1 人) からのみ入力を受け取るため、「原則として」文字列をチェックせずに渡すことができます。しかし、うっかり部分的なコマンドを SQL にリークして奇妙な結果を出すよりも、正直な間違いを検出できれば、私はずっと気分が良くなります。(これ自体はセキュリティ上の問題ではありません。スクリプトにアクセスできるユーザーは、既に mySQL を直接実行できます。)

編集: 提案された複製は、私の問題にわずかに関連しており、確かに複製ではありません。私は DBI を使用しておらず、私の懸念はインジェクション攻撃ではありません。懸念は、ユーザーが悪意のあるデータベースで悪意のあるコードを実行することではなく、ユーザーが不注意でデータベースの副作用を引き起こさないことです。(スクリプトを使用するには、MySQL に直接アクセスできる必要があります。この場合、データベースに任意の変更を加えることができます。)

4

3 に答える 3

2
my $sth = $dbh->prepare("select blah from foo where bar regexp ".$dbh->quote($myRegex));
$sth->execute();

また

my $sth = $dbh->prepare("select blah from foo where bar regexp ?");
$sth->execute($myRegex);

正規表現はコストがかかるため、サーバーに悪影響を与える可能性があることに注意してください。

于 2016-01-28T22:00:26.120 に答える
1

バインド プレースホルダーを使用して準備済みステートメントを使用できない場合は、SQL テキストで指定された安全でない可能性のある値を "エスケープ" する必要があります。

エスケープする必要がある唯一の文字は、バックスラッシュ文字と、文字列を囲むために使用される引用文字です。

値を囲むために一重引用符を使用しています。正規表現内のバックスラッシュ文字の前には、別のバックスラッシュ文字が必要です。また、単一引用符を使用して文字列を囲むため、値の単一引用符の前にバックスラッシュ文字を付ける必要があります。

二重引用符などの追加の文字をエスケープできますが、特定のケースでは厳密に必要ではありません。しかし、二重引用符文字をエスケープしても問題はありません。

関数を書いた人は誰でも、DBI の "quote" 関数のラッパーとしてsendToSQL対応する関数を提供しているはずです:escapeForSQL

sendToSQL("select blah from foo where bar regexp '" . escapeForSQL($myRegex) . "'");
于 2016-01-28T22:10:08.453 に答える
0

正しいアプローチは、bobby-tables.com のアドバイスに従い、クエリでプレースホルダーを使用することです。

于 2016-01-28T22:00:14.757 に答える