ホームページ  >  記事  >  データベース  >  SQL インジェクションを 1 分で理解できます

SQL インジェクションを 1 分で理解できます

醉折花枝作酒筹
醉折花枝作酒筹転載
2021-08-02 16:01:222026ブラウズ

Web フォームの送信に SQL コマンドを挿入したり、ページ リクエストのドメイン名やクエリ文字列を入力したりすることで、最終的にはサーバーをだまして悪意のある SQL コマンドを実行させることができます。具体的には、既存のアプリケーションを使用して、バックグラウンドのデータベース エンジンに (悪意のある) SQL コマンドを挿入して実行し、セキュリティの脆弱性のある Web サイト上のデータベースを取得します。

SQL インジェクションを 1 分で理解できます

SQL インジェクション (SQL インジェクション) は、実際にはコードの脆弱性を利用して SQL のセマンティクスを変更し、それによって悪意のある SQL ステートメントを形成することです。

$username = $_POST['username'];
$password = $_POST['password'];

$query = "select * from users where username = '{$username}' and password = '{$password}'";

// 判断是否登录成功
if (DB::select($query)) {
    return true;
}

return false;

概要この疑似コードでは、アカウントのパスワードが正しいかどうかを確認し、正しければ true を返し、ログインを許可します。ただし、受信ユーザー名が 123' または 1=1;#\ の場合、SQL ステートメントは

select * from users where username = '123' or 1=1;
# and password = '{$password}'";

になります。1=1

であるため、この悪意のある SQL ステートメントはいつでも true を返します。 ORM によるインジェクション

SQL インジェクションはコードの脆弱性を利用して SQL のセマンティクスを変更すると前述しましたが、これは ORM も潜在的なインジェクション ポイントであることを意味します。 tp3.2 を例にとると、次のコードがあります。

$result = D('User')->where([
    'username' => $_POST['username'],
    'password' => $_POST['password'],
]);

if ($result) {
    echo '登录成功';
} else {
    echo '登录失败';
}

このコードは問題がないようですが、ユーザー名が username[0]=neq&username[1]=1111 で渡される場合、これはクエリですステートメントは

$result = D('User')->where([
    'username' => ['neq', 111],
    'password' => $_POST['password'],
]);

となり、$result の結果は常に true になります

回避方法

  • 受信パラメータのデータ型とデータ型を判断します変換

  • エスケープ引用符、PHP では addlashes、mysql_real_escape_string およびその他の関数を使用できます

  • ステートメントの前処理、SQL インジェクションを防ぐ最も効果的な方法

  • コード監査

プリペアド ステートメントが SQL インジェクションを防ぐ方法

プリペアド ステートメントはデータベースによって実装されます。たとえば、MySQL はプリペアド ステートメントを実装します。発言。まず、前処理の基本プロセスについて説明します

  • #MySQL は前処理 SQL テンプレートを受け取り、すぐに解析 (字句および構文) を開始します

  • 顧客最後にデータを送信して SQL テンプレートのプレースホルダー (?) を置き換えます

  • MySQL がステートメントを実行し、結果を返します

  • 前処理ステートメント (オプション)

では、プリペアド ステートメントはどのようにして SQL インジェクションを防ぐのでしょうか?まず、いわゆる SQL インジェクションとは、SQL のセマンティクスを強制的に変更することです。ステップ 1 で、ステートメントが処理され、SQL のセマンティクスが修正されました。ステップ 2 でプレースホルダーを置き換えても、SQL のセマンティクスは変更されません。以下は PHP PDO の例です。

$stmt = $pdo->prepare("select * from users where username = '?' and password = '?'");

$stmt->execute("123' or 1=1;#", 'test');

関連する推奨事項: "

mysql チュートリアル "

以上がSQL インジェクションを 1 分で理解できますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。