試してみませんか?
JavaScript セキュリティ
JavaScript の脆弱性とベストプラクティスについて
他のプログラミング言語と同様に、JavaScript にもセキュリティ上の危険性がないわけではありません。JavaScript の脆弱性を利用すると、データの操作、セッションのリダイレクト、データの変更や盗用など、さまざまなことが可能になります。JavaScript は通常、クライアント側のアプリケーションと考えられていますが、JavaScript のセキュリティの問題は、サーバー側の環境でも問題を引き起こす可能性があります。
よくある JavaScript のセキュリティ脆弱性に対する最善の防御策は、脆弱性を認識することと、適切な対策を講じて脆弱性を低減させることです。
2023 年の Javascript のセキュリティ脆弱性
JavaScript の代表的な脆弱性としては、クロスサイトスクリプティング (XSS)、悪意のあるコード、中間者攻撃、Web アプリケーションのソースコードの脆弱性の悪用などが挙げられます。これらは、開発時にコードの脆弱性をスキャンし、開発者にセキュリティに関する教育を行うことで防ぐことができます。
この記事では、最も一般的な JavaScript の脆弱性と、テストツール (例: 監査やコード分析ツール、JavaScript 脆弱性スキャナ、など) と組み合わせた一般的な最新のセキュリティアプローチによってそれらを防止する方法を見ていきます。
JavaScript のセキュリティとは
JavaScript のセキュリティとは、JavaScript を使用するアプリケーションのセキュリティ問題について調査し、予防し、保護し、解決することを意味しています。
JavaScript 自体は、Web アプリケーションの開発における基本的なテクノロジーで、サーバー側、デスクトップ、さらにはモバイルアプリケーションの開発でも非常に人気があります。ただし、広く普及していることで、ハッカーにとっては格好の標的となり、さまざまな攻撃ベクトルで狙われています。JavaScript は主にフロントエンドで使用されるため、最初にブラウザーの JavaScript のセキュリティ問題に注目することは有益です。
ソフトウェアベンダーもこのような JavaScript のセキュリティ問題を認識しているため、JavaScript セキュリティスキャンソフトウェアや、アプリケーションの安全性を高めて JavaScript セキュリティリスクを大幅に軽減するさまざまな JavaScript セキュリティ テストツールに対応しています。コードの脆弱性を見つけるJavaScript コードチェッカーをお試しください。
JavaScript のよくある脆弱性について
主な JavaScript 攻撃手段は、悪意のあるスクリプトの実行、ユーザーが確立したセッションデータやブラウザーのローカルストレージからのデータの盗用、ユーザーの意図しないアクションの実行、Web アプリケーションのソースコードの脆弱性の悪用などです。
もちろん、これで全部というわけではありません。ここで挙げたものは主に Web アプリケーションのフロントエンド側で発生します。
8 JavaScript セキュリティの脆弱性
1.ソースコードの脆弱性
多くの場合、ソースコードの脆弱性は、他の (いくつかの) JavaScript のセキュリティホールと組み合わされます。残念ながら、このような場合、単独で JavaScript の難読化を行っても、これらのタイプの脆弱性を防止したり隠したりすることはできません。JavaScript はコンパイル言語ではなくインタプリター言語であるため、この方法では潜在的なハッカーによる調査から、アプリケーションコードを保護することは事実上不可能です。それでも、難読化はハッカーによるリバースエンジニアリングの試行を遅らせる点で良いプラクティスであると言えます。
また、ソースコードにセキュリティホールが発生する原因として、公開されているパッケージやライブラリが普及していることが挙げられます。NPM は、JavaScript エコシステムの主要なプレーヤーで、そのレジストリには 100 万を超えるパッケージが登録されています。種類が多いことは確かにメリットですが、同時に Web アプリケーションプロジェクトにインストールされるパッケージには、膨大な数の隠れた脆弱性が存在する可能性があることを意味します。
また、開発者は簡単なタスクでもパッケージをインストールすることが多いため、プロジェクトの依存関係が拡大してしまいます。もちろん、これによりセキュリティの問題や他の広範囲に及ぶ結果が生じる可能性があります。
アプリケーション依存の潜在的な脆弱性をすべてモニタリングして対処するのに時間と労力がかかるとはいえ、監査ツールがあれば、そのプロセスを自動化して加速させることができます。
ソースコードに含まれる JavaScript のセキュリティ問題を防止するための多面的なアプローチには、以下のものが含まれます。
開発者のベストプラクティスに対する意識向上
潜在的な脆弱性を検出するアプリケーションコードの適切な監査
コードが期待通りに動作するだけでなく、安全に実行されることを保証する単体テストの開発
アプリケーションを動的にスキャンし、サードパーティパッケージやライブラリに含まれる JavaScript のセキュリティ問題を特定するツールの導入
2.意図しないスクリプトの実行
意図しないスクリプトを実行する攻撃の大半は、クロスサイトスクリプティング (XSS) が関係しています。JavaScript に関連して特に問題となるのは、Web ページ上のドキュメントオブジェクトモデル (DOM) とやり取りする方法です。これにより、Web 上のクライアントコンピュータにスクリプトを埋め込んで実行できるようになります。このように、XSS 攻撃にはいくつかの種類がありますが、共通しているのは、ユーザーのブラウザーに信頼できないスクリプトを表示して、実行させるという点です。
最も基本的な XSS 攻撃のシナリオの一つは、ユーザーが同じページで互いのメッセージを見ることができる、掲示板型の Web サイトでよく見られるものです。HTML や JavaScript が適切にエンコードされていない場合、悪意のあるユーザーがスクリプトを掲示板に書き込めるようになっている可能性があります。
このようなスクリプトを投稿すると、悪意のあるコードが Web ページの一部に見えるアプリケーションを実行するだけで、すべてのエンドユーザーが意図せずに攻撃を助長する被害者になってしまいます。
XSS 攻撃を防ぐために、開発者は、サーバーからのユーザー入出力を処理する際に、サニタイズ (文字列データのエスケープ、フィルター処理、および検証の組み合わせ) を適用する必要があります。
3.ユーザー入力のエスケープ/エンコード
XSS 攻撃は、Web ページの基礎となる HTML、JavaScript、CSS で使用される特定の特殊文字を含むデータの入力に依存しています。ブラウザーで Web ページのレンダリング時にこれらの文字を検出すると、表示する値としてではなく、Web ページのコードの一部と認識されてしまいます。これにより、ハッカーはテキストフィールドから抜け出し、ブラウザー側のコードを入力して追加し、実行させることができます。
これを防ぐには、ブラウザーから入力するデータに応答を返す際はいつでも (即時反映か、データベースからの取得に関わらず)、特殊文字を対応するエスケープコードに置き換える必要があります。
たとえば、
HTML エンティティの区切りに使用される < and > 文字を
< and > に置き換えることで、HTML エンティティとして解釈するのではなく、それらの文字を表示するようにブラウザーに指示できます。ブラウザーから入力されるデータが JavaScript のコンテキストで返される場合、英数字以外の文字は、NN が文字の 16 進数の ASCII 値である xNN を使用してエスケープする必要があります。
4.フィルタリング入力
場合によっては、入力されたデータから危険な文字を削除することが望ましいこともあります。これはある程度の保護になるとはいえ、データ操作からの保護はこの方法だけに頼ることはできません。このようなフィルターを回避するため、ハッカーは様々なテクニックを駆使しています。
5.入力の検証
可能な限り、ブラウザー入力を検証して、想定される文字のみが含まれていることを確認する必要があります。たとえば、電話番号のフィールドには、数字と、ダッシュまたは括弧文字のみを含められるようにします。想定されるセット以外の文字が含まれる入力は、ただちに拒否する必要があります。これらのフィルターでは入力可能な文字を探し、それ以外はすべて拒否するように設定します。
6.クライアント側の検証のみの依存
上記で説明した方法はすべて良い方法であり、ブラウザーでうまく機能するとはいえ、ハッカーは特別なツールを使って直接サーバーにデータを送信し、クライアント側の検証を回避することがあります。これにより、悪意のあるデータや未検証のデータがサーバーに侵入する可能性があります。サーバー側の追加の検証を行わないと、保存されたデータが破損したり、誤ったデータに置き換えられたりする可能性があります。
このようなシナリオを防ぐベストプラクティスとしては、クライアント側とサーバー側の両方に検証を実装することを推奨します。この方法で、不正なデータのリスクを減らすと同時に、エンドユーザーの結果を改善する検証機能をクライアント側で提供できます。
サーバー側の検証のみだと、すべての検証に通る前にオンラインフォームに複数回入力しなければならない事態が発生し、ユーザーが煩わしく思うかもしれません。JavaScript の検証では、ユーザーが入力した内容に問題があった場合にすぐに通知できます。一方、サーバー側の検証により、想定されるデータのみをアプリケーションに送信できます。
7.セッションデータの盗用
クライアント側のブラウザースクリプトは、Web アプリケーションからブラウザーに返されるすべてのコンテンツにアクセスできるという点で、非常に強力です。これにはユーザーのセッション ID など、機密データを含む可能性のある Cookie が含まれます。実際、XSS 攻撃のよくある手段として、ユーザーのセッション ID トークンをハッカーに送り、セッションを乗っ取るというものがあります。
これを防ぐため、現在ではほとんどのブラウザーが Cookie の Http-Only 属性に対応しています。サーバーがブラウザーに Cookie を設定する際、Http-Only 属性を設定することで、DOM から Cookie へのアクセスを許可しないようブラウザーに指示します。これにより、クライアント側のスクリプトベースの攻撃から、これらの Cookie に保存されている機密データへのアクセスを防ぐことができます。
ローカルストレージやセッションストレージのブラウザーデータも同じように盗まれる可能性がありますが、DOM アクセスで安全を確保することはできません。したがって、Web アプリケーションのアーキテクチャの特定の機能で必要とされる場合を除き、トークンのような機密情報をブラウザーのストレージに保存することは避けたほうがよいでしょう。
8.ユーザーに意図しないアクションを実行させる
クロスサイトリクエストフォージェリー (CSRF) 攻撃は、ユーザーがすでにログインしている Web サイトに対して、その時点では実際にそのサイトを開いていなくても、ブラウザーを騙して不正なリクエストを実行させようとするものです。対象サイトのセッションが Cookie ベースの場合、そのサイトへのリクエストは認証 Cookie で自動的に強化されることがあります。
ハッカーが独自の Web ページを実装し、ユーザーがそれを開いたときにバックグラウンドで他のサイトに対して悪意のあるリクエストを実行させることもあります。また、ソーシャルメディアやフォーラム、プラットフォームなどを利用して、悪意のあるリンクやその他のコンテンツを投稿し、ユーザーのセッション Cookie を利用して、ブラウザーに気づかれないように他のサイトへの呼び出しを行わせることもあります。
この脆弱性を回避するための一般的な手法として、クライアントとサーバーの通信にトークン化を実装し、Cookie に保存されていない追加のトークンを導入する方法があります。トークンは、セッション確立時に Web サイト上の各フォームに対して生成し、ユーザーが Web サイトにいる間にリクエストごとに一緒に送信します。
JavaScript のセキュリティ問題に対処する方法
JavaScript セキュリティのベストプラクティスを採用し、高度なスキャンツールを使用することで、アプリケーションやサーバーを JavaScript の脆弱性から保護し、管理することができます。
Web 開発の世界では、ソフトウェアエンジニアは常に新しい JavaScript のセキュリティリスクについて把握しておく必要があります。アプリケーションの機能テストを行うだけでなく、JavaScript のセキュリティテストツールを定期的に使用することも、脆弱性を防ぐための重要なポイントになります。最後に、シンプルで一般的なベストプラクティスに従うことで、アプリケーションの耐久性は確実に向上します。
以下の JavaScript セキュリティベストプラクティスに従うことで、このリスクを軽減できます。
\**eval()**を使用しない:このコマンドは渡された引数が JavaScript の式であれば実行されるため、コードでは使用しないでください。これは、ハッカーが入力値の操作に成功した場合、任意のスクリプトを実行できることを意味します。その代わりに、もっと安全な代替策を選びましょう。
暗号化: クライアントとサーバーの間で交換されるデータを、HTTPS/SSL を使用して暗号化します。
セキュア Cookie の設定: SSL/HTTPS が確実に使用されるように、Cookieを「secure」に設定し、アプリケーションの Cookie の使用を安全な Web ページのみに制限してください。
API アクセスキーの設定: エンドユーザーごとに個別のトークンを割り当てます。トークンが一致しない場合、アクセスを拒否するか、取り消すことができます。
安全な DOM 操作方法を使用する: innerHTML などのメソッドは、渡される値の制限もエスケープ/エンコードもしないので、強力で潜在的に危険です。代わりに innerText のようなメソッドを使用することで、潜在的に危険なコンテンツを元からエスケープできます。これは特に DOM ベースの XSS 攻撃を防ぐのに有効です。
潜在的な JavaScript のセキュリティ問題を特定することは、開発するアプリケーションの脆弱性を防止する重要な第一歩となります。今すぐオープンソースの脆弱性スキャナでコードをテストしてみましょう。
Up Next
Storytime by Tanya Janca - Secure Coding Libraries
Listen to Tanya share her best practices for creating templates for secure code.
続きを読む