プログラミング言語の脆弱性対策を考える

Share

プログラミング言語のセキュリティは、組織のシステム全体のセキュリティに大きな影響を与えます。「アプリケーションの脆弱性の半数はC/C++に起因する」という報告もあり、プログラミング言語における脆弱性の特徴を理解し、適切な対策を講じることは、いまや組織のセキュリティに不可欠な取り組みといえます。本記事では、プログラミング言語の最新動向、脆弱性が生まれる背景を解説します。

プログラミング言語のトレンド

言語 使用している
開発者の比率
JavaScript69.7%
HTML/CSS 62.4%
SQL 56.9%
Python 41.6%
Java 38.4%
Bash/Shell/PowerShell 34.8%
C# 32.3%
TypeScript 28.3%
PHP 25.8%
C++20.5%
C 18.2%
Go 9.4%
Kotlin8.0%
言語 使用している
開発者の比率
Ruby7.5%
VBA6.2%
Swift6.1%
R5.5%
Assembly4.9%
Rust4.8%
Objective-C4.4%
Scala3.9%
Dart3.7%
Perl3.3%
Haskell1.8%
Julia0.9%

Stack Overflow Developer Survey 2020 より弊社作成
https://insights.stackoverflow.com/survey/2020#technology-programming-scripting-and-markup-languages-professional-developers

JavaScript、HTML/CSS、SQLなどが上位に並んでいますが、皆さんの予想どおりでしょうか?ちなみに冒頭で述べた、「脆弱性の半数」を生み出すとされるC/C++に関しては、昨今IoTデバイスなどの組込機器やデスクトップアプリケーション等に利用目的が収れんしてきているといわれ、その使用率は減少傾向にあります。また、リストには記載がありませんが、日本に限ってみると、COBOLなどのレガシーシステム向けの言語がいまだ根強いシェアを保っているのはご存じの方も多いことでしょう。

なお、弊社での診断傾向としては、JavaScriptのほか、Pythonが目立っています。今後については、「オーバーヘッドが少なく、静的型付け言語である」という特徴をもつTypeScriptなどが、軽量さの望まれるサーバレス環境での需要につながるものとみられます。また、Android端末向けにKotlinの需要も高まると予測しています。以下、ご参考に、プログラミング言語と主な利用分野のマッピングを示します。

図:主要プログラミング言語と現在利用されている代表的分野

プログラミング言語の脆弱性 ― 言語ごとに異なる特徴を知る

プログラミング言語の脆弱性を考える場合、特定の言語に固有のものと、言語間で共通のものを押さえておく必要があります。

例えば、C/C++では、その脆弱性の7割がメモリハンドリングのミスに起因するといわれており、メモリ関連処理のロジックを正しく制御させ、ソースコード内に脆弱性を作りこまないようにすることが、重要なセキュリティ対策となります。そのほか、言語固有の脆弱性として代表的なものは、Javaでの「安全でない入力に対するデシリアライゼーション」の問題、JavaScriptでの「パストラバーサル」や「暗号」の問題、PHPでの「クロスサイトスクリプティング(XSS)」や「SQLインジェクション」などになります。

なお、2000年代後半以降にリリース開始された比較的新しいプログラミング言語(Kotlin、Golang、Rustなど)については、上記とは若干が異なる観点からの注意が必要です。まず、こうした言語では、セキュアコーディングのための様々な関数やライブラリなどが用意され、セキュリティに関する手厚い対策が組み込まれているのですが、その一方で、セキュリティの機能が増えれば増えるほど関連ドキュメントが膨大になり、把握が追いつかないという課題が生じています。例えば、Kotlinの場合、Kotlin自体のドキュメンテーションではセキュリティ関連の記述はNULLの安全性に触れる程度なのですが、セキュアコーディングに取り組もうとすると、膨大なAndroid Developer Guideを参照する必要があります。また、相互運用性への配慮も必要です。例えばKotlinやGolangはJavaと一緒に利用するケースが多いため、こうした言語で開発を行う場合には、Java側の環境を考慮したうえでのセキュアコーディングが不可欠になり、それが開発の難易度を押し上げているという状況があります。

