Aikido

最新のWebアプリケーションにおけるJavaScriptセキュリティ脆弱性トップ10

ルーベン・カメルリンクルーベン・カメルリンク
|
#
#

JavaScriptのセキュリティ脆弱性トップ10

JavaScriptは、動的なWebフロントエンドからスケーラブルなNode.jsバックエンドまで、現代のアプリケーションの広範な領域を支えており、これは広範な攻撃対象領域を露出させることを意味します。JavaScriptを強力にしているその柔軟性は、セキュリティが見過ごされると諸刃の剣となり得ます。フロントエンドコードはユーザーのブラウザで直接実行され(攻撃者によって検査または操作される可能性があります)、一方バックエンドのNode.jsアプリケーションはしばしば無数のパッケージを統合し、機密データを処理します。残念な真実は、JavaScriptのたった1つの安全でない行や脆弱な依存関係が、エクスプロイトへの扉を開く可能性があるということです。実際、最近の業界レポートによると、長年の警告にもかかわらず、Webアプリケーションはクロスサイトスクリプティングや古いライブラリのような一般的な脆弱性に依然として悩まされていることが示されています。

すべての script タグ、あらゆる npmインストールそして、あらゆるJSON解析には潜在的なリスクが潜んでいる可能性があります。以下のセクションでは、クライアントサイドとサーバーサイドの両方の問題を含む、JavaScriptのセキュリティ脆弱性トップ10を、実例と修正・予防策のヒントと共に解説します。XSSのような古典的な落とし穴から最先端の脅威まで サプライチェーン攻撃脆弱性 緩和策と、最新のセキュリティツール(例: AikidoSASTSAST, シークレットそして 依存関係スキャン問題を早期に発見するのに役立ちます。

1. クロスサイトスクリプティング(XSS)攻撃

Cross-Site Scripting (XSS) is one of the most prevalent vulnerabilities in we11b applications year after year. XSS occurs when an application includes unsanitized user input in a webpage, allowing attackers to inject malicious JavaScript that executes in the browsers of other users. This can lead to session hijacking, defacement, and theft of sensitive data. Even widely used libraries have suffered XSS flaws – for example, a five-year-old jQuery bug (CVE-2020-11023) allowed arbitrary code execution by passing malicious HTML to jQuery’s DOM methods. Unsuspecting developers who included a vulnerable jQuery (<3.5.0) version in their frontend exposed their users to potential XSS, a flaw so serious that U.S. CISA added it to its exploited vulnerabilities catalog in 2025.

実例: 攻撃者は、出力を適切にエスケープしないフォーラムで、 <script> 出力エスケープが適切に行われていないフォーラムのタグ。他のユーザーがそのページを表示すると、スクリプトがブラウザ上で実行され、セッションクッキーを盗んだり、ユーザーになりすましたりする可能性があります。 クララネットの2024年セキュリティレポート 発見された XSSの2,570件のインスタンス (反射型および保存型)が発見され、これは 「過去5年間で最も一般的な脆弱性の1つ」であるとされています。これは、JavaScriptを多用するアプリケーションにおいて、XSSが依然として主要な脅威であることを強調しています。

緩和策:XSSから防御するには、コーディングプラクティスとブラウザ防御の組み合わせが必要です。

  • 出力のエスケープと検証:生のユーザー入力をHTMLに直接挿入しないでください。入力時にサニタイズし、適切なコンテキスト(HTML、属性、JavaScriptなど)で出力をエスケープしてください。
  • フレームワークコントロールの使用: コンテンツを自動的にエスケープまたはサニタイズするテンプレートエンジンやフロントエンドフレームワーク(React、Angular、Vue)を活用してください。動的なデータとともに インナーHTML または document.write のような危険なシンクの使用は避け、より安全な代替手段を使用してください。 テキストコンテンツ.
  • コンテンツセキュリティポリシー(CSP):厳格なCSPヘッダーを実装して、スクリプトの読み込み元を制限してください。CSPは、不正なスクリプトをブロックすることで、第二の防御線として機能します。
  • HttpOnlyクッキーとSameSite: クッキーをHttpOnly(JS経由でアクセス不可)としてマークし、 SameSite 属性を使用して、一部の種類の攻撃(クロスサイトスクリプティングによるクッキーの窃盗やCSRFなど)を困難にします。

クロスサイトスクリプティング(XSS)の検出には、コードレビューとテストにおける警戒心が必要です。 Aikidoの静的アプリケーションセキュリティテスト(SAST)は、危険なパターン(例: インナーHTML ユーザー提供データやサーバーテンプレート内の出力エンコーディング不足の場合。依存関係スキャンも役立ちます: Aikido 古いライブラリバージョン(上記のjQuery 3.4.1の例のように)を使用している場合、XSSを可能にする既知の脆弱性があることを警告します。これにより、修正済みのバージョンにアップグレードできます。自動スキャンCI/CD統合することで、攻撃者に先んじてXSS脆弱性を早期に検出できます。

2. プロトタイプ汚染

プロトタイプ汚染は、オブジェクトのプロトタイプの動的な性質を悪用するJavaScript特有の脆弱性です。JavaScriptでは、オブジェクトはプロトタイプからプロパティを継承します。攻撃者がプロパティを注入できる場合、 Object.prototypeそれらのプロパティはすべてのオブジェクトでアクセス可能になり、サービス拒否やリモートコード実行につながることがよくあります。多くの人気ライブラリがプロトタイプ汚染のCVEに苦しんできました。例えば、Lodashのバージョン4.17.12以前には、その defaultsDeep およびその他の関数に脆弱性があり、 Object.prototype via a crafted payload. Another example is Handlebars.js: versions <4.3.0 allowed template input to alter special properties like __proto__が変更されるように騙される可能性がありました。これにより、 「攻撃者が任意のコードを実行できる可能性があります」 とサーバー上で言われています (CVE-2019-19919)。

実例: 攻撃者は、次のようなペイロードでAPIにJSONデータを送信します。 {"__proto__": {"admin": true}}アプリケーションがガードなしでオブジェクトをマージする場合(例えば、古い lodash.merge または類似の関数を使用している場合)、プロトタイプチェーンが汚染されます。その結果、 if(user.admin) のようなチェックがすべてのユーザーに対して予期せずtrueを返す可能性があります。さらに悪いことに、アプリケーションロジックが乗っ取られる可能性もあります。場合によっては、プロトタイプ汚染は他の手法と組み合わせてコードを実行するために使用されることがあります。例えば、前述のHandlebarsテンプレートにおける「プロトタイプ汚染」の欠陥は、アプリケーションのコンテキストでサーバーサイドJavaScriptを実行するために使用される可能性があります。

緩和策: プロトタイプ汚染を防ぐには:

  • 依存関係の更新: プロトタイプ汚染のバグが修正されたライブラリの修正済みバージョンを使用してください。例えば、Lodashをバージョン4.17.20以降にアップグレードしてください(これにより、複数のCVEが修正されています)。
  • 入力検証: JSONまたはオブジェクトの入力を検証し、サニタイズします。 __proto__, constructorという名前のオブジェクトキー、またはデータ内のプロトタイプを拒否またはフィルタリングします。
  • 安全なオブジェクトマージ: オブジェクトをマージする際(例:ディープクローンや拡張)、プロトタイププロパティをコピーしない安全な関数やライブラリを使用してください。一部のユーティリティライブラリは、継承されたプロパティを無視するオプションを提供しています。
  • Strictモードで実行: 決定的な解決策ではありませんが、strictモード ("use strict") は、特定の危険なアクションを防ぎ、バグを特定しやすくすることができます。

プロトタイプ汚染は微妙なものですが、依存関係スキャンがここで役立ちます。 Aikidoの依存関係スキャナーは、Lodash、jQuery、Handlebarsなどのライブラリにおいて、プロトタイプ汚染の影響を受けやすい既知の脆弱なバージョンを検出します。これにより、事前に更新することが可能です。コード側では、 AikidoのSAST 、安全でないオブジェクトマージのパターンや潜在的に危険なオブジェクトキーの使用を検出できます。 Aikido を使用してコードとnpmパッケージの両方を継続的に監査することで、この種のバグに対する安全策を得られます。つまり、侵害が発生した後ではなく、開発段階で問題を捕捉できるのです。

3. 安全でないデシリアライゼーション

アプリケーションが信頼できないシリアライズされたデータを受け入れ、適切な検証なしにオブジェクトにデシリアライズする際に、安全でないデシリアライゼーションの脆弱性が発生します。JavaScript/Nodeでは、これは多くの場合、ユーザーが提供するJSONまたはJavaScriptオブジェクトを受け取り、それらをライブオブジェクトとして「復元」する関数を伴います。慎重に処理されない場合、デシリアライゼーションは任意のコードを実行したり、アプリケーションの状態を操作したりするために悪用される可能性があります。悪名高い例としては、 node-serialize パッケージの脆弱性(CVE-2017-5941)が挙げられます。これは、攻撃者が即時実行関数式(IIFE)を含む悪意のあるシリアライズされたオブジェクトを渡すことを可能にしました。デシリアライズ時に、その関数がサーバー上で実行され、事実上のリモートコード実行を達成しました。

実例:この問題は理論上のものではありません。主要なフレームワークでさえ見落としてきました。2025年末、React/Next.js脆弱性 重大な脆弱性 通称 React2Shell、CVE-2025-55182)が公表された。これはReactサーバーコンポーネントがシリアライズされたデータを処理する方法に起因する。 アカマイ社の調査では「問題の核心は安全でない逆シリアライゼーションにある」と指摘。これにより攻撃者は悪意のあるオブジェクトキーを注入し、プロトタイプ汚染を引き起こして最終的にサーバー上でリモートコード実行が可能となった。つまり、細工したHTTPリクエストを送信するだけで、認証されていない攻撃者が脆弱なReactコードを実行するNode.jsサーバーを乗っ取れるDevSecOps 悪夢のようなシナリオだ。

対策: 安全でないデシリアライゼーションを防ぐには、データフォーマットの慎重な取り扱いが必要です。

  • 安全なフォーマットを優先する: データ交換にはJSONを使用し、クライアント入力からJavaScriptコードや関数をパースすることは避けてください。標準のJSON.parseは、 eval() やJSオブジェクトのカスタムデシリアライゼーションよりも安全です。
  • ホワイトリスト化と検証: シリアライズされたオブジェクトを受け入れる必要がある場合は、厳格なスキーマまたはホワイトリストを実装してください。予期されるオブジェクトプロパティと型のみを許可してください。次のようなキーを含む入力は拒否してください __proto__ やconstructorなど、悪用のベクトルとなりうるもの。
  • 回避する: 評価 そして 関数(): 使用しない: eval() をJSONに対して使用したり、クライアントから生のJSコードを受け入れたりしないでください。同様に、オブジェクトデータを実行するライブラリは避けてください(例えば、パースされた入力から来る関数を自動的に実行することは避けてください)。
  • ライブラリの更新: フレームワークのパッチを常に最新の状態に保ってください。上記のReactの脆弱性は、React/Nextの更新によって修正されました。そのようなパッチは直ちに適用し、デシリアライゼーションを実行するNode.jsライブラリのアドバイザリを監視してください。

Aikidoのプラットフォームは、いくつかの方法で安全でないデシリアライゼーションを検出するのに役立ちます。 静的コード解析 は、コードが危険な関数(例えば、 unserialize() を古いライブラリから使用している場合や、 評価 を入力に対して使用している場合)に警告します。既知の脆弱なパッケージ(例えば、バグのある node-serialize <=0.0.4, or certain versions of React), Aikido’s dependency scanner would flag those by CVE. Additionally, Aikido’s runtime SAST analysis (if integrated in testing) can observe data flows – for example, user input flowing into a dangerous sink – and alert you. The bottom line: integrating such tools in CI means you’d catch something like React2Shell in your code 前に がニュースでReact2Shellとして取り上げられるようなもの)を使用している場合にも警告します。

