Web開発では、SQL注入は一般的な攻撃方法です。攻撃者は、悪意のあるコードをSQLクエリステートメントに挿入してデータベースを操作し、データを盗み、盗み、削除し、システムの許可を取得します。 SQL注入を防ぐために、PHP開発者はデータベースのセキュリティを保護するために効果的な対策を講じる必要があります。この記事では、SQL注入のリスクを回避するために、 REAL_QUERY関数を通じて安全なクエリを実行する方法を紹介します。
SQLインジェクションは、開発者がユーザー入力を適切に処理しない場合に発生するセキュリティの脆弱性です。攻撃者は、特別に作成されたSQLコードを入力して違法な操作を実現することにより、データベースクエリステートメントのロジックをタンピングします。一般的な攻撃方法は次のとおりです。
データベースで機密データを表示します
データを削除または変更します
認証をバイパスします
常にユーザーの入力を確認してクリーニングします。ユーザーが入力したすべてのデータには悪意のあるコンテンツが含まれている可能性があり、開発者はこのデータがSQLクエリに干渉できないことを確認するために入力をフィルタリングまたはエスケープする必要があります。
前処理ステートメントとパラメーターバインディングを使用します。前処理ステートメントは、SQLステートメントをユーザー入力から分離できます。これにより、SQLステートメントの構造に直接影響する悪意のある入力を回避できます。
データベースのユーザー許可を制限する:データベースアカウントには、データベースアカウントにあまりにも多くのアクセス許可が付与されないように、必要な操作を実行するための権限のみが必要です。
SQLクエリログの使用:SQLクエリログを記録および分析することにより、開発者は潜在的な悪意のある動作を発見およびブロックできます。
Real_Queryは、SQLクエリの実行に使用されるPHPのMySQLI拡張機能によって提供される関数です。元のSQLクエリを実行する必要がある場合、 Real_Queryを使用できますが、ユーザー入力が正しく処理されない場合、SQLインジェクションの脆弱性になる可能性もあります。したがって、 Real_Queryを使用する場合は、特に注意する必要があります。
<?php
$conn = new mysqli("localhost", "username", "password", "database");
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT * FROM users WHERE username = '".$_GET['username']."'";
if ($conn->real_query($sql)) {
$result = $conn->use_result();
while ($row = $result->fetch_assoc()) {
echo "Username: " . $row['username'];
}
}
?>
上記のコードでは、SQLクエリステートメントは、$ _get ['username']からのユーザー入力を直接使用します。ユーザーが「または1 = 1-などの悪意のあるSQLコードを入力すると、SQLインジェクション攻撃が発生します。したがって、 Real_Queryが実行される前に、ユーザー入力を処理する必要があります。
SQL注射を防ぐ最も効果的な方法の1つは、準備されたステートメントを使用することです。前処理ステートメントを通じて、SQLステートメントとデータが分離され、データベースエンジンはSQLコードに解析することなく通常の値としてデータを処理します。これは、PHPのMySQLI拡張機能を使用して簡単に実現できます。
<?php
$conn = new mysqli("localhost", "username", "password", "database");
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$stmt = $conn->prepare("SELECT * FROM users WHERE username = ?");
$stmt->bind_param("s", $_GET['username']);
if ($stmt->execute()) {
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo "Username: " . $row['username'];
}
}
?>
この例では、 prepare関数は最初にSQLクエリをコンパイルし、 bind_param関数はユーザー入力をクエリ( ? )のパラメーターにバインドします。このようにして、ユーザーが入力したデータは、SQLインジェクション攻撃を避けて、プレーンテキストとして処理されます。
Real_Queryを使用する必要がある場合は、ユーザー入力を手動でエスケープして、入力に悪意のあるコードが含まれていないことを確認するように注意する必要があります。 MySQLIは、文字列内の特殊文字を逃れるためにREAL_ESCAPE_STRING関数を提供します。
<?php
$conn = new mysqli("localhost", "username", "password", "database");
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$username = $conn->real_escape_string($_GET['username']);
$sql = "SELECT * FROM users WHERE username = '$username'";
if ($conn->real_query($sql)) {
$result = $conn->use_result();
while ($row = $result->fetch_assoc()) {
echo "Username: " . $row['username'];
}
}
?>
REAL_ESCAPE_STRINGを使用すると、ユーザー入力の特殊文字を逃れて、悪意のあるSQLコードが実行されないようにすることができます。このアプローチはSQL注入のリスクを減らすことができますが、完全に回避することはできないため、最初に前処理ステートメントを使用することをお勧めします。
Real_QueryおよびPreprocessingステートメントを使用することに加えて、SQL注入のリスクを減らすのに役立つ追加のセキュリティ対策があります。
PDOの使用(PHPデータオブジェクト) :PDOは前処理ステートメントもサポートしており、さまざまなデータベースに適したMySQLIよりも柔軟です。
データベースの許可を最小限に抑える:データベースユーザーが必要な操作を実行する権限のみを持っていることを確認し、データベースへのアクセスを制限し、攻撃者の潜在的な妨害能力を低下させます。
タイムリーな更新とパッチ:PHP、MySQL、およびサーバー環境を定期的に確認および更新して、すべてのセキュリティの脆弱性が固定されていることを確認します。
Webアプリケーションファイアウォール(WAF)を有効にする:WAFは、SQLインジェクションなどの攻撃を検出および傍受することができ、保護システムにとって重要な障壁です。
SQLインジェクションは最も一般的なWeb攻撃の1つであり、PHP開発者はデータベースのセキュリティを確保するために効果的な措置を講じる必要があります。 Real_QueryおよびPreprocessingステートメントを正しく使用することにより、SQL注入のリスクを効果的に防ぐことができます。さらに、開発者は、入力検証、データベース許可管理、セキュリティパッチの更新など、他のセキュリティ対策を組み合わせて、システムの全体的なセキュリティを強化する必要があります。
関連タグ:
SQL