Aikido

JavaScriptによるSQLインジェクション攻撃の検知と阻止

マッケンジー・ジャクソンマッケンジー・ジャクソン
|
#
#

なぜここに?

JavaScriptによるSQLインジェクション攻撃について耳にしたことはあるだろうが、実際にどのようなものなのか、そもそも心配する必要があるのか、まったくわからない。もしかしたら、それがどの程度悪いものなのか把握しようとしているかもしれない。

要するに、MySQLやPostgreSQLのようなSQLデータベースを使用してアプリケーションを構築している場合、あなたは危険にさらされているのです。開発者としては、ユーザーデータを保護するガードレールを実装し、基礎となるインフラが決して侵入されたり、探索されたり、徴用されたりしないようにする責任があります。

新しいツールはすべて、あなたを助けると言っているが、開発をより複雑にしているだけだ。

Sequelizeや TypeORMの ようなオブジェクトリレーショナルマッパー(ORM)を追加することで、MySQLやPostgreSQLのようなSQLデータベースでの作業を簡素化することはできるが、リスクを完全に回避できるわけではない。ウェブアプリケーションファイアウォール(WAF)は、ネットワークレベルでの攻撃をブロックするのに役立つが、高価なインフラと継続的なメンテナンスが必要だ。コードスキャナー(Code Scanner)は、明らかな欠陥を特定するのに役立つが、未知の未知数や潜んでいるゼロデイテクニックに対しては、ほとんど役に立たない。

SQLインジェクション攻撃がどのようなもので、どのようなリスクがあり、どのような開発ミスがSQLインジェクション攻撃を可能にしているのかを明確に説明します。そして、グローバルなHotfixのインストール方法を説明することで、お客様のアプリが安全であることを確実にお伝えします。

SQLインジェクション攻撃の例とその影響

SQLインジェクション攻撃の最も基本的な定義は、アプリがデータベースクエリを実行するために、検証もサニタイズもされていないユーザー入力を許可することで、攻撃者がSQLデータベースを読んだり、レコードを変更したり、思いのままに削除したりできるようにすることです。

いつものように、XKCDはSQLの危険性を、私たちが夢見るような暗いシナリオよりもうまく説明している:

有名なコミック「ボビー・テーブル」は、JavaScriptによるSQLインジェクション攻撃の可能性を示している。
タイプキャプション(オプション)

脆弱なJavaScriptアプリはどのようなものか?

簡単な擬似コードの例から始めましょう。ユーザーが猫のデータベースを検索できる入力要素を持つJavaScriptアプリです。以下のJavaScriptコード例では、アプリは/catsパスのPOSTリクエストに応答して、リクエストボディからユーザー入力を抽出し、一致するidを持つすべての猫を返すクエリでデータベースに接続します。そして、アプリはJSONレスポンスを使って猫を表示します。

app.post("/cats", (request, response) => {
	const query = `SELECT * FROM cats WHERE id = ${request.body.id}`;
	connection.query(query, (err, rows) => {
    	if(err) throw err;
        response.json({
        	data: rows
		});  
	});
});


この例はSQLインジェクション攻撃の訓練を受けていない人には無害に見えるかもしれませんが、非常に脆弱です。特筆すべきは、このアプリは潜在的に危険な文字列やエンコーディング方法について、ユーザー入力を検証したりサニタイズしたりしようとせず、ユーザー入力をSQLクエリに直接連結していることです。

JavaScriptのSQL攻撃ペイロードの例

SQLインジェクションは、アプリがSQLクエリを生成する方法によって、MySQLやPostgreSQLデータベースを騙してアクションを起こさせたり、想定外のデータで応答させたりすることにかかっています。

会社情報 1=1は常に真 攻撃は、アポストロフィや引用符のようなトリックを使って、猫の表全体を返すことができる。 1=1 は確かに常に 本当だ:

  • ユーザーは入力する: ボビー・テーブル'または1='1
  • データベースはSQLクエリを実行する: SELECT * FROM Users WHERE Cat = BOBBY TABLES OR 1=1;

同様に、攻撃者は = は常に真である というのも、すべての猫を返せという攻撃だからだ。 ""="" は常に 本当だ:

  • ユーザーは入力する: "OR ""=""
  • データベースはSQLクエリを実行する: SELECT * FROM Cats WHERE CatId ="" または ""="";

攻撃者はしばしば、データベースがインラインコメントをどのように扱うかを悪用し、コメント (/* ... */) をクエリに入れることで、意図を難読化したり、フィルタを迂回したりすることができる。

  • ユーザーは入力する: DR/*hello world*/OP/*sneak attack*/ TABLE Cats;
  • データベースはSQLクエリを実行する: DROP TABLE Cats;

これは、攻撃者に無害な文字列で開始させ、セミコロン(;)を使ってそのステートメントを終了させ、インジェクションを含む別のステートメントを開始させるものです攻撃者はクエリスタッキングを使って、DROP TABLEコマンドでデータベース全体を一挙に削除することがよくあります:

  • ユーザーは入力する: ボビー; DROP TABLE キャッツ--。
  • アプリはSQLクエリーを構築する: const query = "SELECT * FROM Cats WHERE CatId = " + input;
  • データベースはSQLクエリを実行する: SELECT * FROM Cats WHERE CatId = BOBBY; DROP TABLE Cats;

