Skip to main content

Node.jsアプリケーションのセキュリティと可観測性をIDEに取り込むプラグイン

著者
blog feature javascript review

2021年8月23日

0 分で読めます

開発者は、IDEで新しいコードを書いたり、リファクタリングしたり、テストを追加したり、バグを修正したりと、多くの時間を過ごします。近年、IDEは強力なツールへと進化し、HTTPリクエストの操作から生産性全般の向上まで、さまざまな場面で開発者を支援しています。そこで考えてみてください。リリース前にコードのセキュリティ問題を防ぐこともできたらどうでしょうか。IDE上で、本番環境のアプリケーション内部で何が起きているかをコードレベルで把握できたらどうでしょうか。

ここで活躍するのが、開発者ファーストのツールです。IDEに適したプラグインを使えば、開発者の日々のワークフローに可観測性とセキュリティを直接組み込むことができ、最も効果的な形で活用できます。

この記事では、次の内容を取り上げます。

  • IDE上でデータ構造をリアルタイムにコードレベルで可視化する方法

  • 本番環境のNode.jsアプリケーションで有害なユーザー入力を見つける方法

  • コードやオープンソース依存関係に潜むセキュリティ問題を検出して修正する方法

IDEでアプリケーションの可観測性をリアルタイムに実現する方法

この記事を読み進めるには、次のものが必要です。

  1. IntelliJ IDEA(LightrunではVisual Studio Codeのサポートも近日公開予定です。いち早く利用するにはこちらからベータ版に登録してください!)

  2. Lightrunアカウント、LightrunのIntelliJ Plugin、および現在ベータ版のNode.js Agent

IntelliJ IDEAプラグインをインストールしたら、Registerボタンをクリックします。ブラウザーで簡単な登録手続きが始まります。

JavaScriptコード、LoginとRegisterボタンのあるLightrunのウェルカムパネル、Snykのセキュリティスキャンパネルが表示されたダークテーマのIDE

次に、Lightrun Node.jsエージェントをインストールして、Node.jsアプリケーション用に設定します。登録手続き中に手順が表示されますが、見逃した場合に備えて、ここにもう一度記載します。

  1. プロジェクトフォルダーで次のコマンドを実行し、lightrunエージェントをインストールします。npm install lightrun

  2. Node.jsアプリケーションのコードベースの冒頭、つまりエントリーポイントとなるapp.jsファイルで、次のようにLightrunエージェントを初期化します(登録手続き中に、<YOUR-COMPANY-NAME>と<YOUR-COMPANY-SECRET>の値が画面に表示されます)。

    require('lightrun').start({ company: '', apiEndpoint: 'app.lightrun.com', lightrunSecret: '', caPath: '',});

コード内にシークレットがあるという警告を見過ごすわけにはいきません。ここまで来たら、まずlightrunSecretのコード行を次のように変更してください。

require('lightrun').start({
    company: '<YOUR-COMPANY-NAME>',
    apiEndpoint: 'app.lightrun.com',
    lightrunSecret: '<YOUR-COMPANY-SECRET>',
    caPath: '',
});

アプリケーションをローカルで起動するときは、この環境変数を事前に利用できるようにしておきましょう。コマンドラインからアプリケーションを実行する場合は、次のように設定できます。

lightrunSecret: process.env.LIGHTRUN_API_KEY

注: exportコマンドを実行するのは一度だけで構いません。同じターミナルのシェルセッションを使い続ける限り、環境変数を利用できます。

アプリケーションを起動すると、右側のサイドバーにLightrunプラグインが適切に設定され、接続されていることが表示されます。マシン名の注記で確認できます(私の場合は「Lirans-MBP」です)。

export LIGHTRUN_API_KEY=<YOUR-COMPANY-SECRET>
npm run start

本番環境のNode.jsアプリケーションで有害なユーザー入力を見つける方法

今回試すNode.jsアプリケーションは、SnykのGoof TODOアプリケーションです。JavaScriptとNode.jsで構築された、エンドツーエンドのTo-Doメモアプリです。

