オンプレからクラウドへ、モノリシックなアプリからコンテナ・マイクロサービスへ、アプリケーションを支える技術は日々進化しており、最新技術を活用してDXやモダナイゼーションを実現し、マーケットニーズに応えるアプリを迅速にリリースすることが求められています。そのために、すべてのエンジニアが様々なツールを使いこなし、企業のビジネスを支えています。
そのような中、いつの時代でも重要な課題であるセキュリティ、今回は新たな視点で「開発エンジニアのセキュリティ意識を向上させる方法」について、お話させて頂きます。
セキュアコーディングとWAF
皆さまがブラウザのリンクをクリックして、コンテンツが画面に表示されるまで、どのようなセキュリティ機能が動作しているかご存知でしょうか。
エンドポイントセキュリティ、ネットワークセキュリティ、サーバサイドセキュリティ、様々なセキュリティ機能が動作していますが、ここではアプリに向かって最後に動作する2つのセキュリティ機能である「セキュアコーディング」「WAF」について考えてみます。
セキュアコーディング:開発するアプリケーション内のコードで、例えば入力文字列をチェック(バリデーションチェック)したり、文字列を無害化するためのサニタイズを行ったり、と様々な脅威に対して開発エンジニア自身が対策を行う方法がセキュアコーディングです。
単純な攻撃に対してはセキュアコーディングで充分であり、脆弱性診断ツールも多々あるので、うまく活用することで「強い」アプリケーションの開発は可能だと考えています。
しかし時には大きな変更を伴う開発が必要な場合もあります。例えばリスト型攻撃に対してコーディングで解決する場合、最終アクセス時間、指定期間でのアクセス回数、アクセス元のIPアドレス、etc、を管理するためのDB等が必要であり、コーディングだけで解決することが難しくなってきます。また最新のゼロデイ攻撃に対しての対応等、高度な攻撃に対応することは非常に難しい状況です。
そこで、セキュアコーディングでカバーしきれない攻撃に対してWAFを活用することになります。
WAF:上述のとおり、セキュアコーディングでカバーしきれない高度な攻撃、代表的なものではOWASP TOP10の脅威等に対する対策がWAFです。アプリケーションの手前に配置され、シグネチャ等チューニングを行うことで攻撃を防ぐことができます。
すべてのアプリケーションでWAFが必要という訳ではありませんが、アプリケーションがよりリッチになるにつれて扱う情報や重要度が増してきている今日では、多くのアプリケーションがWAFを必要としています。
このセキュアコーディングとWAFですが、上述のとおり補完関係にあります。ただし多くの企業にとって、セキュアコーディングを行うエンジニアとWAFを扱うエンジニアは異なっています。
モダナイゼーションにより開発エンジニアのカバーする領域が拡大
モノリシックなアプリケーションの時代、開発エンジニアは指定されたミドルウェア・DB等で動作するアプリケーションの開発に注力していたかと思います。開発エンジニアはバグを減らすため、工数を削減するために共通モジュールを開発したり、コード自動生成の仕組みを利用したり、一方でサーバエンジニアやネットワークエンジニアが足回りの構築を・・・という状況が一般的であったのではないでしょうか。
しかしクラウドやKubernetesの出現により、開発エンジニアがカバーする領域が変化してきています。今まではサーバ・ネットワークエンジニアの領域であった作業も「Infrastructure as Code」によりコード化され、Kubernetesのリソースファイルで管理することが可能となり、CI/CDツールを活用してアプリケーションをデプロイするサイクル含めて開発エンジニアが行うことができる領域となってきています。(だからと言ってサーバ・ネットワークエンジニアが楽になった訳ではありません。Kubernetesを支えるより複雑なネットワーク、マルチクラウド設計等、内容は変わってきていますが非常に高度で大変な作業なのです。)
セキュリティについてはいかがでしょうか。一朝一夕で高度な専門知識を持ったセキュリティエンジニアが育つわけもなく、セキュリティエンジニアにかかる期待や負担は増す一方です。そこで企業は「開発エンジニアのセキュリティ意識を向上させる方法」を模索し、セキュリティエンジニアと開発エンジニアのシームレスな連携環境を準備し、すべての脅威に対して迅速に対応したいと考えています。
DevSecOps、Security as Code等開発エンジニアがセキュリティを意識するための技術・環境は整っている状況で、どのような方法で開発エンジニアの意識を向上させることができるのでしょうか。
セキュアコーディングツールとしてのWAF
Kubernetesで開発を行う場合、各PodをServiceでまとめて公開し、Ingress ControllerによりL7 LBを実現、サービスタイプにNodePortやLoadBalancerを指定して、サービスを公開する方法が一般的かと思います。