4. クロスサイトリクエストフォージェリ(CSRF)

クロスサイトリクエストフォージェリ(CSRF)は、JavaScriptベースのアプリケーション(またはセッションを持つあらゆるウェブアプリケーション)に影響を与えることがよくある古典的なウェブ脆弱性です。コードインジェクションを悪用するXSSとは異なり、CSRFはユーザーのブラウザの信頼を悪用します。これにより、攻撃者は被害者のブラウザを騙して、被害者自身の認証情報のふりをして、意図しないリクエストをアプリケーションに行わせることができます。簡単に言えば、ユーザーがサイトにログインしている場合、攻撃者は(悪意のあるリンクや画像を介して)ブラウザに、ユーザーの同意なしにアカウント詳細の変更や取引の開始などのアクションを実行させる可能性があります。

実例: よく知られた例としては、 フォーラム投稿/銀行振込の例え – 銀行アプリで、送金フォームがCSRFに対して脆弱であると想像してみてください。攻撃者は、ログイン中のユーザーにリンクを送信する(または悪意のあるページに自動送信フォームを埋め込む)ことで、 POST /transfer?amount=1000&to=attackerAccountをトリガーできます。銀行アプリにCSRF保護がない場合、ユーザーのブラウザはセッションクッキーとともにそのリクエストを忠実に送信し、銀行はユーザーが意図したものと判断してそれを実行します。JavaScriptのコンテキストでは、シングルページアプリケーション(SPA)は、認証にクッキーを使用するAPIに依存する場合があります。これらのAPIがCSRF防御策(トークンの要求やSameSiteクッキーなど)を実装していない場合、同様にエクスプロイトされる可能性があります。CSRFトークンを含むフレームワークでさえ、誤って設定される可能性があります。例えば、AngularやReactアプリのバックエンドが過度に広範なCORSポリシーを設定したり、SameSiteフラグが欠落していたりすると、CSRF攻撃がすり抜ける可能性があります。

