SQLインジェクションは攻撃方法です。攻撃者は、悪意のあるSQLコードをSQLクエリに挿入することにより、データベースを操作して不正な操作を実行します。ステートメントを削除すると、攻撃者はSQLインジェクションを介して削除されるべきではないデータを削除し、データベーステーブル全体を削除して深刻なセキュリティリスクをもたらすことさえできます。
SQL注入を効果的に防ぐために、最も推奨されるアプローチは、準備されたステートメントを使用することです。 PHPは、MySQLデータベースと対話するときに使用されるMySQLIおよびPDO拡張機能を提供し、どちらも準備されたステートメントをサポートしています。このようにして、SQLクエリと入力ユーザーデータを分離できるため、悪意のある入力がSQLステートメントに注入されないようにします。
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-comment">// データベース接続</span></span><span>
</span><span><span class="hljs-variable">$mysqli</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">mysqli</span></span><span>(</span><span><span class="hljs-string">"localhost"</span></span><span>, </span><span><span class="hljs-string">"username"</span></span><span>, </span><span><span class="hljs-string">"password"</span></span><span>, </span><span><span class="hljs-string">"database_name"</span></span><span>);
</span><span><span class="hljs-comment">// 接続を確認してください</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$mysqli</span></span><span>->connect_error) {
</span><span><span class="hljs-keyword">die</span></span><span>(</span><span><span class="hljs-string">"Connection failed: "</span></span><span> . </span><span><span class="hljs-variable">$mysqli</span></span><span>->connect_error);
}
</span><span><span class="hljs-comment">// 削除するとしますIDユーザーに提供される値の記録</span></span><span>
</span><span><span class="hljs-variable">$user_id</span></span><span> = </span><span><span class="hljs-variable">$_GET</span></span><span>[</span><span><span class="hljs-string">'id'</span></span><span>]; </span><span><span class="hljs-comment">// からURLユーザーが提供するユーザーを取得しますID</span></span><span>
</span><span><span class="hljs-comment">// 準備されたステートメントを使用して防止しますSQL注射</span></span><span>
</span><span><span class="hljs-variable">$stmt</span></span><span> = </span><span><span class="hljs-variable">$mysqli</span></span><span>-></span><span><span class="hljs-title function_ invoke__">prepare</span></span><span>(</span><span><span class="hljs-string">"DELETE FROM users WHERE id = ?"</span></span><span>);
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">bind_param</span></span><span>(</span><span><span class="hljs-string">"i"</span></span><span>, </span><span><span class="hljs-variable">$user_id</span></span><span>); </span><span><span class="hljs-comment">// "i" パラメーターが整数型であることを示します</span></span><span>
</span><span><span class="hljs-comment">// 実行ステートメント</span></span><span>
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">execute</span></span><span>();
</span><span><span class="hljs-comment">// 削除が成功しているかどうかを確認してください</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$stmt</span></span><span>->affected_rows > </span><span><span class="hljs-number">0</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"レコードが削除されました。"</span></span><span>;
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"レコードは見つかりませんでしたか、削除が失敗しました。"</span></span><span>;
}
</span><span><span class="hljs-comment">// 接続を閉じます</span></span><span>
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">close</span></span><span>();
</span><span><span class="hljs-variable">$mysqli</span></span><span>-></span><span><span class="hljs-title function_ invoke__">close</span></span><span>();
</span><span><span class="hljs-meta">?></span></span><span>
</span></span>
上記のコードでは、 $ stmt-> bind_param()を使用して、ユーザーによるID入力をパラメーターとしてバインドすると、パラメーターが整数型であることを意味します。ユーザーが入力したIDはパラメーターとしてSQLステートメントに安全に渡され、SQLステートメントに直接埋め込まれないため、これによりSQLインジェクションを効果的に防ぐことができます。
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-keyword">try</span></span><span> {
</span><span><span class="hljs-comment">// データベース接続</span></span><span>
</span><span><span class="hljs-variable">$pdo</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">PDO</span></span><span>(</span><span><span class="hljs-string">'mysql:host=localhost;dbname=database_name'</span></span><span>, </span><span><span class="hljs-string">'username'</span></span><span>, </span><span><span class="hljs-string">'password'</span></span><span>);
</span><span><span class="hljs-variable">$pdo</span></span><span>-></span><span><span class="hljs-title function_ invoke__">setAttribute</span></span><span>(PDO::</span><span><span class="hljs-variable constant_">ATTR_ERRMODE</span></span><span>, PDO::</span><span><span class="hljs-variable constant_">ERRMODE_EXCEPTION</span></span><span>);
</span><span><span class="hljs-comment">// 削除するとしますIDユーザーに提供される値の記録</span></span><span>
</span><span><span class="hljs-variable">$user_id</span></span><span> = </span><span><span class="hljs-variable">$_GET</span></span><span>[</span><span><span class="hljs-string">'id'</span></span><span>]; </span><span><span class="hljs-comment">// からURLユーザーが提供するユーザーを取得しますID</span></span><span>
</span><span><span class="hljs-comment">// 準備されたステートメントを使用します</span></span><span>
</span><span><span class="hljs-variable">$stmt</span></span><span> = </span><span><span class="hljs-variable">$pdo</span></span><span>-></span><span><span class="hljs-title function_ invoke__">prepare</span></span><span>(</span><span><span class="hljs-string">"DELETE FROM users WHERE id = :id"</span></span><span>);
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">bindParam</span></span><span>(</span><span><span class="hljs-string">':id'</span></span><span>, </span><span><span class="hljs-variable">$user_id</span></span><span>, PDO::</span><span><span class="hljs-variable constant_">PARAM_INT</span></span><span>);
</span><span><span class="hljs-comment">// 実行ステートメント</span></span><span>
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">execute</span></span><span>();
</span><span><span class="hljs-comment">// 削除が成功しているかどうかを確認してください</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">rowCount</span></span><span>() > </span><span><span class="hljs-number">0</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"レコードが削除されました。"</span></span><span>;
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"レコードは見つかりませんでしたか、削除が失敗しました。"</span></span><span>;
}
} </span><span><span class="hljs-keyword">catch</span></span><span> (PDOException </span><span><span class="hljs-variable">$e</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"間違い: "</span></span><span> . </span><span><span class="hljs-variable">$e</span></span><span>-></span><span><span class="hljs-title function_ invoke__">getMessage</span></span><span>();
}
</span><span><span class="hljs-meta">?></span></span><span>
</span></span>
PDOでは、 BindParam()を使用して、ユーザーが入力したパラメーターをSQLステートメントにバインドし、 PDO :: PARAM_INTを介して整数タイプとしてそのタイプを指定します。これにより、SQL注入も防止されます。
準備されたステートメントの使用に加えて、別の効果的なセキュリティ保護は、ユーザー入力を検証およびフィルタリングすることです。削除操作、特にIDフィールドの場合、それが合法的な整数であることを確認する必要があります。
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-variable">$user_id</span></span><span> = </span><span><span class="hljs-variable">$_GET</span></span><span>[</span><span><span class="hljs-string">'id'</span></span><span>];
</span><span><span class="hljs-comment">// 入力が法的整数であることを確認します</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-title function_ invoke__">filter_var</span></span><span>(</span><span><span class="hljs-variable">$user_id</span></span><span>, FILTER_VALIDATE_INT)) {
</span><span><span class="hljs-keyword">die</span></span><span>(</span><span><span class="hljs-string">"無効なユーザーID"</span></span><span>);
}
</span><span><span class="hljs-comment">// データベース削除操作を実行します</span></span><span>
</span><span><span class="hljs-meta">?></span></span><span>
</span></span>
filter_var()関数を使用して、ユーザーが提供するIDが法的整数であるかどうかを確認します。そうでない場合、実行は直接停止します。この追加の検証は、セキュリティを改善することができます。
データベースと対話するときは、常に最小許可の原則に従ってください。データベースアカウントには、必要なアクションを実行する許可のみが必要です。たとえば、削除操作は、データベースアカウントに完全な権限を与えるのではなく、特定のデータベースアカウントのみを実行できるようにする必要があります。このように、たとえSQL注入の脆弱性が発生したとしても、攻撃者が実行できるアクションは制限されます。
潜在的なSQLインジェクション攻撃をタイムリーに検出するには、データベースのSQLロギング機能を有効にし、データベースを監視することをお勧めします。これは、攻撃が発生したときに異常な活動を追跡し、予防措置を講じるのに役立ちます。
最後に、PHP、データベース、および関連するすべてのコンポーネントを更新することは、セキュリティの脆弱性を防ぐための鍵です。すべてのシステムに最新のセキュリティパッチがロードされていることを確認するために、セキュリティ通知を頻繁に確認してください。
関連タグ:
SQL