TQLインジェクションの紹介

はじめに

アプリケーションやウェブサイトから機密データを抽出する方法として、最も古く、最も成功している方法の1つに、SQL インジェクションと呼ばれる方法があります。SQLインジェクションとは、悪意のあるアクターが脆弱なウェブサイトで実行して、個人情報や貴重な情報を抽出するためのSQL文のことです。

今回のブログでは、TQLインジェクションとは何か、どうやって防御するのかについて説明します。TQLはSQLとよく似ているので、ここで紹介する教訓やテクニックは、他のコードインジェクション攻撃に対する一般的なガイドラインとして活用できるかもしれません。

SQL・TQLインジェクション

TQLインジェクション攻撃がどのようなものかを示すために、以下の例を見てみましょう。

tql="select * where id='"+user_input+"'"
    col.query(tql)

ウェブサイトやアプリは、ユーザの入力を受けてDBに問い合わせ、ユーザーのユーザー名を調べるという、一見何の問題もないように見えます。しかし、悪意ある者が「12」に等しいユーザー入力を行ったとすると、実行されるクエリは次のようになります。

select * where id='12'

まだ何も壊れていませんが、ユーザーは入力ボックスに何を入力してもよいので、12' OR id LIKE '%'のように入力することもできてしまいます。

select * where id='12' OR id LIKE '%'

このクエリは、開発担当者が何の防御もせずに実行することができるため、悪意のある攻撃者が、通常ではアクセスできない大量の情報をデータベースから取得することができてしまいます。

選択可能なソリューション

様々な方法でこの種のインジェクション攻撃を防御することができますが、このブログでは、パラメータ化、コンテナ化、入力のサニタイズ、URLデータのエンコードに焦点を当てて説明します。

パラメータ化する

パラメータ化するとは、「特定のプロセスや活動の範囲を定義する制限や境界」を設定することです。今回の方法では、JDBCとそのGridDB JDBCコネクタを利用します。ここでは、JDBCの準備されたステートメントを利用して大切なデータを保護することを考えています。

query = "select * from data where id = '"+user_input+"';
    rs = stmt.executeQuery(query);
query = "select * from data where id = ?"';
    PreparedStatement stmt = con.prepareStatement()
    updateSales.setString(1, user_input);
    rs = stmt.executeQuery();

この例では、ユーザーが上記のような悪意のあるワイルドカードを入力しようとした場合、実行されたステートメントは貴重なデータではなくエラーを返すことになります。これは、開発担当者が任意のSQL文ではなく、与えられた型を設定しているからです。

コンテナ化する

この例では、GridDBのコンテナアーキテクチャを利用して、データを適切に保護することができます。

col = gridstore.get_container("sensor_12") 

例えばこの場合は、適切なデータを返します。

col = gridstore.get_container("sensor_12' OR id LIKE '%")

しかし、ユーザーが上記の例を悪意のあるワイルドカードとして行った場合、そのコンテナは存在しないため、単にエラーを返します。シンプルで非常に効果的ですが、少し制限が生じてしまうことは確かです。

入力をサニタイズする

インジェクション攻撃に対抗するために最もよく使われる方法は、入力のエスケーピングまたはサニタイズです。これは、特別な意味を持つ文字をエスケープすることで機能します。

sanitized_input=re.sub("\"", "\\\"", re.sub( "\'", "\\\'",user_input))
    sanitized_tql="select * where id='"+sanitized_input+"'"

この例では、すべてのユーザーの入力がサニタイズされ、不要な入力や発言がないようにクリーニングされます。

URL エンコーディング

最後に紹介するのは、URLエンコーディングです。通常、この種の保護方法は、HTTP POSTメソッド、リクエストを使用するデータフォームに適用されます。これは、すべての入力がデータベースに送信される前にエンコードされ、基本的なインジェクション攻撃に使用される可能性のある特殊文字(先ほどのワイルドカードのようなもの)がすべて取り除かれるというものです。

tql="select * where id='"+user_input+"'"
    sanitized_input = urllib.parse.quote(user_input)
    sanitized_tql="select * where id='"+sanitized_input+"'"

上の例では、ユーザーの入力を実行して問い合わせをする前に、まずデータをエンコードしていることがわかります。

まとめ

今回はTQL・SQL インジェクション攻撃に対する対策をいくつかご紹介しましたが、攻撃の方法も、攻撃を防ぐ方法も、どちらも他にも数多くあります。常にセキュリティを考慮してアプリケーションを開発するようにしてください。

ブログの内容について疑問や質問がある場合は Q&A サイトである Stack Overflow に質問を投稿しましょう。 GridDB 開発者やエンジニアから速やかな回答が得られるようにするためにも "griddb" タグをつけることをお忘れなく。 https://stackoverflow.com/questions/ask?tags=griddb

Leave a Reply

Your email address will not be published. Required fields are marked *