軽減策: CSRFを阻止するための主要な戦略は以下の通りです。

  • CSRFトークン: フォームまたはAPI呼び出しに予測不可能なトークンを埋め込み、サーバー側で検証します。最新のフレームワークには、しばしばCSRFミドルウェアが備わっています。トークンがユーザーのセッションに紐付けられ、状態を変更するすべてのリクエストで検証されるようにしてください。
  • SameSite Cookies: セッションクッキーを SameSite=Lax または 厳格 属性で設定します。これにより、ブラウザがクロスサイトリクエスト(CSRFの主要なメカニズム)でクッキーを送信するのを制限します。 厳格 は一部の正当なフローを壊す可能性があるため、 緩い はほとんどのアプリにとってバランスの取れたデフォルトです。
  • カスタムヘッダーとオリジンの検証: APIの場合(特にSPAでfetch/XHRを使用している場合)、カスタムヘッダー(例: X-Requested-With: XMLHttpRequest)を要求し、それを持たないリクエストを拒否できます。さらに、 Origin そして Referer ヘッダーを確認し、それらが自社のドメインから来ていることを確認します。
  • 状態変更にGETを使用しない: CSRFは <img> または <script> タグを使用してGETリクエストを開始できます。重要なアクション(データの変更など)がPOST(またはGET以外のメソッド)を使用し、理想的には依然としてトークンを要求するようにしてください。