NoSQLインジェクション攻撃についてはどうだろうか?

NoSQLインジェクション攻撃は、アプリとユーザーデータのセキュリティにとって同様に危険だが、MongoDBのようなデータベースを使用する技術スタックにのみ影響する。SQLとNoSQLのクエリはまったく独自の構文を使用するため、一方のカテゴリーから他方のカテゴリーに変換することはできません。

SQLデータベースを使用していれば、NoSQLインジェクション攻撃のリスクはない。

基本的な方法:SQLインジェクションの脆弱性をすべて手動で修正する。

この時点では、可能性のあるインジェクションのトリックがどのようなものかにはあまり興味がなく、MySQL や PostgreSQL にあるデータをどのように保護するかに関心があるかもしれません。

  • パラメータ化されたクエリを使用する:SQLにはクエリと値の実行を切断する機能があり、インジェクション攻撃からデータベースを保護します。上記のJavaScript/Node.jsの例では、SQLクエリにクエスチョンマーク(?).その connection.query() メソッドは第2引数にパラメータを取り、インジェクション防止メソッドと同じ結果を提供する。
app.post("/cats", (request, response) => {  
	const query = `SELECT * FROM Cats WHERE id = ?`;  
    const value = request.body.id;  
    connection.query(query, value, (err, rows) => {    
    	if(err) throw err;    
        response.json({      
        	data: rows    
		});  
	});
});

  • ユーザー入力の検証とサニタイズ:パラメータ化されたクエリは、SQLデータベースを侵入や攻撃から保護するのに役立ちますが、ユーザーが潜在的に危険な文字列をアプリケーションに入力するのを防ぐこともできます。

    サニタイズとバリデーションのためのオープンソースのライブラリをアプリに追加するのも一つの方法だ。例えば バリデータ.js JavaScript/Node.jsエコシステムにおいて、ユーザーがサインアップフォームにSQLインジェクション攻撃ではなく、本物のメールアドレスを入力しようとしていることをダブルチェックする。

    同じような作業を行うために、正規表現ベースのカスタムバリデータを開発することもできますが、調査や膨大な手作業によるテストなど、膨大な時間と複雑な道のりが待ち受けています。さらに、この正規表現例を本当にEメールバリデーションのために解釈できるでしょうか?

    const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

    のような文字列を防ぐのにも同じ考え方が適用される。 ...' OR 1-'1. このような機会をすべて自分で調査し、潰していくこともできるが、それよりも新機能の構築に時間を費やした方がいいだろう。

  • WAFやエージェントベースのセキュリティ・プラットフォームを導入する

    第一に、高価であることが多く、オンプレミスまたはクラウド上に新しいインフラを立ち上げる必要がある。第二に、ルールセットを更新するために手作業によるメンテナンスが必要になり、SQLインジェクションに対する他の手作業による介入から注意をそらすことになる。最後に、計算負荷が増えたり、分析のためにすべてのリクエストを自社のプラットフォーム経由でリダイレクトすることで、待ち時間が増え、エンドユーザー・エクスペリエンスが損なわれることがよくある。

大きな問題は、SQLインジェクション攻撃の機会は雑草のようなものであることだ。これらのツールを使えば一度はすべて刈り取ることができるが、二度と芽が出ないようにコードベース全体を常に警戒しなければならない。

JavaScript SQLインジェクション攻撃を解決する代替手法:Aikido

Aikido 最近、無料かつオープンソースのセキュリティエンジン「Firewall」をリリースしました。これはSQLインジェクション攻撃から自動で保護するだけでなく、さらに多くの機能を備えています。

Node.jsを使用していない場合、私たちは将来的に他の言語やフレームワークのサポートを開始する予定です。FirewallがJavaScriptの世界を超えて拡大する正確な情報を得るために、いつでも製品ニュースレターを購読することができますし、特定の言語を売り込みたい場合はhello@aikido.devまでメールしてください。

JavaSciptのSQLインジェクションに脆弱なアプリのテスト

オープンソースリポジトリに同梱されているサンプルアプリを使って、Aikido 動作を実演しましょう。ローカルMySQLデータベースをデプロイするには、Docker/Docker Composeも必要です。

まず、firewall-nodeリポジトリをフォークし、そのフォークをローカルのワークステーションにクローンします。

git clone https://github.com/<YOUR-GITHUB-USERNAME>/firewall-node.gitcd firewall-node


Dockerを使用して、ポート27015でローカルMySQLデータベースをデプロイします。このdocker-compose.ymlファイルは、s3mock、MongoDB、PostgreSQLコンテナも作成します。これは、Aikido ファイアウォールが様々な攻撃をどのようにブロックするかテストするのを支援するために作成されました。

docker-compose -f sample-apps/docker-compose.yml up -d


次に、サンプルアプリを起動します:

node sample-apps/express-mysql2/app.js


オープン http://localhost:4000 をブラウザで開いて、とてもシンプルな猫アプリをチェックしよう。テキストエリアに猫の名前をいくつか入力して 追加 ボタンをクリックします。SQLインジェクションをテストするには テスト噴射 リンクをクリックするか、テキストエリアに以下を入力してください: キティ'); DELETE FROM cats;-- H をクリックしてください。 追加 もう一度。いずれにせよ、このアプリを使えば、複数のクエリーをまとめて、卑劣なクエリーコメントを使って、ネコのデータベース全体を削除することができる。

どうしてこうなるのか?先に警告したように、このアプリは単に いずれも SQLクエリの最後にユーザー入力を入力するが、これは本質的に安全ではない。

const query = `INSERT INTO cats(petname) VALUES ('${name}');`


ここでの結果は小さいかもしれないが、このしばしば起こる正直なミスが、本番アプリに悲惨な結果をもたらすことは想像に難くない。

Aikido JavaScript SQLインジェクションのブロック

では、私たちのオープンソースのセキュリティ・エンジンが、あなたのコードにあるデータベースのやり取りをすべて手作業で修正することなく、JavaScriptのSQLインジェクション攻撃をどれだけ素早くブロックするか見てみましょう。

まだAikido をお持ちでない場合は、ぜひ 無料で作る.すでにお持ちの場合は、ログインして GitHubアカウントに接続するその過程で、Aikido あなたのフォークを読み取るAikido 許可してください。 ファイアウォールノード プロジェクトに参加している。

に行く。 ファイアウォール・ダッシュボード をクリックし、Add Serviceをクリックします。サービス名を付け、再度、フォークを選択して ファイアウォールノード プロジェクトに参加している。

JavaScriptのSQLインジェクション攻撃から保護するために、Node.jsプロジェクトにファイアウォールを追加する。
タイプキャプション(オプション)

Aikido Aikido インストールと実装方法を指導します。サンプルアプリを使用しているため、この作業は既に完了していますが、JavaScript SQLインジェクション攻撃の脆弱性がある可能性のあるすべてのNode.jsアプリに、このオープンソースのセキュリティエンジンを導入する方法についての有益な参考資料となります。

タイプキャプション(オプション)

をクリックする。 トークンの生成 Aikido ブロックしたSQLインジェクション攻撃に関する情報をAikido 安全に送信するためのトークンを作成するボタンです。生成されたトークン(先頭が AIK_RUNTIME...そしてターミナルに戻ってサンプルアプリを再実行する:

AIKIDO_TOKEN=<YOUR-AIKIDO-TOKEN> AIKIDO_DEBUG=true AIKIDO_BLOCKING=true node sample-apps/express-mysql2/app.js


オープン ローカルホスト:4000 そして再び、組み込まれたSQLインジェクション攻撃を実行します。今回はAikido ブラウザレベルでブロックAikido 、ローカルWebサーバーのログに出力するとともに、新たなイベントを生成します。そのイベントをクリックすると、ペイロードやアプリが危険なSQLクエリを生成した箇所など、SQLインジェクションの試みに関する詳細な情報を確認できます。

JavaScriptによるSQLインジェクション攻撃をブロックするファイアウォールの例。
タイプキャプション(オプション)

JavaScript SQLインジェクション攻撃(既知の重大な脅威から未確認の攻撃まで)を永久に防御することに悩む代わりに、Aikido 包括的なブロック機能と高度な可視化機能を提供します。これにより、攻撃元、一般的なペイロード、潜在的な脆弱性について常に把握できます。

次はどうする?

すべてのNode.jsベースのアプリケーションにAikido 無料でインストール・実装できます。当社のオープンソース組み込みセキュリティエンジンは、JavaScript SQLインジェクション攻撃、コマンドインジェクション、プロトタイプ汚染、パストラバーサルなど(近日追加予定)からインフラストラクチャとユーザーデータを保護します。

Firewall が SQL インジェクションから守るための開発のベストプラクティス(パラメータ化されたクエリを使 うとか、ユーザの入力を信用しないとか)に取って代わるべきだと言っているわけではありません。コードベースに欠陥はなく、正直な間違いは常に起こります。

FirewallはSQLインジェクションのグローバルな修正プログラムだと思ってください。カスタム開発された正規表現、レイテンシーを誘発するWAF、あるいは高額な費用がかかる複雑なセキュリティ・エージェントとは異なり、Firewallはこの1つの仕事を非常にうまく、しかも影響はごくわずかで、完全に無料で行うことができる。

もし気に入っていただけたなら、ロードマップをご覧いただき、GitHub リポジトリ(https://github.com/AikidoSec/firewall-node) に星をつけてください。⭐

4.7/5

今すぐソフトウェアを保護しましょう

無料で始める
CC不要
デモを予約する
データは共有されない - 読み取り専用アクセス - CC不要

今すぐ安全を確保しましょう

コード、クラウド、ランタイムを1つの中央システムでセキュアに。
脆弱性を迅速に発見し、自動的に修正。

クレジットカードは不要。