GitHubプロジェクトをクローンしてコピーを入手し、一般的なnpmプロジェクトと同じ手順で依存関係をインストールすれば、すぐに始められます。起動時に接続するMongoDBデータベースも必要です。

起動すると、以下のスクリーンショットのように表示されます。このアプリケーションには興味深い機能があります。たとえば、Get my app secured in 15 minutesのようなTo-Do文字列を送ると、オープンソースのhumanize-ms npm packageを使って、15 minutesという文字列を[15m]という形式に変換します。humanize-msパッケージは週に約4,500,000回ダウンロードされており、良い選択肢のように見えます。

アプリケーションセキュリティ、IDEプラグイン、オブザーバビリティとセキュリティに関するタスクが表示された「Goof TODO」アプリのブラウザーウィンドウ。

セキュリティ意識が高く、過去にバックエンドアプリケーションの開発経験がある方なら、入力が何らかの検証や想定されるスキーマに適合するようにしているでしょう。

しかし、このアプリケーションはすでに本番環境で稼働しています。どのようなユーザー入力が届いているかは分かりませんし、機能を壊したくもありません。一方で、受け取る可能性のある危険なユーザー入力については把握したいところです。ここでLightrunが力を発揮します!

10,000文字を超える文字列を含むユーザー入力が送信された場合に、アラートを記録したいと思います。そのために、IntelliJでユーザー入力テキストを解析するコード行に、条件付きのLightrunログを追加します。次のようになります。

ログ、仮想ブレークポイント、メトリクス、スナップショット、設定、ログアウトのオプションを表示するLightrunメニューを備えたコードエディター

コード行を右クリックし、注釈の種類としてLogを選択して、次のようにログルールを設定します。item.length>10000

index.jsの162行目に設定された「Create Log」ダイアログを表示するコードエディター。条件は item.length > 10000。

これにより、稼働中のNode.jsアプリケーションにアラートが設定されます。このコードパスに到達したリクエストのうち、入力の長さが10,000文字を超えて条件に合致したものが対象になります。

アクションを追加すると、そのコード行に便利な注釈が表示され、追加したユーザーも分かります。将来、技術的負債の解消やリファクタリングを担当する開発者の注意を引き、重要な情報を伝えるうえで役立ちます。

ユーザー入力を解析し、内容と更新日を含む新しいTodoを保存するJavaScriptを表示したダークテーマのコードエディター

IDEからアラートを追加できるのは便利ですが、さらに素晴らしいのは、ログを確認するために新しいWebページを開かずに、IDEのコンソールですぐにアラートを確認できることです。

これを実現するには、Lightrunプラグインの右側のサイドバーを開き、エージェントの項目で一番右にあるPIPEアイコンをクリックします。次に、Bothボタンをクリックします。これでアラートログがLightrun SaaSアプリと、IDEのLightrunコンソールウィンドウの両方に送信されます。やった!

Lirans-MBPの本番エージェント、index.jsの162行目、App、Plugin、Bothの選択肢が表示されたメニューを示すダークテーマのアプリケーション画面。

アラートを設定できたので、大きなペイロードを送って試してみましょう。ペイロードの送信には、手元にある便利なコマンドラインツールをいくつか使います。

  1. Oh My Zshのシェル環境(見た目のいいシェルプロンプトが嫌いな人はいませんよね?)

  2. To-Do項目を追加するHTTPリクエストの送信にはHTTPieツール

  3. 文字を指定した回数だけ簡単に繰り返せるUnixのseqツール

これらを使って、次のコマンドでペイロードを送信します。

echo 'content=Buy milk in 'seq -s "" -f "5" 60000 'minutes' | http --form http://localhost:3001/create -v

これにより、Buy milk in 500000... minutesというTo-Doテキストが作成されます。数字5の後ろにゼロが60,000個続く、かなり長い文字列です。

アプリケーションの画面では、次のように表示されます。

