TL; DR:句のリテラルだけでなく、すべてのリテラルを制限する必要がありますWHERE
。そうしない理由により、データベースを他のシステムから切り離したままにすることができます。
まず、あなたの前提に欠陥があります。WHERE
句のみを制限したいが、それがユーザー入力の唯一の場所ではない 例えば、
SELECT
COUNT(CASE WHEN item_type = 'blender' THEN 1 END) as type1_count,
COUNT(CASE WHEN item_type = 'television' THEN 1 END) AS type2_count)
FROM item
これは、SQLインジェクションに対しても同様に脆弱です。
SELECT
COUNT(CASE WHEN item_type = 'blender' THEN 1 END) FROM item; DROP TABLE user_info; SELECT CASE(WHEN item_type = 'blender' THEN 1 END) as type1_count,
COUNT(CASE WHEN item_type = 'television' THEN 1 END) AS type2_count)
FROM item
したがって、WHERE
句のリテラルを単に制限することはできません。すべてのリテラルを制限する必要があります。
ここで、「なぜリテラルをまったく許可するのか」という質問が残っています。この点に注意してください:リレーショナルデータベースが別の言語、時間の大部分で書かれたアプリケーションの下に使用されている間、何もありません要件データベースを使用するようにアプリケーションのコードを使用しなければならないことは。そして、ここに答えがあります:コードを書くにはリテラルが必要です。他の唯一の選択肢は、すべてのコードをデータベースに依存しない言語で記述することです。したがって、それらを使用すると、「コード」(SQL)をデータベースに直接書き込むことができます。これは価値のある分離であり、リテラルなしでは不可能です。(リテラルなしで好きな言語で書いてみてください。これがどれほど難しいか想像できると思います。)
一般的な例として、リテラルは値リスト/ルックアップテーブルの作成によく使用されます。
CREATE TABLE user_roles (role_id INTEGER, role_name VARCHAR(50));
INSERT INTO user_roles (1, 'normal');
INSERT INTO user_roles (2, 'admin');
INSERT INTO user_roles (3, 'banned');
それらがなければ、このテーブルにデータを入力するためだけに別のプログラミング言語でコードを書く必要があります。SQLで直接そうする能力は貴重です。
その後、もう1つ質問があります。なぜプログラミング言語のクライアントライブラリはそれをしないのですか?そして、ここに非常に簡単な答えがあります:彼らは、データベースのサポートされているバージョンごとにデータベースパーサー全体を再実装するでしょう。どうして?すべてのリテラルを見つけたことを保証する方法は他にないからです。正規表現では十分ではありません。たとえば、これにはPostgreSQLの4つの個別のリテラルが含まれます。
SELECT $lit1$I'm a literal$lit1$||$lit2$I'm another literal $$ with nested string delimiters$$ $lit2$||'I''m ANOTHER literal'||$$I'm the last literal$$;
特に、データベースのメジャーリリース間で有効な構文が頻繁に変更されるため、これを実行しようとするとメンテナンスの悪夢になります。
bad_ideas_sql = 'SELECT title FROM idea WHERE idea.status == "bad" AND idea.user == :mwheeler'
単一のクエリにハードコーディングされた値とパラメータ化された値の両方が含まれます。それをキャッチしてみてください!このような混合クエリには有効なユースケースがあると思います。