【第1回】セキュリティワーキンググループの取り組みと、開発で気をつけたいセキュリティの話(前編)

こんにちは。
システムズのセキュリティワーキンググループ(以下、セキュリティWG)です。
最近、「○○社で情報漏えい」「Webサービスが不正アクセスで停止」といったニュースを見かけることが増えました。
とはいえ、いざ「セキュリティを意識して開発しましょう」と言われても、

  • どこから手を付ければいいのか分からない
  • 何をすると危ないのかイメージしづらい

と感じる方も多いと思います。
このコラムでは、

  • そもそもシステムのセキュリティは、何が怖いのか
  • 開発時に特に気をつけたい代表的な脆弱性はどんなものか
  • セキュリティWGがどんな取り組みをしているのか

を、あまり専門用語に寄りすぎない形でご紹介します。

前編となる今回は、「セキュリティリスクの怖さ」と「代表的な脆弱性(SQLインジェクション/OSコマンドインジェクション)」についてお話しします。

システムのセキュリティリスクは、なぜそんなに重要なのか

「ちょっとしたバグ」が会社全体の問題になることも

業務システムやWebアプリは、今や多くの企業で仕事の“インフラ”になっています。そのため、セキュリティ上の問題があると、影響も仕事全体に波及しやすくなります。
たとえば、

  • 顧客情報や社内の機密情報が外部に漏えいしてしまう
  • サービスが停止し、業務や取引が止まってしまう
  • お客様やパートナー企業からの信頼を失う

といった事態が起きる可能性があります。
一度トラブルが発生すると、

  • 原因調査
  • 関係者への説明・お詫び
  • セキュリティ対策の見直しと再発防止策の実施

などに、かなりの時間とコストがかかります。
「とりあえず動いているからOK」ではなく、「攻撃されるかもしれないことを前提に設計・実装する」ことが、いまのシステム開発では求められています。

セキュリティリスクにはどんなものがあるか

セキュリティリスクと一口に言っても、種類はさまざまです。代表的なものを、簡単にご紹介します。

不正アクセス
パスワードの総当たりや、ログイン処理の不備を突かれ、他人になりすましてシステムに入られてしまうパターンです。

アプリやミドルウェアの“すき間”を突く攻撃
いわゆる「脆弱性」を突いて、本来できないはずの操作をさせる攻撃です。このあと触れる「SQLインジェクション」「OSコマンドインジェクション」「XSS」などが代表例です。

設定ミス・運用ミス
クラウドのアクセス権限を緩く設定してしまったり、テスト用アカウントを削除し忘れていたりといった、“ちょっとしたミス”から情報漏えいにつながることもあります。

すべてのリスクを100%防ぐことは現実的ではありませんが、「どんな攻撃パターンがあるか」を知っておくだけでも、日々の設計・実装の中で意識しやすくなります。

開発時に特に気をつけたい 3つの脆弱性

ここからは、開発に関わる方なら「まずここは押さえておきたい」という代表的な脆弱性を、3つに絞ってご紹介します。

  • SQLインジェクション
  • OSコマンドインジェクション
  • クロスサイトスクリプティング(XSS)

細かい専門用語はなるべく控え、「何が起きるのか」「どう防ぐのか」に絞って説明します。
前編では、最初の2つを取り上げます。

SQLインジェクション

入力次第で、好きなSQLを実行されてしまう問題

SQLインジェクションは、ユーザーからの入力を悪用して、攻撃者に任意のSQLを実行されてしまう脆弱性です。たとえば、「ユーザーIDを入力して検索する画面」があり、その値を次のようにSQLへ埋め込んでいるとします。

ここに、普通の「user01」ではなく、’ OR ‘a’=’a’; のような文字列を入れられてしまうと、SQLが次のように変わってしまうことがあります。

‘a’=’a’ は常に真なので、ユーザー情報が全部取れてしまう…といった危険があります。

どう防ぐか(ポイント)
対策の考え方は、とてもシンプルです。

外部からの入力を、そのままSQLの文字列に埋め込まない。
具体的には、次のような方法があります。

プリペアドステートメント(Prepared Statement)を使う
SQLの中に、? や :id といった「プレースホルダ」を書き、実行時にその部分だけ値を渡す方法です。多くの言語・フレームワークがこの仕組みを提供しており、特殊文字の扱いも自動的に安全な形で処理してくれます。

入力チェックと無害化(バリデーション/サニタイズ)

  • 数値だけ入るはずの項目に、文字や記号が入っていないか確認する
  • 長さや文字の種類が明らかにおかしいものは受け付けない
  • 必要に応じて、専用のエスケープ関数で特殊文字を処理する

といった形で、「そもそも怪しい入力を通さない」ようにします。

万が一に備えた“保険”の対策

  • データベースユーザーの権限を最小限にする(例:参照だけのアカウント)
  • SQLエラーの内容をそのまま画面に表示しない(テーブル名などを知られないようにする)

など、もし攻撃されても被害を広げない工夫も重要です。

覚えておきたいキーワードは、「SQL文の中に直接変数を書かない」「文字列連結でSQLを組み立てない」 です。

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

サーバに勝手にコマンドを打ち込まれるイメージの攻撃

OSコマンドインジェクションは、アプリケーションを経由して、サーバ上で任意のコマンドを実行されてしまう脆弱性です。

アプリの中で、例えば、

  • メール送信
  • ファイルのコピーや圧縮

などを、「OSのコマンド」を呼び出して実現しているケースがあります。その際、ユーザー入力をチェックせずにそのままコマンドに渡してしまうと、攻撃者が仕込んだコマンドまで一緒に実行されてしまう恐れがあります。

イメージとしては、次のような流れです。

  • メールアドレスの入力欄に
    test@example.com”; cat /etc/passwd” のような文字列を入力される
  • その値を、シェルのコマンド文字列にそのまま連結して実行してしまう
  • 結果として cat /etc/passwd も一緒に実行され、
    サーバ上の重要なファイルの内容が表示されてしまう

どう防ぐか(ポイント)
できるだけ「何でもできるコマンド実行関数」を使わない
可能な限り、言語やフレームワークが用意している

  • ファイル操作用の関数
  • メール送信用のAPI

など、「用途が決まっている専用の機能」を使うことが、安全で確実です。

どうしてもコマンドを使う必要がある場合

  • コマンドと引数を配列で渡せるAPIを使い、文字列連結で1本のコマンドを組み立てない
  • 引数は「この一覧の中からだけ選べる」といった ホワイトリスト方式 にする

ことで、予期しないコマンドが紛れ込む余地を減らします。

実行権限を絞っておく

  • コマンドを実行するOSユーザーに、不要な権限を与えない
  • もし侵入されても、できることを限定しておく

といった形で、「最悪の事態」を小さく抑えることも大切です。

SQLインジェクションと同じく、「外部から来た文字列を、そのまま“強力な機能”に渡さない」 という考え方が基本になります。

次回の後編では、3つ目の脆弱性である「クロスサイトスクリプティング(XSS)」と、セキュリティWGの具体的な活動内容(ツール導入・勉強会など)についてご紹介します。