「Goof TODO」アプリのタスクを表示したブラウザーウィンドウ。牛乳を買う、アプリをセキュリティで保護する、IDEプラグインをダウンロードする、オブザーバビリティとセキュリティに関するタスクが含まれている。

ご覧のとおり、アプリケーションもMongoDBデータベースもクラッシュしていません。副作用は、humanize-ms npmパッケージがその時間を単にInfinityという文字列に解析したことのようです。全体としては妥当な動作で、実際の問題ではなさそうです。たぶん。

IDEでアラートを設定したことを覚えていますか?

どのように表示されるか見てみましょう……

Lightrun Consoleウィンドウでハイライトされている行が見えますか?本番稼働中のアプリケーションに送信されたHTTPリクエストのうち、ログ条件に合致したものについて、IDE上でアラートを受け取っています。とても便利ですね!(本当に役立ちます!)

ダークテーマのコードエディターにJavaScript、Lightrunパネル、危険な可能性のある長いユーザー入力に関する警告を表示したコンソールが表示されている。

でも、このアラートがそんなに重要なのはなぜでしょう?続きを見ていきましょう……

コードやオープンソース依存関係に潜むセキュリティ問題を検出して修正する方法

どうやら、このバージョンのhumanize-ms npm packageには、間接的なセキュリティ脆弱性がいくつかあるようです。週に4,500,000回ダウンロードされているからといって、安全とは限りませんでした。このパッケージの脆弱性は、Node.jsのWebアプリケーションに深刻な影響を及ぼす可能性があります。

どうして分かったのでしょうか?Snyk IntelliJ pluginをインストールしてプロジェクトをスキャンしたところ、この脆弱性をはじめ、いくつかの脆弱性が検出されたからです。スキャンの実行方法と、このセキュリティ脆弱性の深刻さを、Lightrunで大きなユーザー入力ペイロードのアラートを使って確認してみましょう。

Snyk IntelliJ pluginをインストールして認証したら(手順についてはプラグインのインストール方法をご覧ください)、Snykプラグインのウィンドウで緑色のPlayボタンをクリックして、セキュリティスキャンを開始します。

スキャンでは、次のような潜在的なセキュリティ問題が検出されます。

  1. コードベースにインポートされたnpmパッケージなど、サードパーティのオープンソースライブラリに含まれるセキュリティ脆弱性。Java、Ruby、Pythonなど、他の言語のプロジェクトをスキャンする場合も、Snykがパッケージマニフェストファイルを自動的に検出してスキャンします。

  2. 独自コードに含まれるコードセキュリティの問題。現在、JavaScript、TypeScript、Java、Pythonに対応しています。

このTODOプロジェクトの依存関係として追加したサードパーティのnpmパッケージを、Snyk Open Sourceでセキュリティスキャンした結果をご覧ください。

Todoの保存関数を表示するJavaScriptコードエディターと、オープンソースのセキュリティ脆弱性を一覧表示するSnykパネル

結果をスクロールしていくと、このTODOアプリケーションにかなり多くのセキュリティ脆弱性が含まれていることが分かります。これは、こうした脆弱性とその修正方法を実演し、練習し、学べるように意図的に脆弱性を含めたアプリケーションです。

時間文字列の解析と整形に使っているhumanize-ms npmパッケージを覚えていますか?どうやら、このパッケージは一般的なms npm packageの脆弱なバージョン範囲に依存しているため、正規表現によるサービス拒否(ReDoS)の脆弱性を引き起こすようです。

クロスサイトスクリプティング、プロトタイプ汚染、正規表現によるサービス拒否の問題が表示された、ダークテーマのコードエディターとSnykの脆弱性検出結果。

セキュリティ攻撃のペイロードに戻って、もう一度見てみましょう。

echo 'content=Buy milk in 'seq -s "" -f "5" 60000 'minutes' | http --form http://localhost:3001/create -v

