security-vite について
Vite アプリの開発者向けセキュリティ監査スキルです。環境変数、ビルド設定、SPA 特有の脆弱性を確認するコマンドと強化チェックリストを提供します。
主な機能
- 01VITE_ 環境変数の露出確認
- 02ビルド時の秘密情報注入の確認
- 03開発サーバーのネットワーク公開確認
- 04SPA のクライアント側認証リスクの特定
- 05本番バンドル内の秘密情報とソースマップの確認
- 06監査コマンドと強化チェックリスト
活用シーン
- 01.env ファイル内の機密変数の監査
- 02vite.config.ts への秘密情報注入の確認
- 03開発サーバーの意図しない公開の評価
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ igorwarzocha/ opencode-workflows --skill security-viteインストール後、Claude Code で/security-viteを入力して読み込まれたか確認します。
同梱ファイルscripts/scan.sh
詳細
Vite アプリケーションを対象に、環境変数の露出、ビルド時のシークレット、SPA 固有の脆弱性に焦点を当てたセキュリティ監査パターンです。
環境変数の露出
VITE_ の落とし穴
VITE_* → Bundled into client JavaScript → Visible to everyone
No prefix → Only available in vite.config.ts → Safe for secrets
監査手順:
grep -r "VITE_" . -g "*.env*"- ソースコード内で
import.meta.env.VITE_*の使用箇所を確認します - よくある間違い:
VITE_API_SECRET(サーバー側専用にする必要があります)VITE_DATABASE_URL(使用してはいけません)VITE_STRIPE_SECRET_KEY(公開可能キーのみ使用します)
環境変数ファイルの優先順位
Vite は次の順序で読み込みます(後のものが前のものを上書きします):
.env # Always loaded
.env.local # Always loaded, gitignored
.env.[mode] # e.g., .env.production
.env.[mode].local # e.g., .env.production.local, gitignored
確認事項: .env.local と .env.*.local は .gitignore に含まれていますか?
envPrefix の上書き
envPrefix が設定されている場合、Vite はそのプレフィックスを持つすべての変数を公開します。envPrefix はセキュリティ上重要な設定として扱ってください。
ビルド時と実行時
危険:vite.config.ts 内のシークレット
// ❌ Secret in config (ends up in bundle)
export default defineConfig({
define: {
'process.env.API_KEY': JSON.stringify(process.env.API_KEY),
},
});
// The above makes API_KEY available in client code!
安全なパターン
// Only use VITE_ prefix for truly public values
export default defineConfig({
define: {
'__APP_VERSION__': JSON.stringify(process.env.npm_package_version),
},
});
// Keep secrets on server (use a backend API)
開発サーバーのセキュリティ
ネットワークへの公開
// ❌ Exposes dev server to network
export default defineConfig({
server: {
host: '0.0.0.0', // or host: true
},
});
共有ネットワークでは危険です。意図した設定かどうかを確認してください。
プロキシの設定ミス
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
// ❌ Missing secure options for production-like setup
},
},
},
});
SPA のセキュリティ上の問題
クライアント側の認証のみ
// ❌ "Protection" only in React Router
const ProtectedRoute = ({ children }) => {
const { user } = useAuth();
if (!user) return <Navigate to="/login" />;
return children;
};
// API calls still need server-side auth!
// This is UI convenience, not security.
バンドル内のシークレット
# Check the built bundle for secrets
rg -a "(sk_live|sk_test|AKIA|api[_-]?key)" dist/
本番環境のソースマップ
// Check vite.config.ts
export default defineConfig({
build: {
sourcemap: true, // ❌ Exposes source code in production
},
});
<severity_table>
よくある脆弱性
| 問題 | 確認箇所 | 深刻度 |
|---|---|---|
| VITE_* のシークレット | .env*、ソースファイル | 重大 |
| define 内のシークレット | vite.config.ts | 重大 |
| 本番環境のソースマップ | vite.config.ts | 中 |
| 開発サーバーの公開 | vite.config.ts server.host | 中 |
| クライアント側のみの認証 | API 認証のないルートガード | 高 |
| バンドル内の API キー | dist/ ディレクトリ | 重大 |
</severity_table>
監査用クイックコマンド
# Find VITE_ secrets
grep -r "VITE_" . -g "*.env*"
# Find import.meta.env usage
rg 'import\.meta\.env' . -g "*.ts" -g "*.tsx" -g "*.vue"
# Check define in config
rg 'define:' vite.config.*
# Scan built bundle for secrets
rg -a "(sk_live|AKIA|ghp_|api[_-]?key['\"]?\s*[:=])" dist/
# Check for source maps
fd '\.map$' dist/
セキュリティ強化チェックリスト
-
VITE_*変数にシークレットが含まれていない -
.env.localと.env.*.localが.gitignoreに含まれている - 本番ビルドで
sourcemap: falseが設定されている -
server.hostが0.0.0.0またはtrueではない(意図した設定の場合を除く) - 機密性の高い API 呼び出しはすべてバックエンド経由で行われている(ブラウザーから直接行っていない)
-
vite.config.tsの define ブロックにシークレットが含まれていない
コメント
Markdown 対応