1656069000
Webアプリケーションを扱う開発者は、自分たちが構築したものに害を及ぼす恐れのある多くのことを目にします。これらの一部には、人を標的とした攻撃(ソーシャルエンジニアリングなど)、これらの攻撃の一部(DoSまたはDDoS攻撃、クロスサイトスクリプティング、クロスサイトリクエストフォージェリ、認証の破損、機密データの漏洩、アクセス制御の破損、安全でない)が含まれます。デシリアライズなど)Webアプリケーションのターゲット部分。ただし、一部の攻撃は主にデータベースとそこに保存されているデータを標的としています。そのような攻撃の1つは、SQLインジェクション(略してSQLi)です。このブログ投稿では、このような攻撃が与える可能性のある影響について説明します。
SQLインジェクションは、Webアプリケーションを標的とすることが多い攻撃です。このような攻撃の目的は、データベースから機密データを盗み出し、攻撃者の個人的な利益のためにそれを使用することです。多くの開発者が公開されているWeb向けソリューションを作成する際のセキュリティの重要性を見落としているため、このような攻撃は非常に蔓延していて危険です。セキュリティギャップが見落とされると、悪意のある当事者がそれらを見つけて悪用することがよくあります。これらの悪意のある攻撃者は、侵害中に盗まれたデータを販売することで利益を得ることができるため、このような脆弱性を悪用します。
このような攻撃の影響は、Webアプリケーションによって異なります。アプリケーションが機密情報を保存していないと仮定します。その場合、攻撃は広範囲にわたる結果をもたらさない可能性があります。ただし、そうでない場合は、重大な問題が発生する可能性があります。機密データが盗まれて営利目的で売却され、パスワードのリセットや他の場所での情報の変更によるストレスにより、ビジネスに問題が発生したり、顧客に不必要な問題が発生したりする可能性があります。
SQLインジェクションの概念は非常に単純です。一部の開発者は、ユーザーが特定の入力フィールドに書き込んだすべてのものをクエリに入れてデータベースに渡すため、このような攻撃は機能します。脆弱なコードの基本的なスニペットは次のようになります($_POSTの代わりに$_GETを使用することもできます。前提は同じです)。
$Input = $_POST['input'];
SELECT * FROM demo_table WHERE column [= | < | > | <= | >= | LIKE ...] '$Input';
ご覧のとおり、場合によっては、脆弱なコードは非常に単純です(複雑になる可能性もあります。後でさまざまなシナリオに進みます)。このような脆弱なコードは、攻撃者が引用文字(')を頻繁に使用して悪用します。エラーを誘発します。エラーが発生すると、攻撃者はコードが脆弱であることを認識し、アプリケーションを攻撃する可能性があります。
SQLインジェクション攻撃に該当するカテゴリはいくつかあります。
攻撃者は、上記の各タイプを使用してさまざまな目標を達成します。攻撃者がシステムの内部動作について暗黙の知識を持っている場合は、従来のSQLインジェクションが役立ちます。攻撃者がカップルの結果を組み合わせる場合は、ユニオンベースのSQLインジェクションが役立ちます。ステートメントをSELECT
単一の結果セットにまとめる場合、アプリケーションが「サイレント」の場合にエラーベースのSQLインジェクションが使用されます(つまり、応答が返されないため、攻撃者は特定の種類のクエリを発行するときに機能の変更を探します)
この時点で、SQLインジェクションとは何か、そのタイプは何かをかなりよく理解しているはずですが、そのような攻撃からアプリケーションをどのように保護しますか?ありがたいことに、このような脆弱性が現在または将来悪用されるリスクを軽減するためのよく知られた方法がいくつかあります。
/* Prepare MySQL statement */
if (!($statement = $mysqli->prepare(
"SELECT customerID
FROM orders
WHERE item = ?"
))) {
echo "Failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
/*
Bind variables to statement as parameters using bind_param().
The type (first) parameter can take integers (i), doubles (d),
strings(s), and blobs (b).
*/
$purchasedItem = 'ice cream';
if (!$statement->bind_param("s", $purchasedItem)) {
echo "Failed: (" . $statement->errno . ") " . $statement->error;
}
/* Execute prepared MySQL statement */
if (!$statement->execute()) {
echo "Failed: (" . $statement->errno . ") " . $statement->error;
}
これらの点を念頭に置いておくと、アプリケーションがうまく機能し続けるのに役立ちます。
プリペアドステートメントの使用、MySQLが提供するセキュリティに重点を置いたプラグインの使用、不要な管理者権限の付与の回避、およびその他の前述の予防措置を考慮に入れることで、ユーザーとデータベースを適切なパスに置くことができます。ただし、MySQLをさらに深く掘り下げて、SQLクエリがそのように機能する理由と、たとえばWebアプリケーションファイアウォール(WAF)を使用することで、SQLインジェクションを含むさまざまな種類の攻撃から保護できる理由を理解したい場合は、次のことを検討してください。
SHOW PROFILE FOR QUERY [query id here];
正しく使用された場合、ほとんどの場合、出力はクエリの実行内容とタスクの期間を提供します。また、次のような質問への回答を得るなど、興味深いことをたくさん観察することもできます。
これらの質問に対する回答のいくつかは、SQLインジェクションがそのように機能する理由を理解するのに役立つ場合があります。たとえば、SHOW PROFILE FOR QUERY
クエリをもう一度発行すると、次のように表示されます。
クエリの出力の一部SHOW PROFILE FOR QUERY
マークされた行は、クエリの実行を開始した直後に、MySQLがアクセス許可をチェックすることを示しています。前に説明したことを覚えていますか?この理由から、不要な権限を正確に付与することは避けてください。攻撃者がターゲットにしているMySQLアカウントに十分な権限がない場合、クエリは失敗します。クエリの機能はSHOW PROFILE FOR QUERY
このブログ投稿の範囲に含まれていないため、ここではあまり詳しく説明しませんが、上記のアドバイスに従うことが重要である方法と理由を確認できます。
上で概説したアドバイスのほとんどは、データベーススペースにも当てはまります。
上記のアドバイスを考慮に入れてください。そうすれば、現在または将来データベースに影響を与える可能性のあるSQLインジェクションの問題を軽減するための道を進んでいるはずです。
お気づきかもしれませんが、SQLインジェクションからアプリケーションとデータベースを保護するのに役立つアドバイスのほとんどは、非常に一般的で簡単です。ただし、SQLインジェクションからデータベースを保護することも、ロケット科学ではありません。上記で概説したガイドラインを念頭に置いてください。
1656069000
Webアプリケーションを扱う開発者は、自分たちが構築したものに害を及ぼす恐れのある多くのことを目にします。これらの一部には、人を標的とした攻撃(ソーシャルエンジニアリングなど)、これらの攻撃の一部(DoSまたはDDoS攻撃、クロスサイトスクリプティング、クロスサイトリクエストフォージェリ、認証の破損、機密データの漏洩、アクセス制御の破損、安全でない)が含まれます。デシリアライズなど)Webアプリケーションのターゲット部分。ただし、一部の攻撃は主にデータベースとそこに保存されているデータを標的としています。そのような攻撃の1つは、SQLインジェクション(略してSQLi)です。このブログ投稿では、このような攻撃が与える可能性のある影響について説明します。
SQLインジェクションは、Webアプリケーションを標的とすることが多い攻撃です。このような攻撃の目的は、データベースから機密データを盗み出し、攻撃者の個人的な利益のためにそれを使用することです。多くの開発者が公開されているWeb向けソリューションを作成する際のセキュリティの重要性を見落としているため、このような攻撃は非常に蔓延していて危険です。セキュリティギャップが見落とされると、悪意のある当事者がそれらを見つけて悪用することがよくあります。これらの悪意のある攻撃者は、侵害中に盗まれたデータを販売することで利益を得ることができるため、このような脆弱性を悪用します。
このような攻撃の影響は、Webアプリケーションによって異なります。アプリケーションが機密情報を保存していないと仮定します。その場合、攻撃は広範囲にわたる結果をもたらさない可能性があります。ただし、そうでない場合は、重大な問題が発生する可能性があります。機密データが盗まれて営利目的で売却され、パスワードのリセットや他の場所での情報の変更によるストレスにより、ビジネスに問題が発生したり、顧客に不必要な問題が発生したりする可能性があります。
SQLインジェクションの概念は非常に単純です。一部の開発者は、ユーザーが特定の入力フィールドに書き込んだすべてのものをクエリに入れてデータベースに渡すため、このような攻撃は機能します。脆弱なコードの基本的なスニペットは次のようになります($_POSTの代わりに$_GETを使用することもできます。前提は同じです)。
$Input = $_POST['input'];
SELECT * FROM demo_table WHERE column [= | < | > | <= | >= | LIKE ...] '$Input';
ご覧のとおり、場合によっては、脆弱なコードは非常に単純です(複雑になる可能性もあります。後でさまざまなシナリオに進みます)。このような脆弱なコードは、攻撃者が引用文字(')を頻繁に使用して悪用します。エラーを誘発します。エラーが発生すると、攻撃者はコードが脆弱であることを認識し、アプリケーションを攻撃する可能性があります。
SQLインジェクション攻撃に該当するカテゴリはいくつかあります。
攻撃者は、上記の各タイプを使用してさまざまな目標を達成します。攻撃者がシステムの内部動作について暗黙の知識を持っている場合は、従来のSQLインジェクションが役立ちます。攻撃者がカップルの結果を組み合わせる場合は、ユニオンベースのSQLインジェクションが役立ちます。ステートメントをSELECT
単一の結果セットにまとめる場合、アプリケーションが「サイレント」の場合にエラーベースのSQLインジェクションが使用されます(つまり、応答が返されないため、攻撃者は特定の種類のクエリを発行するときに機能の変更を探します)
この時点で、SQLインジェクションとは何か、そのタイプは何かをかなりよく理解しているはずですが、そのような攻撃からアプリケーションをどのように保護しますか?ありがたいことに、このような脆弱性が現在または将来悪用されるリスクを軽減するためのよく知られた方法がいくつかあります。
/* Prepare MySQL statement */
if (!($statement = $mysqli->prepare(
"SELECT customerID
FROM orders
WHERE item = ?"
))) {
echo "Failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
/*
Bind variables to statement as parameters using bind_param().
The type (first) parameter can take integers (i), doubles (d),
strings(s), and blobs (b).
*/
$purchasedItem = 'ice cream';
if (!$statement->bind_param("s", $purchasedItem)) {
echo "Failed: (" . $statement->errno . ") " . $statement->error;
}
/* Execute prepared MySQL statement */
if (!$statement->execute()) {
echo "Failed: (" . $statement->errno . ") " . $statement->error;
}
これらの点を念頭に置いておくと、アプリケーションがうまく機能し続けるのに役立ちます。
プリペアドステートメントの使用、MySQLが提供するセキュリティに重点を置いたプラグインの使用、不要な管理者権限の付与の回避、およびその他の前述の予防措置を考慮に入れることで、ユーザーとデータベースを適切なパスに置くことができます。ただし、MySQLをさらに深く掘り下げて、SQLクエリがそのように機能する理由と、たとえばWebアプリケーションファイアウォール(WAF)を使用することで、SQLインジェクションを含むさまざまな種類の攻撃から保護できる理由を理解したい場合は、次のことを検討してください。
SHOW PROFILE FOR QUERY [query id here];
正しく使用された場合、ほとんどの場合、出力はクエリの実行内容とタスクの期間を提供します。また、次のような質問への回答を得るなど、興味深いことをたくさん観察することもできます。
これらの質問に対する回答のいくつかは、SQLインジェクションがそのように機能する理由を理解するのに役立つ場合があります。たとえば、SHOW PROFILE FOR QUERY
クエリをもう一度発行すると、次のように表示されます。
クエリの出力の一部SHOW PROFILE FOR QUERY
マークされた行は、クエリの実行を開始した直後に、MySQLがアクセス許可をチェックすることを示しています。前に説明したことを覚えていますか?この理由から、不要な権限を正確に付与することは避けてください。攻撃者がターゲットにしているMySQLアカウントに十分な権限がない場合、クエリは失敗します。クエリの機能はSHOW PROFILE FOR QUERY
このブログ投稿の範囲に含まれていないため、ここではあまり詳しく説明しませんが、上記のアドバイスに従うことが重要である方法と理由を確認できます。
上で概説したアドバイスのほとんどは、データベーススペースにも当てはまります。
上記のアドバイスを考慮に入れてください。そうすれば、現在または将来データベースに影響を与える可能性のあるSQLインジェクションの問題を軽減するための道を進んでいるはずです。
お気づきかもしれませんが、SQLインジェクションからアプリケーションとデータベースを保護するのに役立つアドバイスのほとんどは、非常に一般的で簡単です。ただし、SQLインジェクションからデータベースを保護することも、ロケット科学ではありません。上記で概説したガイドラインを念頭に置いてください。