文字列入力からすべてのスペースを削除することでSQLインジェクション攻撃から保護できるかどうか知りたいですか?
私は [〜#〜] owasp [〜#〜] でSQLインジェクションについて読んでいますが、スペースの削除については何も言及されていないので、なぜそうなるのか、そうでないのか興味がありました作業?
私は この質問 を見ていましたが、これはtrim
について尋ね、一番上の答えは次のとおりです:
いいえ、トリムを追加してもSQLインジェクションは妨げられません。
trim
は、文字列の外側のスペースのみを削除します。Select * from aTable where name like '%'+@SearchString+'%'
@SearchStringが次のようなものを保持している場合
'' update aTable set someColumn='JackedUpValue' where someColumn like '
それをすべてまとめて動的に実行すると、
Select * from aTable where name like '%' update aTable set someColumn='JackedUpValue' where someColumn like '%'
ただし、その検索文字列を取得した場合
update aTable set someColumn='JackedUpValue' where someColumn like
この質問 に示されている操作を実行しましたが、
updateaTablesetsomeColumn='JackedUpValue'wheresomeColumnlike
どちらを実行するべきではありませんか?
これを無効にできるSQLインジェクションの形式があるかどうか知りたいのですが。 1つのWordの危険なコマンドはありますか?これを打ち負かすことができるなら、スペースを削除することは少なくとも防御に少し役立つでしょうか?
注:この質問は、SQLインジェクション防止の「適切な」メソッドの使用を回避する方法としてではなく、純粋に好奇心からのものです。
いいえ。パーサーが入力を処理する方法は他にもたくさんあるので、スペースを削除してもSQLインジェクションは妨げられません。例を見てみましょう。クエリでユーザー提供の入力を安全に使用しないURLがあるとします。
http://example/index.php?id = 1 => SELECT * from page where id = 1
あなたの例では、攻撃者はスペースを使用します:
http://example/index.php?id = 1%20or%201 = 1 => SELECT * from page where id = 1 or 1=1
。
スペースを削除すると、注入が文字列に折りたたまれます。
次に、攻撃者が別の形式の空白、つまりタブを使用したと想像してください。
http://example/index.php?id = 1%09or%091 = 1 => SELECT * from page where id = 1 or 1=1
。
スペースを削除しても、注入は可能です。
使用しているテクノロジーによっては、攻撃者はスペースを/**/
%00
%09
%0a
%0d
またはSQLパーサーによるトークン化を引き起こす任意の数のUnicode。参照されている例ではスペースだけではなく、前述の例ではSQLコメントを利用して、空白ではないトークン化を引き起こしています。あなたはまだ脆弱です。
SQLインジェクションを防ぐ唯一の信頼できる方法は、パラメーター化されたクエリを使用することです。
2016年です。安全でないコードを使用しない限り、SQLインジェクションは過去のものです。
使用する言語が何であれ、all SQLインジェクションを防止したい場合は、準備されたステートメントまたは他のタイプのデータを使用しますバインディング。
準備されたステートメントはクエリをデータから分離し、データがクエリに影響することを不可能にします。
質問に直接答えるために、スペースを削除するとSQLインジェクションは削減されますが(古いコードとライブラリを使用する場合)、入力テキストは確実に制限されます(スペースはありません)。
それは問題を制限しますが、それを排除しません。次の状況を考慮してください。
$un = str_replace(" ", "", $_POST["username"]);
$pw = hash($_POST["password"];
$sql = "SELECT * FROM users WHERE username = '$un' AND password = '$pw'";
ユーザー名を投稿するとしましょうadmin'--
。それは私を単一のスペースを使用せずに管理者としてログインします。
wireghoul が指摘するように、タブなどの他の空白文字も削除する必要があります。しかし Julie Pelletier が指摘するように、準備されたステートメントを使用してください。 SQLiを使わずにSQLiを停止するための巧妙なスキームを考え出そうとするのは楽しいゲームかもしれませんが、準備されたステートメントが行うようなセキュリティは決して得られません。他のすべては単なる気晴らしです。
いいえ。これをSQLとして持っているとしましょう:
_"select * from people where last_name = '" + surname + "'"
_
入力すると:'OR(1=1)OR'a'='
が入力になり、次のようになります。
_select * from people where last_name = ''OR(1=1)OR'a'=''
_
これは、OracleとMySQLで(少なくとも)実行され、テーブルからすべての行を返します。
ただし、その検索文字列を取得した場合
update aTable set someColumn='JackedUpValue' where someColumn like
とこの質問に示されている操作を実行したのですが、
updateaTablesetsomeColumn='JackedUpValue'wheresomeColumnlike
実行してはいけませんよね?
他の人が指摘したように、タブや\n
(改行)など、考慮する必要のあるさまざまなSQLデータベース実装に空白を入れる他の方法があります。ほとんどすべてのデータベースエンジンは次のように受け入れます。
update
aTable
set
someColumn='JackedUpValue'
さまざまなデータベースのローカリゼーション設定に基づいて空白として機能するさまざまなUnicode文字があるかもしれませんが、それを理解するには実装の詳細を掘り下げる必要があります。パラメータ化されたクエリを使用するだけでなく、文字列を置換するこれらすべてのEdgeケースを試してカバーする理由は本当にありません。
だからここにアイデアがあります。データベースサーバーは、受信したSQLクエリを受け取り、それをパーサーで実行して、解析ツリーを作成します。次に、ツリーを計画に変換して実行します。
インジェクションの本質は、パーサーがプログラマーが意図したものとは異なるツリーを生成することです。
したがって、修正は異常な解析ツリーを検出できるようにすることです。解析後、ツリーを歩き、データ値を差し引いた標準形式の文字列を生成します。文字列のSHA=ハッシュを計算します。アプリケーション/データベースユーザーの既知のハッシュのテーブルを保持します。サーバーが不明なハッシュを検出した場合は警告または中止します。
明らかに、起動の問題があります。したがって、プログラマーはテストモードでアプリケーションを実行し、徹底的なテストの後にハッシュを抽出し、アプリケーションの起動時にサーバーにハッシュをロードする必要があります。次に、abort-on-new-hashをオンにすると、SQLインジェクトができなくなります。