プログラミング言語の脆弱性 ― 全言語に共通の特徴を知る

続いては、すべての言語に共通する脆弱性です。これは大きく以下の3つに分類できます。

情報漏洩
・表示する必要のない機微な情報(ユーザ名やIDなど)の露呈
・不要なシステム情報の公開
入力検証の不備
・不正なパラメータの許容、XSS、SQLインジェクション
・HTTPヘッダ分割
認可・認証関連の脆弱性
・オブジェクトやファイルなどへのアクセス認可の不備
・認証情報の保護機構や暗号化の不備

脆弱性が発生する背景

以上述べてきたような脆弱性は、なぜ発生するのでしょう。その背景には、開発現場における以下のような課題があると考えられます。

・プロジェクトベースで人員が変わることが多く、知識や経験の共有が行われることがまれ
・脆弱性やセキュアコーディングに対する意識、知識レベルがプログラマによって異なる
・ギリギリのスケジュールでプロジェクトが進むことが多く、知識や経験の共有まで手が回らない
・セキュリティへの対応が明示的な業務として遂行されるのではなく、プログラマやプロジェクトメンバー1人1人の善意に依存する面が強い

具体例で説明しましょう。先ほど、PHPではXSSやSQLインジェクション等の脆弱性がよく見られると述べました。しかし、PHPでも、バージョン4以降であれば「htmlspecialcharacters」という関数を利用することでXSSの回避に必要な特殊文字のエスケープ処理ができます。SQLインジェクションについても、プレースホルダの利用による回避が可能です。このように、すでに対策が存在する場合であっても、プログラマ間で知識や経験の共有が行われていない場合、ソースコード診断やステージング環境でのWebアプリケーション脆弱性診断が実施されない限り、脆弱性は放置されることになります。また、「機微な情報の露呈」という問題については、個人情報保護などの法制度に対する知識が共有されておらず、そもそも課題として認識されていないという可能性があります。なお、知識共有のハードルは、セキュリティ機能が充実しているゆえに把握すべき情報量が膨大で、他の言語との互換性等まで含めた配慮が求められる最近のプログラミング言語では、さらに高いといえるでしょう。

こうした課題を解決するには、プログラマ個人の知識・技術レベルを高めることはもちろんですが、それ以上に重要なのは、組織を挙げての体系的な取り組みであるといえます。

先手を打った対処がカギ

そこでぜひ取り入れたいのが、プログラミング言語に関わる脆弱性が生じていないかを、開発の初期段階から継続的に点検する取り組みです。これは「DevSecOps」とも呼ばれる考え方で、「開発(Dev)」・「運用(Ops)」に「セキュリティ(Sec)」の観点を組み込むことで、システムのセキュリティ強化を図るものです。開発プロジェクトは常に時間との闘いですが、だからといって脆弱性への対応を先送りしてはなりません。対処が事後になればなるほど、影響範囲が広がり、コストも肥大する恐れがあります。

以前の記事でも解説しましたが、何よりも、初期段階からの取り組みが重要です。例えば、人員の流動が激しいプロジェクトベースの現場では、開発の早期からソースコード診断を含むテスト活動を実施し、脆弱性をコード単位で効率的に解消していくことによって、各段階で積み上げられた知識や経験を、後続の工程で活用することが可能になります。また、近年主流になっているアジャイル型の開発手法でもこれは有効で、短い開発サイクルが繰り返される中で早期に・こまめにテストや修正を行うようにすることで、セキュリティを強化できるのみならず、プロジェクト全体の工数も抑制できます。なお、短いサイクルでテストを回すには、SaaSタイプのソースコード診断サービスの利用を検討してもよいでしょう。

先手を打って脆弱性に対処できれば、脆弱性の要因となっていた様々な課題に取り組む余裕も生まれます。結果として、セキュリティと開発効率をともに高められる好循環を実現できるのではないでしょうか。



Share