【実務・中級編】【安全な資格情報一時保持】WScript.Shell の Volatile 環境変数を利用した同一セッション内での一時トークン受け渡し – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

【安全な資格情報一時保持】WScript.Shell の Volatile 環境変数を利用した同一セッション内での一時トークン受け渡し

システム連携や業務自動化の現場において、避けては通れないのが「認証情報(APIトークン、ワンタイムパスワード、セッションキーなど)のプロセス間共有」です。

多くの開発現場で、以下のような致命的な設計(アンチパターン)を目にします。

  • アンチパターン1: 処理Aが取得したトークンを、一時的に `C:\Temp\token.txt` などのローカルファイルに書き出し、処理Bがそれを読み込んで削除する。
  • アンチパターン2: コマンドライン引数にパスワードをそのまま渡して後続プロセスを起動する(タスクマネージャーやプロセス監視ログから平文で丸見えになる)。

これらは、ディスクへの書き込み痕跡(アーティファクト)が残るリスクや、異常終了時にファイルが削除されずに放置されるリスクを孕んでおり、現代のセキュリティ基準では「論外」と切り捨てられるべき設計です。

では、ファイルを使わず、かつ同一セッション内の別プロセス(VBScript、PowerShell、バッチファイル、あるいはVBAやVB.NET)に安全かつスマートに一時的な資格情報を引き渡すにはどうすべきか?

その最適解が、Windows Script Host (WSH) が提供する `WScript.Shell` の `Volatile`(揮発性)環境変数の活用です。

本記事では、この「Volatile環境変数」のライフサイクルを完全に掌握し、安全かつ堅牢に一時資格情報をバトンパスするための設計手法と、そのまま本番投入できる極限まで洗練されたVBScriptコード例を提示します。

—

1. なぜ「Volatile」なのか? 環境変数4つのスコープを理解する

WSH(`WScript.Shell`)オブジェクトを介してアクセスできる Windows の環境変数(`Environment`)には、以下の4つのスコープ(カテゴリ)が存在します。それぞれの特性とライフサイクルを正しく理解することが、堅牢な設計の第一歩です。

| スコープ | 格納場所 | ライフサイクル | 用途とセキュリティリスク |
| :— | :— | :— | :— |
| System | レジストリ(HKLM) | PC再起動後も永続 | システム全体の設定用。一般ユーザーは書き込み不可。 |
| User | レジストリ(HKCU) | ユーザーが削除するまで永続 | ユーザー固有の設定用。次回ログオン時も残るため、一時情報の保持には不適。 |
| Process | メモリ(プロセス毎) | プロセス終了時に消滅 | 自プロセスおよび子プロセスのみ有効。並列・後続の「別プロセス」には直接渡せない。 |
| Volatile | レジストリ(HKCUの一時領域) | サインアウト(ログオフ)時に自動消滅 | 同一ユーザーセッション内の一時データ共有に最適。 ディスクに永続化されない。 |

Volatile環境変数の圧倒的な優位性

`Volatile` に格納されたデータは、レジストリの `HKEY_CURRENT_USER\Volatile Environment` に一時的にマッピングされます。
この領域はユーザーがサインアウトした瞬間に、OSによって完全に消去されます。

万が一、スクリプトがクラッシュして「削除処理」を素通りしてしまったとしても、サーバーの再起動やユーザーのログオフによって資格情報は自動的に消滅するため、ファイルのように「長期間ディスクに放置される」という最悪のシナリオを防止できます。

—

2. 堅牢なバトンパス設計:3つの鉄則

Volatile環境変数は強力ですが、ただ書き込んで読み出すだけでは「プロの設計」とは言えません。以下の3つの鉄則を課すことで、エンタープライズ環境に耐えうる堅牢性を確保します。

1. 名前空間の衝突防止 (Name Spacing):
環境変数名はグローバルです。他アプリや同スクリプトの別インスタンスと衝突しないよう、ユニークなプレフィックス(例: `APP_TOKEN_` + ランダム値や特定用途名)を付与します。
2. 徹底した「用済み即削除」 (Immediate Revocation):
受信側(Reader)は、データを読み取った瞬間にその場で環境変数を削除(Remove)します。これにより、揮発性データの露出時間を最小限(ミリ秒単位)に抑え込みます。
3. 例外処理(エラーハンドリング)の義務化:
送信側・受信側ともに、途中でエラーが発生した場合でも必ずクリーンアップ(環境変数の破棄)が行われる構造にします。

