SQLインジェクション(安全なウェブサイトの作り方)

前回、携帯ウェブ向けのサイトにおける注意点までで、「安全なウェブサイトの作り方」を読み終えた気になってた。
けど、一つ忘れている。

SQLインジェクションを飛ばしている。

安全なウェブサイトの作り方では、一番に「SQLインジェクション」について説明されている。
しかし、IPAから「安全なSQLの呼び出し方」が公開されていることを考えて、最後に回したのである。

今回で「安全なウェブサイトの作り方」のSQLインジェクションを学び、次回より「安全なSQLの呼び出し方」を読み進める。
ラストとか言ってごめんなさい。

1.SQLインジェクションとは

安全なウェブサイトの作り方より。

SQL文の組み立て方法に問題がある場合、攻撃によってデータベースの不正利用をまねく可能性があります。このような問題を「SQLインジェクションの脆弱性」と呼び、問題を悪用した攻撃を、「SQLインジェクション攻撃」と呼びます。

インジェクションとは「注入」という意味。
つまり、不正な文を SQLに注入するから SQLインジェクションと呼ぶ。

これで起こりうる脅威の例は以下。
・個人情報の漏洩
・データベースの情報の改ざん・消去
・認証回避による不正ログインなど。

注意が必要なサイトは、DBを使用しているサイト全て。

2.SQLインジェクションの対策

とりあえず、安全なウェブサイトの作り方に示されている解決策を見ていく。

SQL文の組み立てはすべてプレースホルダで実装する

SQL には通常、プレースホルダを用いてSQL 文を組み立てる仕組みがあります。SQL 文の雛形の 中に変数の場所を示す記号(プレースホルダ)を置いて、後に、そこに実際の値を機械的な処理で割り 当てるものです。

プレースホルダとは、SQL文の雛形の中の変数が入る予定の場所のこと、またはその場所を示す記号や識別氏のこと。
そのプレースホルダに実際の値を割り当てることをバインドと呼ぶ。

通常の文字列連結処理で生成する SQL文に比べて、プレースホルダでは機械的に SQL文が組み立てられるので、SQLインジェクションの脆弱性を回避できる。

バインドにも2種類ある。
・静的バインド:プレースホルダのままSQLをコンパイルし、DB側で値を割り当てる
・動的バインド:アプリケーション側で値をエスケープし、プレースホルダへはめこむ

SQLインジェクションの脆弱性がなくなるのは静的バインドのほう。

SQL文の組み立てを文字列連結により行う場合は、エスケープ処理などを行うデータベースエンジンのAPIを用いてSQL文のリテラルを正しく構成する

SQL 文の組み立てを文字列連結により行う場合は、SQL 文中で可変となる値をリテラル(定数)の 形で埋め込みます。値を文字列型として埋め込む場合は、値をシングルクォートで囲んで記述します が、その際に文字列リテラル内で特別な意味を持つ記号文字をエスケープ処理します(たとえば、「’」 →「”」、「\」→「\\」等)。

基本はプレースホルダだけど、どうしても使えない場合は文字列連結しかない。
そんなときは SQL文中で可変となる値をエスケープ処理して定数(リテラル)で埋め込むこと。

リテラルの例えとして、文字列ならシングルクォートで囲むこと。
数値なら数値リテラルであることを確実にする処理をはさむこと。

この処理は、SQL文を構成する全てのリテラルに対して行なう。

ウェブアプリケーションに渡されるパラメータに SQL文を直接指定しない

これは、いわば「論外」の実装ですが、hidden パラメータ等にSQL 文をそのまま指定するという事例 の届出がありましたので、避けるべき実装として紹介します。

すごいな・・・時代を感じる。
でも、なんにも知識がなかったらやってしまってたのかもな、自分も。
だから、勉強する。

以下、保険的対策。

エラーメッセージをそのままブラウザに表示しない

エラーメッセージの内容に、データベースの種類やエラーの原因、実行エラーを起こしたSQL 文等 の情報が含まれる場合、これらはSQL インジェクション攻撃につながる有用な情報となりえます。また、 エラーメッセージは、攻撃の手がかりを与えるだけでなく、実際に攻撃された結果を表示する情報源と して悪用される場合があります。

どちらかというと Apacheなどの Webサーバの設定になるのだろうか。

ステージングサーバなどと本番環境との出力するエラーレベルを考えておく。

データベースアカウントに適切な権限を与える

ウェブアプリケーションがデータベースに接続する際に使用するアカウントの権限が必要以上に高い場合、攻撃による被害が深刻化する恐れがあります。ウェブアプリケーションからデータベースに渡す命令文を洗い出し、その命令文の実行に必要な最小限の権限をデータベースアカウントに与えてください。

MySQLやphpMyAdminを使用する場合、最初からある rootを使わないほうがいい。
なんでもできてしまうため、乗っ取られたら終わる。

制限付きのユーザで処理を行なおう。
被害が最小限に抑えられる。

以上、安全なウェブサイトの作り方よりSQLインジェクションについてでした。
ただ、詳しくは「安全なSQLの呼び出し方」を参照ください、とちょくちょく書かれてたので、次はこれを進めていく。

参考

安全なウェブサイトの作り方

コメント

タイトルとURLをコピーしました