関わっているプロジェクトで脆弱性診断を受けていた時に、スタックスマッシング攻撃に対する脆弱性が指摘されるという報告があり、現在対処法を検討するうことになったのだが、これはSwiftで開発したアプリでは珍しいことであるということもわかった。この記事では、スタックスマッシング攻撃について、およびその対策法等について書いてみたい。
スタックスマッシング攻撃およびStack Smashing Protectionとは
スタックスマッシング攻撃とは、スタック領域(ローカル変数や返り値などを格納する領域)のメモリー領域において、一定サイズ以上で上書きすると、扱えるサイズをこえてしまい(バッファーオーバーフロー。スタック領域であればスタックオーバーフロー)、スタック上のデータが破壊されてしまって、異常な動作の原因となる脆弱性のことで、これによってセキュリティー上懸念になることが考えられる。
その対策として、スタック領域にcanaryと呼ばれる特殊な値を使って管理、それが意図せず書き換えられたらスタックオーバーフローを検知したと判断して強制終了させるというメカニズムでセキュリティーを確保しようという仕組みが作られている。それがStack Smashing Protection (SSP)と呼ばれる。
SSPが有効かどうかを確認する
任意のアプリでSSPが有効かどうかを判断するには、端末上のアプリパッケージ(*.app)のディレクトリー内の実行ファイルのある場所で、 otool -Iv (アプリ実行ファイル名) | grep stack
コマンドで確認すれば良い。 ___stack_chk_guard
および ___stack_chk_fail
などが確認できれば、SSPが有効になっていることが確認できる。
(4/27追記)ただし、この方法が有効なのはObjective-Cで書かれたコードが含まれている場合に限られる。___stack_chk_guard
および ___stack_chk_fail
などはObjective-Cにのみ依存するもののようで、Swiftのみのコードからビルドされた場合は含まれないようである。
Swiftのアプリでは通常はSSPは有効となる
なお、このSSPは、Swiftで開発されたアプリでは既定で有効となるものであり、通常は明示的にSSPを有効にする必要はないものである。したがって、Swiftのアプリプロジェクトにおいては、特に対応する必要はないと言える。これでもしSSPが無効になっているとしたら、Objective-Cアプリとして扱われているか、何らかの理由で無効になっていることが考えられる。(4/27追記)上述の理由により、Objective-Cのコードが含まれていなければSSPが有効になっていることを確認できるシンボルは含まれない模様。
SSPはコンパイルオプションで有効化できる
一方で、Objective-Cで開発されたアプリではそうなっておらず、Xcodeのプロジェクト設定で有効化する必要がある。とはいえ、通常はSSPを有効化するのは決して難しいことではなく、アプリプロジェクト(またはターゲット)の「Other C Flags」に -fstack-protector-all
フラグを付与すれば良いというものである。(4/27追記)このオプションはCやObjective-Cに依存するものであるため、純粋なSwiftアプリではそもそも対応は不要である。
最後に
今回は脆弱性診断で指摘の上がったものであり、自身でもまだ理解できているわけではないが、セキュリティーを考えると、問題になる可能性は否定できないものであるものと判断したため、できるなら対処しておきたいものであると考えている。特に分野によっては是非とも対応したいものである。とはいえ、どういう時にSmash Smashing Protectionが有効になったり無効になったりするのかがいまいちわからない状態なため、今は調査が必要ではあるのだが・・・。
ウェブマスター。本ブログでITを中心にいろいろな情報や意見などを提供しています。主にスマートフォン向けアプリやウェブアプリの開発を携わっています。ご用の方はコメントかコンタクトフォームにて。