—

3. 実装:プロレベルのプロダクションコード

ここからは、実際にコピペで動作し、エラーハンドリングやセキュリティ考慮が組み込まれた実用コードを示します。

想定シナリオ:

  • スクリプトA(Writer.vbs): 一時トークンを生成(またはAPIから取得)し、Volatile環境変数に格納して、後続のスクリプトBを起動する。
  • スクリプトB(Reader.vbs): Volatile環境変数からトークンを読み込み、即座に環境変数を消去した上で、本処理を行う。

【送信側】スクリプトA:`TokenWriter.vbs`

‘ ==============================================================================
‘ Script Name: TokenWriter.vbs
‘ Description: 安全に一時トークンをVolatile環境変数に書き込み、後続プロセスを起動する
‘ ==============================================================================
Option Explicit

Sub Main()
Dim shell, volatileEnv, tokenKey, tokenValue, targetScript

Set shell = CreateObject(“WScript.Shell”)

‘ 1. 安全な一意の環境変数キーを定義(プレフィックス付き)
tokenKey = “MYAPP_SECURE_TOKEN_SESSION”

‘ 2. 本来はAPI等から取得する一時トークン(擬似生成)
tokenValue = “SECURE_vbs_tok_” & Right(“000000” & Hex(Timer() 100), 8)

‘ 3. Volatile(揮発性)環境変数へ書き込み
On Error Resume Next
Set volatileEnv = shell.Environment(“Volatile”)
If Err.Number <> 0 Then
WScript.Echo “[ERROR] 環境変数領域へのアクセスに失敗しました: ” & Err.Description
WScript.Quit 1
End If

volatileEnv(tokenKey) = tokenValue
If Err.Number <> 0 Then
WScript.Echo “[ERROR] トークンの書き込みに失敗しました: ” & Err.Description
WScript.Quit 1
End If
On Error GoTo 0

WScript.Echo “[SYSTEM] 一時トークンをVolatile領域に退避しました。”
WScript.Echo “[DEBUG] Key: ” & tokenKey

‘ 4. 後続の受信スクリプト(TokenReader.vbs)を非同期で起動
‘ ※同一フォルダに TokenReader.vbs が存在することを想定
targetScript = “TokenReader.vbs”

On Error Resume Next
‘ wscript.exe でターゲットを起動(パスにスペースが含まれることを考慮してダブルクォーテーションで囲む)
shell.Run “wscript.exe “”” & targetScript & “”””, 1, False

If Err.Number <> 0 Then
WScript.Echo “[ERROR] 後続プロセスの起動に失敗しました: ” & Err.Description
‘ 起動失敗時は、ゴミを残さないために即時削除
volatileEnv.Remove tokenKey
WScript.Quit 1
End If
On Error GoTo 0

WScript.Echo “[SYSTEM] 後続スクリプトを起動しました。プロセスを終了します。”
End Sub

‘ 実行エントリーポイント
Call Main()

【受信側】スクリプトB:`TokenReader.vbs`

‘ ==============================================================================
‘ Script Name: TokenReader.vbs
‘ Description: Volatile環境変数からトークンを取り出し、即時削除した上で処理を行う
‘ ==============================================================================
Option Explicit

Sub Main()
Dim shell, volatileEnv, tokenKey, secureToken

Set shell = CreateObject(“WScript.Shell”)
tokenKey = “MYAPP_SECURE_TOKEN_SESSION”

‘ 1. Volatile環境変数領域にアクセス
On Error Resume Next
Set volatileEnv = shell.Environment(“Volatile”)
If Err.Number <> 0 Then
WScript.Echo “[ERROR] 環境変数領域へのアクセスに失敗しました。”
WScript.Quit 1
End If
On Error GoTo 0

‘ 2. トークンの読み出し
secureToken = volatileEnv(tokenKey)