このコマンドを実行すると、非常に長い文字列がTo-Do項目として送信されますが、見たところサービス拒否は発生しませんでした。アプリケーションは通常どおりリクエストを処理し続け、Node.jsアプリケーションはほぼ即座に応答を返しました。

しかし、正規表現は……扱いが難しいものです。正しく記述されていないと、破滅的なバックトラッキングが発生する可能性があります。つまり、線形の入力に対する計算に、超線形の時間がかかるということです。

このアプリケーションを効果的に攻撃するために、攻撃ペイロードで変更するのはminutesをminuteaに置き換えることだけです。そのうえでコマンドを送信します。実行前後を比べられるよう、リクエストを送信する前の画面と、ノートPCの通常のCPU使用状況を表示するhtopコマンドのスクリーンショットを見てみましょう。

JavaScriptコードやターミナルのプロセス、正規表現によるサービス拒否の脆弱性の詳細を示すSnykパネルが表示された、開発者の作業環境。

ReDoSの脆弱性がある場合、Node.jsアプリケーションは正規表現の計算にかなりの時間がかかり、Node.jsのアーキテクチャはシングルスレッドであるため、その後のすべてのリクエストが滞ると予想されます。正規表現の計算に利用可能なリソースをすべて消費し、CPU使用率は100%まで急上昇します。

ReDoS攻撃のペイロードを送信してみましょう。

echo 'content=Buy milk in 'seq -s "" -f "5" 60000 'minutea' | http --form http://localhost:3001/create -v

ご覧ください!右上のターミナル画面には送信したHTTPリクエストが表示されていますが、すぐには応答がありません。左下のターミナル画面では、Node.jsプロセスが表の最上部で緑色にハイライトされ、CPUリソースを98.4%消費しています。

JavaScriptコード、ターミナルのプロセス、文字が繰り返し表示されたコンソール、Snykの脆弱性情報が表示されたダークモードの開発者向けワークスペース。

次は、これらのセキュリティ問題を修正しましょう。プロジェクトをSnykアプリケーションにインポートすると、バックグラウンドで継続的にスキャンおよび監視されます。また、GitHubなどのGitリポジトリにプルリクエストを自動的に作成し、プロジェクト内の脆弱なバージョンをアップグレードします。詳しくは、Snyk Open Sourceを始める方法の記事をご覧ください。

開発者ファーストのセキュリティと可観測性

LightrunやSnykのような開発者ファーストのツールは、開発者をワークフローから引き離すのではなく、必要なデータを開発者に届けることで、日々の開発作業における生産性向上を支援します。

IntelliJ IDEやコマンドラインで可観測性とセキュリティを活用すると、開発者はリアルタイムのトラフィックを監視し、問題が継続的インテグレーションサーバーに到達する前、ましてや本番環境に到達する前に、セキュリティ上の問題を発見して修正できます。

両方の利用を始めるには、次のリソースをご覧ください。

  1. Snykを使い始める

  2. Lightrunを使い始める

CTFを始めよう

オンデマンドのバーチャル入門ワークショップで、CTFチャレンジの解き方を学びましょう。

続きを読む

Blog

フロンティアモデルは脆弱性を発見した。攻撃者だけがエクスプロイトチェーンを見つけた。

静的解析で欠陥は見つかりましたが、ライブ攻撃テストで侵害につながる連鎖を実証できたのは唯一でした。Evo COS、Claude Security、Claude Code Securityを比較します。

feature insights context
Blog

自律型攻撃はすでに始まっている。防御もそのスピードに追いつかなければならない。

自律型攻撃者によって、防御に使える時間は短くなっています。継続的な検出、修復、検証、予防で、セキュリティチームが攻撃に歩調を合わせる方法をご紹介します。

Blog

AIコーディングエージェントが不適切なアクセス制御を繰り返し実装する理由

AIコーディングエージェントは、コンパイルが通りレビューも通過する一方で、あるテナントのデータを別のテナントに公開してしまう認可ロジックを生成することがあります。不適切なアクセス制御が検出しにくい理由と、その防止策をご紹介します。