🔐

安全なWebサイトを作ろう!①

2023/12/01に公開

ごあいさつ

こんにちは!
オアシステクノロジーズの古本です。

今日はWebアプリケーションを構築する上でめちゃめちゃ重要な「セキュリティ」に関する話題です。

まず、このページをみたことありますか?
https://ipa.go.jp/security/vuln/websecurity/index.html

IPAさんがまとめてくれているWebセキュリティーについての情報がまとまっているページです。

ありがたいっすね。

今日はこのなかの「安全なウェブサイトの作り方」を読み込んでいきましょう。
https://www.ipa.go.jp/security/vuln/websecurity/ug65p900000196e2-att/000017316.pdf

ウェブページのセキュリティ実装

SQLインジェクション

まずはSQLインジェクションから見ていきましょう。

セキュリティリスク

データベースと連携したウェブアプリケーションの多くは、利用者からの入力情報を基にSQL文(データベースへの命令文)を組み立てています。ここで、SQL文の組み立て方法に問題がある場合、攻撃によってデータベースの不正利用をまねく可能性があります。このような問題を「SQLインジェクションの脆弱性」と呼び、問題を悪用した攻撃を、「SQLインジェクション攻撃」と呼びます。

簡単に言うと、入力値を使ってユーザが自由にSQLを発行できるよ!ってことです。
たとえば以下のようなSQLを発行したい時

select * from users where email = 'xxx';

このemailにユーザの入力値をそのままつかっちゃだめだよ!ってことです。
たとえば、メールアドレスの入力フォームに以下のような文字列を入れてリクエストしたとします。

'; update users set password = '0000' where '1' = '1

そうすると、実行されるSQLはこうなるわけです。

select * from users where email = ''; update users set password = '0000' where '1' = '1';

もしこれが実行された時には、全てのユーザのパスワードが書き換わっちゃうことになりますよね。
こういう問題を適切にコントロールしようね!ってことです。

解決策としては以下の2点があります。

解決策

  1. SQL文の組み立ては全てプレースホルダで実装する。
    最近のDBだったら基本的に機能があるはずです。
    まず「こういうSQL」を発行するよ!ってDBに宣言して、そのあとに変数部分だけ変えたSQLを発行することによって、意図しないSQLの実行を防ぐ仕組みです。
    MySQLだとこのあたりに記述がありますね。
    https://dev.mysql.com/doc/refman/8.0/ja/sql-prepared-statements.html
    普段何気なくORマッパーが吸収してくれることがおおいですが、裏ではこういう仕組みを自動的に使ってくれてるんですね。

  2. SQL文の組み立てを文字列連結により行う場合は、エスケープ処理等を行うデータベースエンジンのAPIを用いて、SQL文のリテラルを正しく構成する。
    これは単純ですね。
    入力値に'みたいな構文が変わってしまう文字が含まれる場合に、適切にエスケープしてあげましょうってことです。
    これもORマッパーを利用していれば自動的にやってくれるケースが多いです。

結論

ORマッパーを使いましょう。

自分で文字列結合したSQLをORマッパーに依存しない形で発行しちゃだめよってことです。
とはいえ集計関数を利用したい場合など、どうしてもORマッパー任せにできないときもあると思います。
そういう場合は適切にエスケープしてあげることを忘れずに!

OSコマンド・インジェクション

次にOSコマンドインジェクションです。

セキュリティリスク

これもSQLインジェクションとほとんど同じです。
違う点はSQL発行じゃなくて、OSコマンド発行するっていう部分ですね。

プログラム上でこういうOSコマンドを発行している時

mv /var/www/storage/xxx/avatar.png /var/www/storage/xxx2/avatar.png

xxxにユーザの入力値を利用しているとして、以下のようなリクエストが来たとします。

 ./ ; cp /var/www/storage /var/www/public ;

そうすると以下のようなOSコマンドが発行されるわけです。

mv /var/www/storage/ ./ ; cp /var/www/storage /var/www/public ; /avatar.png /var/www/storage/xxx2/avatar.png

本来見えちゃいけない情報がpublic配下にコピーされることで誰でも見られるようにされちゃうようなパターンですね。
こういうことを防ぎたいわけです。

結論

これはもう先に結論を言っちゃいます

入力値を利用したOSコマンド発行することなんてほとんどない。設計を見直せ。

かれこれ10年以上基幹システム開発をやっていますが、入力値を使ってOSコマンドを発行するパターンに遭遇したことはありません。
ファイル管理方式にバグがあったり、業務処理設計にバグがあったり、実装上の回避策があると思います。

まとめ

特にコンシューマ向けのサービスなど、不特定多数が利用するシステムの場合には性悪説で考えてリスク管理することが重要です。
意外と知らない人が多かったので、他の章も継続してお勉強していこうと思います。

本日は以上!

Discussion