SQLインジェクションとは、一部のデータベースの外部インターフェースを使用して、実際のデータベース操作言語にユーザーデータを挿入し、それによってデータベース、さらにはオペレーティングシステムに侵入するという目的を達成することです。 セキュリティの分野では、我们永远不要信任用户的输入
,我们必须认定用户输入的数据都是不安全的,我们都需要对用户输入的数据进行过滤处理。没有(运行时)编译,就没有注入。
そのため、上記のタイプの攻撃を根本的に防ぐ方法は、データがコードに変換されて実行されるのを防ぎ、コードとデータの境界を常に区別することです。特に SQL インジェクションに関しては、実行された悪意のあるコードはデータベースの SQL 解釈エンジンを通じてコンパイルされるため、ユーザーが入力したデータがデータベース システムによってコンパイルされるのを防ぐだけで十分です。
他のデータベースとは異なり、MySQL は異なる SQL モード (SQL サーバー モード) で実行でき、異なるクライアントに異なるモードを適用できます。このようにして、各アプリケーションは、独自のニーズに応じてサーバーの動作モードをカスタマイズできます。スキーマは、MySQL がどの SQL 構文をサポートする必要があるか、およびどのような種類のデータ検証チェックを実行する必要があるかを定義します。これは、Apache がさまざまなレベルのエラー ログを設定し、どのエラーが報告され、どのエラーが報告されないかに似ています。
//php代码 $unsafe_variable = $_POST['user_input']; mysql_query("INSERT INTO `table` (`column`) VALUES ('{$unsafe_variable}')");
投稿内のコードが次の場合:
value'); DROP TABLE table;--
queryコードは
INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')
になります。これによりテーブルが直接削除され、データが破棄されます。 。
方法 1
prepareStatement+Bind-Variable: SQL ステートメントとクエリ パラメーターがそれぞれ解析のためにデータベース サーバーに送信されます。
phpには2つの実装方法があります。
//使用PDO(PHP data object) $stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name'); $stmt->execute(array('name' => $name)); foreach ($stmt as $row) { // do something with $row } //使用mysql扩展-mysqli $stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?'); $stmt->bind_param('s', $name); $stmt->execute(); $result = $stmt->get_result(); while ($row = $result->fetch_assoc()) { // do something with $row }
方法 2
クエリステートメントをエスケープする (最も一般的な方法): アプリケーションが提供する変換関数を使用します。
|アプリケーション|関数|
|--------| |MySQL C API | mysql_real_escape_string ()| |MySQL++|escape和quote修饰符| |PHP|使用mysql_real_escape_string()(适用于PHP4.3.0以前),之后可以使用mysqli或pdo| | Perl DBI|placeholder或quote()| |Ruby DBI|placeholder或quote()|
方法 3
検証には独自の定義関数を使用します。その本質は、入力された不正なデータをエスケープしてフィルタリングすることです。
入力の検証は次のように分類できます: 1. データを有効にするためにデータを整理する; 2. 既知の不正な入力を拒否する; 3. 既知の正当な入力のみを受け入れる。
方法 4
ストアド プロシージャを使用します。
ストアド プロシージャについては、次を参照してください: (9) mysql のストアド プロシージャと カスタム関数
#查看当前sql模式 select @@sql_mode; #查看当前sql模式 SELECT @@session.sql_mode; #修改当前sql模式 SET [SESSION][GLOBAL] sql_mode='modes';
セッション オプションは、このモードでのみ有効であることを意味します。接続、およびグローバルは、この接続では有効にならず、次の接続で有効になることを意味します。
「--sql-mode='modes'」を使用して、MySQL の起動時に sql_mode を設定することもできます。
はconfigファイルで設定できます。
ONLY_FULL_GROUP_BY:
GROUP BYaggregation 操作の場合、SELECT の列が GROUP BY に現れない場合、その列は GROUP BY にないため、この SQL は不正です条項真ん中。
NO_AUTO_VALUE_ON_ZERO:
この値は、自動拡張列の挿入に影響します。デフォルト設定では、0 または NULL を挿入すると、次の自動増加値が生成されます。このオプションは、ユーザーが値 0 を挿入する必要があり、列が自動増加する場合に便利です。
STRICT_TRANS_TABLES:
このモードでは、トランザクション テーブルに値を挿入できない場合、現在の操作は中断され、非トランザクション テーブルには制限がありません。
NO_ZERO_IN_DATE:
厳密モードでは、ゼロ日とゼロ月は許可されません。
NO_ZERO_DATE:
この値を設定すると、mysql データベースではゼロの日付の挿入が許可されず、ゼロの日付を挿入すると警告ではなくエラーがスローされます。
ERROR_FOR_pISION_BY_ZERO:
INSERT または UPDATE 中に、データがゼロで除算される場合、警告ではなくエラーが生成されます。モードが指定されていない場合、データがゼロで除算されると、MySQL は NULL を返します。
NO_AUTO_CREATE_USER:
GRANT が空のパスワードを持つユーザーを作成することを禁止します。
NO_ENGINE_SUBSTITUTION:
必要なストレージ エンジンが無効になっているかコンパイルされていない場合、エラーをスローします。この値が設定されていない場合、代わりにデフォルトのストレージ エンジンが使用され、例外がスローされます。
PIPES_AS_CONCAT:
は、or 演算子 ではなく、 文字列 の接続 演算子 として扱います。これは、Oracle データベースと同じであり、文字列連結関数 Concat に似ています。
ANSI_QUOTES:
ANSI_QUOTES が有効な場合、文字列は識別子として解釈されるため、二重引用符で引用することはできません。
説明
ORACLE の sql_mode 設定は、PIPES_AS_CONCAT、ANSI_QUOTES、IGNORE_SPACE、NO_KEY_OPTIONS、NO_TABLE_OPTIONS、NO_FIELD_OPTIONS、NO_AUTO_CREATE_USER と同等です。
【関連する推奨事項】
以上がSQL インジェクションの例と SQL インジェクションを防ぐ方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。