CSRFはコードのバグというよりも設計の問題ですが、Aikidoのセキュリティツールキットは依然として役立ちます。 静的解析 は、一般的なフレームワークを使用している場合、CSRF保護が不足しているルートやコントローラーを検出できます(例えば、不足している csrf() Expressアプリにおけるミドルウェアの不備、またはアンチCSRFモジュールが使用されていないケースなどです。Aikidoは、動的解析やパイプラインスクリプトを介してHTTPセキュリティヘッダーやクッキーの設定をスキャンし、不足している SameSite または HttpOnly 属性を特定します。これらのチェックを統合することで、Aikidoはセキュアコーディングの習慣(CSRFトークンの実装や適切なクッキーフラグの設定など)がプロジェクト全体で一貫して適用されるようにします。

5. NoSQLインジェクション

従来のSQLデータベースがSQLインジェクションの被害を受けるのと同様に、MongoDBやCouchDBなどのNoSQLデータベースを使用する最新のJavaScriptアプリケーションは、NoSQLインジェクションに対して脆弱になる可能性があります。NoSQLインジェクションは、攻撃者がNoSQLクエリで使用される入力を操作することで発生し、クエリの変更、認証のバイパス、または不正なデータの取得を可能にします。NoSQLクエリはしばしばJSONやクエリオブジェクトを使用するため、構文はSQLとは異なりますが、予期しない方法でパラメーターを注入するという概念は依然として適用されます。

実例: ユーザー認証にMongoDBを使用するNode.jsアプリケーションで、以下のようなコードを考えてみましょう。

// insecure pseudo-codeUsers.findOne({ username: inputUser, password: inputPass })

一見すると問題ないように見えますが、MongoDBのクエリはオブジェクトと特殊な演算子を受け入れます。攻撃者は、JSONペイロードを送信する可能性があります inputPass 例えば { "$ne": null }。クエリは次のようになります {username: "victim", password: { $ne: null } }、これはMongoでは「ユーザー名が'victim'で、パスワードがnullではないユーザーを見つける」という意味になり、実質的にパスワードチェックをバイパスします。なぜなら $ne: null 実際のパスワードフィールドでは常に真となるためです。この種の NoSQL演算子インジェクション は、ログインフォームをバイパスするための既知の手法です。PortSwiggerのWeb Security Academyは、NoSQLインジェクションが「場合によっては、攻撃者が認証をバイパスしたり、データを抽出または変更したり、サーバー上でコードを実行したりすることを可能にする」方法を文書化しています。

認証バイパスに加えて、NoSQLインジェクションはデータを抽出するためにも使用できます。例えば、を注入することで $regex やその他の演算子を注入することで、アプリケーションが注意を怠ると、攻撃者はユーザーレコードを列挙したり、データベースをダンプしたりする可能性があります。

緩和策:

  • 入力サニタイズ: ユーザーが制御するデータを直接データベースクエリに渡さないでください。入力をサニタイズしてください。例えば、文字列のユーザー名を期待している場合、それが文字列であり、を含まないことを確認してください。 $ やその他の特殊文字を含まないことを確認してください。一部のORMやドライバーライブラリには、演算子インジェクションを防ぐための組み込みチェックやモードがあります(例:Mongooseは無効にできます $ プレフィックス付きキーをデフォルトで)。
  • パラメーター化クエリ/ORMの使用: ORMやクエリビルダーを使用することで、生のクエリへの直接的な露出を減らすことができます。利用可能なパラメーター化機能を必ず使用してください。
  • 認証とクエリロジック: 機密性の高い操作では、単一の条件だけに依存しないでください。ログインの場合、操作される可能性のある大きなクエリ一つに頼るのではなく、ユーザー名を介してユーザーを取得した後にパスワードを個別に検証するワークフローを推奨します。
  • ロギングとモニタリング: NoSQLインジェクションの試行は、しばしば痕跡(例:異常なクエリパターンやエラー)を残します。ログイン失敗の試行や予期しないクエリパラメーターをログに記録してください。これにより、進行中の攻撃を検出するのに役立つ可能性があります。

Aikidoの静的解析は、

findOne()

または、未チェックのユーザー入力を含む同様のクエリです。例えば、Aikidoは以下のような場合にフラグを立てることができます。 $ または、クエリ文字列に連結される正規表現文字、あるいは未加工の Users.findOne({ ... ユーザー入力 ... }) サニタイズなし。さらに、 Aikidoの動的スキャン(実行中の開発インスタンスに対して使用する場合)は、NoSQLインジェクションに対する特定のテストを含めることがあり、これは DAST SQLインジェクションのテスト。これらを活用することで、開発者は早期に警告を受け取れます:「このログイン機能はNoSQLインジェクションの脆弱性がある可能性があります」。早期に修正することで、本番環境での認証バイパスという潜在的な大惨事を回避できます。

6. 正規表現サービス拒否 (ReDoS)

正規表現サービス拒否 (ReDoS) は、攻撃者が特別に細工した入力を正規表現に提供することで、評価に異常に長い時間がかかり、CPUを独占して実質的にサービス拒否を引き起こす脆弱性です。JavaScriptの正規表現エンジン(他の多くのエンジンと同様に)は、 壊滅的なバックトラッキング 特定のパターンで発生する可能性があります。これは、単一のスレッドが多数のクライアントを処理するNode.jsにとって特に重要です。正規表現が停止すると、イベントループ全体がブロックされる可能性があります。ReDoSの脆弱性は、さまざまなnpmパッケージやフレームワークで発見されています。例えば、Vue.js 2のテンプレートコンパイラ(CVE-2024-9506)では、深刻度は低いものの注目すべき欠陥が発見されました。HTMLを解析するための不適切に記述された正規表現は、不正な形式の <textarea> または <script> タグによって 「テンプレート解析に重大な遅延を引き起こす」。同様に、人気のある path-to-regexp ライブラリ(Expressルーティングで使用)にもReDoSの問題(CVE-2024-52798)がありました。また、URLやメールなどの無数のバリデーションライブラリでも、長年にわたりReDoSのCVEが報告されています。

実例: ユーザー登録時にメールアドレスを検証するために正規表現を使用するNode.jsサーバーを想像してみてください。単純な正規表現パターン(例えば、 /(.+)@(.+)\.(.+)/)は、特定の長さと構成の文字列に対して壊滅的なバックトラッキングを引き起こす可能性があります。攻撃者は、非常に長いメール文字列のような "aaaa....aaaa!" (特定のパターンを持つ)を送信することで、正規表現が数秒以上処理に時間を要し、その間サーバーが他のリクエストを処理できなくなる可能性があります。あるケースでは、 バリデータ.js ライブラリのURL検証でReDoSが発見されました。数十キロバイトの細工されたURL入力によってプロセスがハングアップしました。攻撃者がこのような入力を大量に自動送信した場合、サービスを効果的に停止させることができます。OWASP財団は、ほとんどの正規表現エンジンがこのような極端なケースに対して脆弱であると指摘しています。

緩和策:

  • 信頼できない入力に対する複雑な正規表現を避ける: 正規表現パターンを簡素化するか、非バックトラッキングアプローチを使用してください。可能であれば、一般的なタスクには組み込みライブラリや検証済みのアルゴリズムを使用してください(例えば、URLには複雑な正規表現ではなくNodeの組み込みURLパーサーを使用するなど)。
  • タイムアウトの使用: 重要なケースでは、タイムアウトまたはサンドボックスをサポートする正規表現ライブラリを使用できます。Nodeでは、 RegExp 操作は同期ですが、メインループのブロックを避けるために、必要に応じて正規表現の処理を別のワーカー スレッドで実行できます。
  • 入力長の制限: ReDoSは、非常に長い入力文字列に依存することがよくあります。入力に適切な長さ制限を設けることで(例:RFCに従い、メールアドレスは254文字を超えないようにする)、ReDoSの実行可能性を低減できます。
  • パターンのレビューとテスト: 正規表現の壊滅的なバックトラックの可能性を分析できるツールが存在します。複雑なパターンについては、コードレビューにそれらを組み込みます。病的な入力を持つテストケースを作成し、正規表現がストレス下でどのように動作するかを確認します。

依存関係スキャンがここで威力を発揮します。Aikidoは、npmパッケージ内の既知のCVEと脆弱性を追跡します。既知のReDoSを持つパッケージ(例えば、脆弱なバージョンの日付パーサーやURLバリデーターなど)を取り込んでいる場合、Aikidoは修正済みのバージョンに更新するよう警告します。コード内のカスタム正規表現パターンについては、AikidoのSASTがハードコードされた正規表現リテラルや new RegExp() 使用状況を検出し、ヒューリスティックチェックを適用できます(例えば、過剰な量指定子やネストされたグループを持つパターンにフラグを立てるなど)。すべての「悪意のある」正規表現を捕捉できるわけではありませんが、Aikidoのナレッジベースと組み合わせることで、「この正規表現は指数関数的に疑わしい」と警告できます。また、Aikidoのテストツールはファジング攻撃をシミュレートできます。単純なペイロードがパフォーマンスの問題を引き起こした場合、午前2時にポケベルで知らされるのではなく、テスト中にそれを把握できます。

7. ディレクトリトラバーサルとファイル公開

ディレクトリトラバーサル(またはパストラバーサル)の脆弱性は、攻撃者がファイルパスを操作することで、サーバー上のアクセス制限されたファイルにアクセスすることを可能にします。Node.jsでは、これは静的ファイルを提供するライブラリやコード、ファイルダウンロードを処理するコード、またはzipアーカイブを処理するコードでよく発生します。ユーザー入力が適切なサニタイズなしにファイルパスに連結されると、攻撃者は次のようなシーケンスを使用して ../ 意図されたディレクトリから抜け出すことができます。例えば、 node-static パッケージ(シンプルな静的ファイルサーバー)において、 servePath 関数内の不適切なチェックによって、攻撃者が .. を含むURLをリクエストし、任意のファイルにアクセスできる脆弱性(CVE-2023-26111)が発見されました。概念実証では、攻撃者が次のような機密ファイルを /root/.ssh/id_rsa をエンコードすることで ../../..//..//..// URLで取得できることが示されました。

実例: よくあるシナリオとして、Expressアプリケーションが express.static() を使用している場合や、カスタムのファイル提供ルートを使用している場合が挙げられます。例えば、次のようなコードがあるとします。

app.get('/download', (req, res) => {  const file = req.query.file;    res.sendFile(__dirname + '/uploads/' + file);});

注意しないと、攻撃者は /download?file=../../etc/passwd を呼び出し、システムファイルを取得できます。このようにして、アプリケーションが意図せずキーや設定ファイルを公開してしまった事例もあります。ライブラリを使用している場合でもバグが存在しました。Expressの静的ミドルウェアの古いバージョンには、エッジケース(エンコードされたドットを含むURLなど)で既知のディレクトリトラバーサル問題がありました。Windows上のNodeのコアパス処理にも、悪用される可能性のあるデバイス名に関連するトラバーサルの癖(CVE-2025-27210)がありました。ファイルの読み取りだけでなく、ファイルの書き込みも別の側面です(例えば、zipアーカイブの展開が意図されたフォルダ外にファイルを書き込む「Zip Slip」攻撃など)。

緩和策:

  • パスの正規化と検証: 使用して path.normalize() そして path.join() シーケンスを解決し、 .. 解決されたパスが許可されたディレクトリ内にあることを確認します。例えば、解決後、ファイルが指定の /uploads フォルダ外にある場合は、リクエストを拒否してください。
  • ユーザー制御パスの直接使用を避ける: 可能な限り、ユーザー入力をファイル名として直接使用しないでください。ユーザー入力を事前に定義されたファイルパスにマッピングします。例えば、ユーザーが自身のファイルのみをダウンロードすべき場合、ファイル名パラメータを信頼するのではなく、識別子を使用してサーバー側でファイル名を検索してください。
  • 最小権限の原則: Node.jsプロセスを最小限の権限で実行してください。アプリケーションが特定のディレクトリ外にアクセスする理由がない場合、トラバーサルによる被害を制限するために、OSレベルの制限またはコンテナ化を検討してください。
  • ライブラリを最新の状態に保つ: ファイル提供ライブラリや解凍ライブラリを使用している場合、それらのセキュリティパッチを常に最新の状態に保ってください。その node-static 脆弱性は、古いパッケージでは「修正なし」でした。これは、代替ライブラリを使用するか、独自のパッチを追加する必要があることを意味するかもしれません。

Aikidoのスキャンは、コード内の一般的なディレクトリトラバーサルのパターンを検出できます。例えば、 sendFile または readFile を用いて req.query または req.params の使用は、当社のSASTルールが強調できる危険信号です。Aikidoは既知の脆弱性も相互参照します。プロジェクトが send または node-static のバージョンに依存し、パス・トラバーサルのCVEを持つ場合、更新を促します。DevSecOpsチームにとって、Aikidoの強みはこれらのシグナルを組み合わせることです。例えば、ファイル提供コードスニペットを危険とフラグ付けすると想像してください。 そして それに対して古いライブラリを使用していることを指摘します。この洞察は、迅速な修正(入力のサニタイズとライブラリバージョンの更新)を促進できます。本質的に、Aikidoは追加のセキュリティレビューアとして機能し、攻撃者がファイルシステムを探索できないように、ファイルアクセスロジックを徹底的に調査します。

8. 脆弱で古い依存関係

現代のJavaScriptアプリケーションには、数十から数百ものnpmパッケージが含まれていることがよくあります。これらの依存関係(およびそのサブ依存関係)のそれぞれが、既知の脆弱性を抱えている可能性があります。古いライブラリの使用は非常に一般的であり、それ自体がリスクのカテゴリとなっています。フロントエンドフレームワーク、Nodeモジュール、またはユーティリティライブラリの安全でないバージョンは、自身のコードに問題がなくても、アプリケーションを攻撃にさらす可能性があります。Claranetの2024年の調査では、500のアプリケーションで1,032件の古いJavaScriptライブラリが発見され、“古いJavaScriptを使用すると、XSS、サービス拒否攻撃、機密情報の漏洩につながる可能性がある”と指摘されています。言い換えれば、人気のあるライブラリの既知のCVEは、更新されていない場合、アプリケーションにとって直接的なリスクとなります。

実世界の例:

  • Lodash: 非常に人気のあるユーティリティライブラリです。複数のCVE(前述の通り)がLodashに影響を与えています。プロトタイプ汚染の脆弱性(CVE-2018-16487、CVE-2019-10744、CVE-2020-8203)や、さらには正規表現によるDoS問題も _.escapeRegExp古いLodashバージョンに依存しているアプリケーションは、それらの脆弱性を継承していました。
  • jQuery: Once ubiquitous on the frontend. jQuery <3.5.0 had that XSS vulnerability where injecting <option> タグがスクリプトを実行する可能性がありました。フロントエンドでjQuery 2.1や3.4などをまだ使用している場合、攻撃者が積極的にエクスプロイトしている既知のXSSの脆弱性を抱えていることになります。
  • Expressなど: Expressフレームワーク自体にもいくつかのCVE(オープンリダイレクト、不正なリクエストによるサービス拒否など)がありました。のような小規模なパッケージでは moment (日付ライブラリ)は、特定の利用方法でパス・トラバーサル脆弱性(CVE-2022-24785)がありました。 markdown-it XSSの問題などがありました。Nodeのコアにもパッチ適用が必要な脆弱性がありました(2022年から2025年にかけてのHTTPリクエスト密輸やパス・トラバーサルの問題など)。

脆弱なコンポーネントの使用は、OWASP Top Tenの1つです(「既知の脆弱性を持つコンポーネントの使用」の下)。これは本質的にサプライチェーンの懸念事項であり、ライブラリを導入すると、そのバグも一緒に持ち込むことになります。

緩和策:

  • 依存関係のスキャンと更新: 定期的に npm 監査 や類似のツールを実行して、依存関係内の既知の脆弱性のリストを取得します。パッケージをパッチ適用済みのバージョンにアップグレードします。使用しているライブラリで新しい脆弱性が見つかったときに警告するツールを使用します。
  • ロックファイルの衛生管理: を管理します。 パッケージロック.json (またはYarnロックファイル)を慎重に管理します。を使用して、未解決のネストされた依存関係の問題を回避します。 npm audit fix 適切な場所で。サブ依存関係が脆弱で更新されない場合、オーバーライドを検討するか、メンテナーに連絡してください。
  • 最小限の依存関係: 不要なパッケージを含めないでください。余分な依存関係は、潜在的な脆弱性となります。例えば、小さな関数しか必要ない場合、信頼して監視する必要がある30個の関数を持つライブラリを導入するよりも、自分で実装する方が安全かもしれません。
  • アドバイザリの監視: Node/JSエコシステムにおけるセキュリティアドバイザリに常に注意を払ってください。NodeセキュリティメーリングリストやGitHubのDependabotアラートをリポジトリにサブスクライブしてください。

ここでAikido依存関係スキャンとAIによる修正が真価を発揮します。 Aikido 脆弱性 に対して依存関係ツリーを継続的にスキャンします。例えばExpressやLodashに新たなCVEが発見された場合、通知が届き、自動修正提案(例:「CVE-2020-8203を修正するためLodash 4.17.11から4.17.21へアップグレード」)まで提供されます。 開発者向けのツールは単なるレポートではありません。 Aikido は更新版を含むプルリクエストを自動生成します。さらに AikidoのSafeChain機能(パッケージマネージャー用のアプリ内ファイアウォール)は、既知の悪意あるパッケージのインストールを防止します。これらのツールを統合することで、脆弱性 からアプリ内で修正するまでの「脆弱性への曝露期間」を大幅に短縮できます。

9. 悪意のあるNPMパッケージとサプライチェーン攻撃

すべての攻撃がコーディングミスから来るわけではありません。一部は、あなたが と考えたコードから来ます。 信頼できるもの。npmエコシステムは、攻撃者がパッケージの供給を乗っ取り、悪意のあるコードを挿入するサプライチェーン攻撃の被害を受けています。これは、次のような手法によって発生する可能性があります。 タイポスクワッティング (人気のあるパッケージと似た名前でパッケージを公開し、誰かが誤って入力したり、誤ってインストールしたりすることを期待する)手法、または正規プロジェクトのメンテナーを侵害することによって発生します。悪名高い事件の1つは、 event-stream 2018年の攻撃です。攻撃者が~のメンテナーを説得し、 event-stream (広く使用されているパッケージ)の制御を譲り渡させ、隠された依存関係(flatmap-stream)を含むマルウェアをリリースしました。数ヶ月にわたり、その悪意のあるアップデートは何百万回もダウンロードされ、特にBitcoinウォレットアプリ(Copay)を標的として、暗号通貨のキーを盗みました。

他の例としては、次のようなパッケージがあります。 ua-parser-js, node-ipcそして event-source-polyfill 攻撃者によってハイジャックされたか、あるいは開発者自身によって妨害され、望ましくないペイロード(スパイウェア、コインマイナー、破壊的なスクリプトなど)を配信したものです。2021年には、セキュリティ研究者が「依存関係の混乱(dependency confusion)」攻撃を実証しました。これは、企業が内部パッケージ名を使用している場合、攻撃者が同じ名前のパッケージをnpmに公開すると、ビルドツールが攻撃者のバージョンをプルしてしまう可能性があるというものです。これらのシナリオは、従来の脆弱性を悪用することなく、ビルド時や本番環境で攻撃者にリモートコード実行を許してしまう可能性があるため、特に危険です。

緩和策:

  • パッケージの信頼性を検証する: パッケージの整合性ハッシュを使用します(npmは自動的に package-lock をパッケージのsha512ハッシュとともに使用します。そのロックファイルをコミットしたままにしてください)。npmアカウントで2FAを有効にすることを検討し、信頼できるソースからのパッケージを優先してください。
  • 内部依存関係をロックダウンする: プライベートパッケージを使用している場合、レジストリまたはビルドプロセスが誤ってパブリックレジストリから取得しないようにしてください。内部パッケージを名前空間化するか、スコープ付きレジストリを使用してください。
  • インストールスクリプトを監視する: インストール/ポストインストールスクリプトを持つパッケージには注意してください。これらのスクリプトが何をするかを監査してください(一部の悪意のあるパッケージは、インストール時に有害なコマンドを実行するためにこれらを使用します)。
  • セキュリティツールを使用する: npmの監査機能やその他のツールを活用して異常を特定してください。例えば、広く使用されているパッケージが長期間の休止後に突然新しいマイナーバージョンをリリースした場合、厳しく調査してください(event-streamの3.3.6リリースがそうであったように)。
  • 最小権限の原則: ビルドやCIを実行する際は、サンドボックス環境で実行してください。本番環境では、Nodeの --experimental-policy どのモジュールが 必要 何を実行できるかを制御するメカニズム、またはコンテナ化を検討して被害を制限してください。

Aikido ソフトウェアのサプライチェーンを保護します。Aikido 、パッケージのメタデータや内容物自体を分析し、悪意のある兆候を検出できます。既知の侵害パッケージや不審な動作(難読化されたインストール後スクリプトなど)を示すパッケージのインストールをブロックします。 Aikidoの脅威インテリジェンスフィードはオープンソースパッケージ内のマルウェアを監視し続けます。そのため、もし明日人気ライブラリが乗っ取られても、 Aikido は警告を発するか、汚染されたバージョンへの更新を防止します。さらに、 AikidoSAST 依存関係 機微な操作の使用を検SAST 依存関係 例えば依存関係が突然シェルコマンドを実行し始めたり、予期せぬ方法でネットワークにアクセスしたりする場合)。これらのツールをパイプラインに統合することで、次に来るイベントストリーム型攻撃に対する強力な防御層を追加できます。これは本質的に、サードパーティコード向けの自動化されたコードレビューアを構築することに他なりません。