このIngress Controllerとして多くのエンジニアに利用されているのがNGINXとなります。そしてNGINX App Protectというモジュールを使うことで、WAF機能を搭載したIngress Controllerを利用することができるようになります。

※こちら、AUDI様の事例もご参照ください。
OpenShift上でNGINX Ingress ControllerとApp Protectを活用した事例となります。
Kubernetes環境でWAFを導入する場合、一般的にはKubernetes環境の手前にWAF装置を設置するかWAFaaSを利用する方式になると思いますが、NIGNX App ProtectをNGINX Ingress ControllerにアドオンすることによりKubernetesリソースとしてWAFを扱えるようになります。つまり、開発エンジニアがカバーする領域にWAFが入って来ることになります。
※こちら、IDCフロンティア様の事例発表もご参照ください。
KubernetesのリソースファイルでNGINX App Protectを扱うサンプル等含まれています。
開発エンジニアがWAFを扱うためには新たな学習コストが必要にはなりますが、WAFだからといって特別なフォーマットで特別な設定があるわけではありません。慣れ親しんだNGINXの設定ファイルからWAF機能をオンにし、JSONやYAML形式でシグネチャのチューニングが行なえます。

※こちら、マニュアルもご参照ください。
セキュリティポリシーをKubernetesリソースとして管理できることで「セキュアコーディングのツール」としてWAFを扱うことができるようになります。開発エンジニア自らが開発を行うアプリケーションにKubernetesリソースファイルの開発を加え、カバー領域を広げることでセキュアコーディングのモダナイゼーションを実現することができるのです。
開発エンジニアのセキュリティ意識の向上へ
冒頭で提起した「開発エンジニアのセキュリティ意識を向上させる方法」ですが、上述のとおり「セキュアコーディングのツールとしてWAFを活用する」ことです。
開発エンジニアにとって新たな学習コストが発生するものの、世の中にどういった攻撃があるのか、どのようなシグネチャがあって、どういう仕組みで防いでいるのか、そういったノウハウを身に付けてセキュアコーディングを行うことで、よりセキュリティレベルを高める事ができます。
また、今まで実際のコーディングで行っていたセキュリティ対策も、WAFの活用で工数削減を行い、コーディング量が減ることでレビューやテスト工数も削減できます。
セキュリティエンジニアの視点では、WAFのチューニングのたびに開発エンジニアとの調整が必要でしたが、これからは多くの工程を開発エンジニアが対応することができるようになります。
高度な攻撃に対し、セキュリティエンジニアがリスク・影響範囲・ガバナンスなどの観点から評価を行い、セキュリティ・開発エンジニア双方が同じダッシュボードを見て状況を把握します。そしてセキュリティエンジニアが作成するガイドラインやアドバイスのもと開発エンジニアが自身でチューニング・本番環境への適用を実施することができるようになります。
例えばLog4jの脆弱性に対して、セキュリティエンジニアがすべてのアプリケーションの状況を把握して対策するのではなく、セキュリティエンジニアはガイドラインを作成し、それに従って開発エンジニア自身が対策を実施する仕組みができれば、今後アプリケーションが増加・複雑化しても、セキュリティエンジニアの負担増を最小限に抑えることができます。
セキュリティエンジニアと開発エンジニアが共通のツール(WAF)を通してセキュリティ対策に取り組むことで、開発エンジニア自身のセキュリティ意識を向上させることができるのです。

「うちのエンジニアは全員WAFをセキュアコーディングツールとして使っているよ」
セキュリティに強い企業として、その価値をアピールできるメッセージではないでしょうか。開発エンジニアのセキュリティ意識向上が企業価値向上に直結するのです。また開発エンジニアにとっても、新たな強力な武器(WAF)を手に入れることで、いつの時代でも最も重要なスキルである「セキュリティ」を身につけ、マーケットで一つ抜き出た高い価値を持つエンジニアとなります。
開発エンジニアの皆さま、ご自身のスキルアップのためにも、ぜひモダンな「セキュアコーディング」をご検討ください。