‘ 3. 【最重要】読み出したら「即座に」レジストリから抹消する
‘ これにより、他のプロセスがこのトークンを覗き見ることができる時間を最小化する
If secureToken <> “” Then
On Error Resume Next
volatileEnv.Remove tokenKey
If Err.Number <> 0 Then
WScript.Echo “[WARNING] トークンの削除に失敗しました。手動削除が必要です。”
End If
On Error GoTo 0
Else
WScript.Echo “[ERROR] 認証トークンが見つかりません。セッションが無効です。”
WScript.Quit 1
End If

‘ 4. 取得した安全なトークンを用いて本処理を行う
Call ExecuteBusinessLogic(secureToken)

End Sub

‘ 本処理(ビジネスロジック)を記述するサブルーチン
Sub ExecuteBusinessLogic(ByVal token)
WScript.Echo “[SUCCESS] 認証トークンの受け渡しに成功しました。”
WScript.Echo “[PROCESS] トークン [” & token & “] を使用してセキュアな処理を実行中…”

‘ — ここに実際のWeb API呼び出しや、データベース接続処理を記述する —

End Sub

‘ 実行エントリーポイント
Call Main()

—

4. 開発リーダーが教える設計の裏側と、セキュリティ上の限界

「Volatile環境変数を使っていればセキュリティは100%安全」と思い込むのは、エンジニアとして危険な思考停止です。この手法の裏側にある「仕組み」と「限界」をしっかりと理解してください。

Q1. 他のユーザーからこのトークンは見えないのか?

見えません。
Volatile環境変数はレジストリの `HKEY_CURRENT_USER (HKCU)` に紐づいています。Windowsのセキュリティモデル上、他のログインユーザーが、別ユーザーの `HKCU` 領域を(管理者権限を持っていたとしても標準的な方法では)直接覗き見ることは困難です。ただし、同一ユーザーセッション内で動作している「他の悪意あるプログラム」からは読み取られるリスクがあります。
そのため、「読み取ったらミリ秒単位で即削除(`Remove`)」というロジックが必須となるのです。

Q2. エラーでスクリプトが落ちた場合の「ゴミ」はどうなる?

VBScriptで最も恐ろしいのは、予期せぬエラーによる強制終了(異常終了)です。
もし `TokenReader.vbs` が読み出しを行う前に異常終了した場合、レジストリにトークンが残ります。
しかし、前述の通りこれは Volatile(揮発性) です。
ユーザーがPCをシャットダウン、再起動、あるいはWindowsからサインアウト(ログオフ)した時点で、OSがレジストリごとこのキーを物理的に消滅させます。
ファイルに書き出した場合のように、「数ヶ月前のパスワードが `C:\temp\pass.txt` に残っていた」というような致命的な事態は構造的に発生しません。

Q3. PowerShellやVBA、VB.NETとの連携は可能か?

完全に可能です。
Windowsのシステムレベルで環境変数が共有されているため、送信側がVBScriptで、受信側がPowerShell (`$env:MYAPP_SECURE_TOKEN_SESSION`) であっても、何の問題もなくデータのバトンパスが可能です。
以下に、PowerShellで受け取る場合のワンライナーを示します。

PowerShell側でのセセキュアな取得と即時削除の例
$token = [System.Environment]::GetEnvironmentVariable(“MYAPP_SECURE_TOKEN_SESSION”, “User”)
※Volatile環境変数は.NETからは”User”スコープ、またはレジストリ直接参照で取得します。

—

まとめ

業務自動化の現場では、「動けばいい」という甘い考えで書かれたスクリプトが、重大なセキュリティホール(シャドーITや認証情報の漏洩)を作り出します。

  • 情報はファイルに書かない。
  • 引数でパスワードを渡さない。
  • 同一セッションでの一時保持には、サインアウトで消える `Volatile` 環境変数を選ぶ。
  • 取得した瞬間に `Remove` し、メモリ上のみで処理する。

この一連のライフサイクル設計を徹底することで、あなたの作成するスクリプトは「ただの自動化ツール」から「エンタープライズ品質のセキュアプログラム」へと昇華します。ぜひ、今日の開発からこのテクニックを標準化してください。

タイトルとURLをコピーしました