10. ハードコードされたシークレットと露出した認証情報

JavaScriptコードや設定ファイルにシークレット(APIキー、トークン、パスワード)をハードコーディングすることは、残念ながら依然として一般的な危険な慣行です。フロントエンドコードでは、シークレット(例えばサードパーティサービスのAPIキーなど)はエンドユーザーに可視であり、公開情報として扱うべきですが、開発者はそのことを忘れ、機密性の高いトークンをJSバンドルに残してしまうことがあります。Node.jsのバックエンドコードや設定ファイルでは、シークレットがGitにコミットされ、ソース管理やデプロイされたパッケージに含まれてしまう可能性があります。シークレットの露出は、不正アクセス、アカウント乗っ取り、または高額な請求(例えば、攻撃者がクラウドプロバイダーのAPIキーを発見した場合、リソースを起動したりデータベースをダンプしたりする可能性があります)につながる可能性があります。

この問題の規模は、調査によって浮き彫りになっています。2024年だけでも、約2,380万件の新しいハードコードされたシークレットが公開GitHubコミットで検出され、前年比で25%増加しました。著名な情報漏洩は、漏洩した認証情報が原因で発生しています。例えば、New York Timesの認証情報漏洩やSisenseでの漏洩は、シークレットの拡散に起因していました。Dockerイメージでさえ、意図せず数千ものAPIキーが組み込まれているのが発見されています。結論として、シークレットの露出は蔓延しており、ソフトウェアの脆弱性をエクスプロイトすることなく攻撃者が侵入する最も簡単な方法となることがよくあります。

実例: 2019年、ある開発者が誤ってMongoDBの接続文字列(認証情報を含む)を公開GitHubリポジトリにプッシュしました。数時間以内に、GitHubをスキャンしていた攻撃者がそれを見つけ、データベースにアクセスし、データを人質に取って身代金を要求しました。別のケースでは、モバイルアプリ開発者がFirebaseのプライベートキーをアプリのJavaScriptに残しており、攻撃者がそれを抽出してFirebase上のユーザーデータにアクセスしました。これらの例は、それが .js ファイル、誤ってコミットされた 環境 ファイル、またはコードベースのどこかに存在する場合でも、シークレットは露出すると攻撃者にとって格好の標的となることを示しています。

緩和策:

  • シークレットをハードコードしない: 環境変数またはシークレット管理サービスを使用してください。Node.jsアプリは、ソースコードにシークレットを記述するのではなく、実行時に process.env から読み取ることができます。フロントエンドの要件については、シークレットが露出しないようにバックエンドを介してリクエストをプロキシすることを検討するか、シークレットの埋め込みを必要としないOAuthフローを使用してください。
  • Git Ignoreとスキャン: 設定ファイルやその他のシークレットを含むファイルをコミットしないでください。 環境 を使用してそれらを除外します。 .gitignore さらに、シークレットスキャンツール(GitHubには公開リポジトリ用の組み込みシークレットスキャナーがあり、サードパーティツールはコミットをスキャンできます)を使用して、紛れ込んだシークレットを捕捉してください。
  • キーのローテーション: シークレットが漏洩した疑いがある場合は、直ちにローテーションしてください。キーローテーションの計画を立て、異なる環境には個別の認証情報を使用してください(例えば、開発環境での漏洩が本番環境を危険にさらさないようにするため)。
  • Vaultと設定管理: 設定ファイルにシークレットを保存するのではなく、適切なシークレットVaultまたはクラウドシークレットマネージャーを使用して、実行時にシークレットを保存および取得してください。

Aikido シークレット 、コードや設定ファイルを継続的にスキャンして認証情報のパターンを探します。例えば、API 、 Aikido はプルリクエスト中も含め、高優先度アラートでこれを検知します。パターン認識に加え文脈も判断可能(例:設定ファイル内の40文字16進数文字列はAPI としてフラグ付け)。さらに Aikidoのプラットフォームはバージョン管理システムと連携し、シークレット 本番環境にシークレット 未然に防ぎます。CIパイプライン内で検知する仕組みです。これは「そのキーを本当にコミットしますか?」と確認する守護者を置くようなものです。シークレットが発見された場合、 Aikido はそのシークレットが拡散した可能性のある箇所を特定し、是正策(例:ローテーションすべきキーの提案)まで示して影響評価を支援します。こうしたツールを活用することで、開発者は「王国の鍵」を意図せず公開することなく、リポジトリへのコミットを確信を持って行えるようになります。

結論

JavaScriptの強みである、ブラウザからバックエンドまでの普及性と柔軟性は、まさにそのセキュリティ確保を極めて重要なタスクにしています。単純な見落とし(サニタイズされていない出力、古いパッケージ、漏洩したAPIキー)が、いかに簡単にアプリケーションのセキュリティを崩壊させるかを見てきました。良いニュースは、意識とベストプラクティスが大いに役立つということです。これらの主要な脆弱性を理解することで、開発者は信頼できないデータをevalしたり、 ../ を介してドアを開放したりするような一般的な間違いを避けることができます。セキュリティファーストの考え方を受け入れることは、入力の検証、出力のエンコード、依存関係の更新、そして「誰も私の間違いに気づかないだろう」と決して思い込まないことを意味します。なぜなら、あなたがそれを捕捉しなければ、最終的には攻撃者が捕捉するからです。

開発ワークフローにセキュリティを組み込みましょう。安全なコーディング習慣を身につけ(OWASPチートシートを参照し、リンターや型チェッカーを活用して問題を早期に発見)、静的コード分析から依存関係監査、シークレットスキャンまで、開発プロセスと連携する統合セキュリティツールを活用してください。 Aikido は、これらの実践CI/CD に組み込むことを可能にし、すべてのコミットとビルドが自動的に脆弱性チェックされます。問題を早期かつ頻繁に捕捉することで、速度を落とさずにリスクを低減できます。JavaScriptの世界は急速に変化しますが、適切な安全策を講じれば、アプリケーションを危険に晒すことなく、同じ速さでイノベーションを推進できます。自信を持って安全にリリースしましょう。ユーザーとDevSecOps 感謝するはずです!

続きを読む:
トップ9 Dockerコンテナセキュリティ脆弱性
トップ7 クラウドセキュリティ脆弱性
トップ10 すべてのチームが知るべきWebアプリケーションセキュリティ脆弱性
トップ9 Kubernetesセキュリティ脆弱性と設定ミス
現代アプリケーションで発見される主要なコードセキュリティ脆弱性
トップ10 開発者が避けるべきPythonセキュリティ脆弱性 トップ9 ソフトウェアサプライチェーンセキュリティ脆弱性の解説

4.7/5

今すぐソフトウェアを保護しましょう

無料で始める
CC不要
デモを予約する
データは共有されない - 読み取り専用アクセス - CC不要

今すぐ安全を確保しましょう

コード、クラウド、ランタイムを1つの中央システムでセキュアに。
脆弱性を迅速に発見し、自動的に修正。

クレジットカードは不要。