UseConstrainedLanguageMode

重症度レベル:警告

デフォルト状態:無効化

説明

このルールは、制限された言語モード(CLM)で制限されたり許可されていないPowerShellパターンを検出します。 スクリプトがApp Control for Business、AppLocker、Just Enough Administration(JEA)などの制限されたPowerShell環境と互換性を保つ必要がある場合に利用してください。 このルールはデフォルトで 無効 化されています。

CLMはPowerShellのセキュリティ機能であり、以下を制限します:

  • 使用できる.NET型
  • インスタンス化可能なコンポーネントオブジェクトモデル(COM)オブジェクト
  • 実行可能なコマンド
  • 利用可能な言語機能

CLMは一般的に以下で使われます:

  • アプリケーション制御環境(ビジネス用アプリケーション制御、AppLocker)
  • Just Enough Administration(JEA)エンドポイント
  • 他のPowerShell制限を必要とするセキュア環境

信頼できる出版社からのデジタル署名スクリプトは、CLM環境でもフルランゲージモード(FLM)で動作します。 このルールはシグネチャブロック(# SIG # Begin signature block)を検出し、それに応じてチェックを調整します。 ほとんどの制限は署名済みスクリプトには適用されませんが、一部のチェックは依然として適用されます。

Important

このルールは署名ブロックの簡単なテキストチェックを行い、署名の真正性や証明書の信頼度は検証しません。 PowerShellは実行時に実際のシグネチャ検証を行います。

CLM制限および修復基準

以下の表を使って、各CLM制限の意味、推奨される対策、署名済みスクリプト、署名なしスクリプト、または両方にチェックが適用されるかをまとめて表示してください。

制限 意味 推奨される修復方法 強制された
Add-Type Add-Type 任意のC#コードをコンパイルしますが、これはCLMでは許可されていません。 許可されたコマンドレットを使うか、事前コンパイル、署名、ロードアセンブリを使います。 署名なし脚本のみ
許可されていないCOMオブジェクト 許可されているのは Scripting.Dictionary、 Scripting.FileSystemObject、 VBScript.RegExp のみです。 他のCOMオブジェクト(例えばExcel.Application)はフラグが付けられています。 許可されているCOMオブジェクトのいずれかを使うか、COMの使用をPowerShellコマンドレットに置き換えてください。 署名なし脚本のみ
禁止された.NET型 許可されている.NETおよびタイプ加速器タイプは約70種類のみです。 これらの型には、一般的なプリミティブ、選択されたコレクション、PowerShell固有の型、ユーティリティ、そして許可された型の配列が含まれます。 [string]、[int]、[hashtable]などの許可された型に置き換えるか、直接的な禁止型使用を避けるコマンドレットを使うことができます。 パラメータ型制約は常に強制されます。その他の.NETタイプのチェックは署名のないスクリプトにのみ適用されます
型制約 パラメータや変数の型制約はCLMの互換性を確認する。 制約で許可された型を使い、特にパラメータ宣言で活用しましょう。 パラメータ制約は常に強制されます。変数制約は符号なしスクリプトのみです
型式 [Type]::Method()のような静的参照は、禁止された型を使うとフラグが立てられます。 CLM互換のコマンドレットベースのパターンや許容型の使用に置き換えてください。 署名なし脚本のみ
タイプキャスト 禁止されたタイプへのキャストはフラグが立てられます。 鋳型を外すか、許可された種類に鋳型してください。 署名なし脚本のみ
メンバーの祈願 禁止された型付きオブジェクトに対するメソッドやプロパティ呼び出しはフラグが付けられます。 許可されていない型付きオブジェクトの代わりに、許容型とCLM互換コマンドレットを使用してください。 署名なし脚本のみ
PowerShell クラス classキーワードはCLMでは許可されていません。 New-Object PSObjectをAdd-Memberと組み合わせるか、ハッシュテーブルを使うのが良いでしょう。 タイプキャスティングを使うので [PSCustomObject]@{} 避けてください。 署名なし脚本のみ
XAMLまたはWPF CLMではXAMLやWPFの使用は許可されていません。 CLM互換スクリプトではXAMLやWPFは避けてください。 署名なし脚本のみ
Invoke-Expression Invoke-Expression CLMでは制限されています。 直接召喚(&)やより安全な代替手段を使いましょう。 署名なし脚本のみ
ドットソーシング ドットソーシングは、出典の場所によって制限されることがあります。 可能な限り、ドットソーシングよりもモジュールや Import-Module を好む。 全脚本(署名・無署名)
モジュールマニフェストワイルドカード FunctionsToExport、CmdletsToExport、AliasesToExport、VariablesToExportのワイルドカードは推奨されず、CLMの文脈ではブロックされることがあります。 *を明示的なエクスポートリストに置き換えましょう。 すべての .psd1 ファイル(署名済み・署名なし)
モジュールマニフェスト .ps1 ファイル .ps1、RootModule、ModuleToProcessにNestedModulesを使おうとする試みはCLMに優しくありません。 .psm1(スクリプトモジュール)または.dll(バイナリモジュール)を使ってください。 ScriptsToProcessは避けてください。 すべての .psd1 ファイル(署名済み・署名なし)

例示

Add-Type

非準拠

Add-Type -TypeDefinition @"
    public class Helper {
        public static string DoWork() { return "Done"; }
    }
"@

対応

# Sign your scripts or modules by using appropriate signing tools
# (for example, Set-AuthenticodeSignature or an external signing process).
# Use allowed cmdlets instead of Add-Type-defined types where possible.
# Or precompile, sign, and load the assembly (for example, by using Add-Type -Path).

COM オブジェクト

非準拠

$excel = New-Object -ComObject Excel.Application

対応

# Use allowed COM object
$dict = New-Object -ComObject Scripting.Dictionary

# Or use PowerShell cmdlets
Import-Excel -Path $file  # From ImportExcel module

禁止されたタイプ

非準拠

# Type constraint and member invocation flagged
function Download-File {
    param([System.Net.WebClient]$Client)
    $Client.DownloadString($url)
}

# Type cast and method call flagged
[System.Net.WebClient]$client = New-Object System.Net.WebClient
$data = $client.DownloadData($url)

対応

# Use allowed cmdlets
function Download-File {
    param([string]$Url)
    Invoke-WebRequest -Uri $Url
}

# Use allowed types
function Process-Text {
    param([string]$Text)
    $upper = $Text.ToUpper()  # String methods are allowed
}

PowerShell クラス

非準拠

class MyClass {
    [string]$Name

    [string]GetInfo() {
        return $this.Name
    }
}

# Also wrong - uses type cast
$obj = [PSCustomObject]@{
    Name = "Test"
}

対応

# Option 1: New-Object PSObject with Add-Member
$obj = New-Object PSObject -Property @{
    Name = "Test"
}

$obj | Add-Member -MemberType ScriptMethod -Name GetInfo -Value {
    return $this.Name
}

Add-Member -InputObject $obj -NotePropertyMembers @{"Number" = 42}

# Option 2: Hashtable
$obj = @{
    Name = "Test"
    Number = 42
}

モジュール マニフェスト

非準拠

@{
    ModuleVersion = '1.0.0'
    RootModule = 'MyModule.ps1'        # .ps1 not recommended
    FunctionsToExport = '*'             # Wildcard not recommended
    CmdletsToExport = '*'
}

対応

@{
    ModuleVersion = '1.0.0'
    RootModule = 'MyModule.psm1'       # Use .psm1 or .dll
    FunctionsToExport = @(              # Explicit list
        'Get-MyFunction'
        'Set-MyFunction'
    )
    CmdletsToExport = @()
}

配列の種類

非準拠

# Disallowed type in array
param([System.Net.WebClient[]]$Clients)

対応

# Allowed types in arrays are fine
param([string[]]$Names)
param([int[]]$Numbers)
param([hashtable[]]$Configuration)

ルールの設定

@{
    Rules = @{
        PSUseConstrainedLanguageMode = @{
            Enable = $true
        }
    }
}

パラメーター

Enable

このパラメータは、ScriptAnalyzerがこのルールに対してコードをチェックするかどうかを制御します。 ブール値も受け入れます。 このルールを有効にするには、このパラメータを $trueに設定します。 既定値は $false です。

署名を無視する

このパラメータは、ルールがシグネチャ検出をどのように扱うかを制御します。 ブール値も受け入れます。 既定値は $false です。

このパラメータが $falseに設定されると、スクリプトが署名されているかどうかを自動的に検出します。 署名付きスクリプトは選択的なCLMチェックを受け、署名されていないスクリプトは完全なCLMチェックを受けます。

このパラメータが $trueに設定されると、ScriptAnalyzerは署名検出をスキップし、署名の状態に関係なくすべてのスクリプトに完全なCLMチェックを適用します。

その行動は以下の通りです:

  • $false (デフォルト):シグネチャーを自動的に検出。 署名済みスクリプトは選択的にチェックされます。 署名されていない脚本には全額の小切手が支払われます。
  • $true:シグネチャー検出をバイパス。 すべてのスクリプトは署名の有無に関わらず完全なCLMチェックを受けます。
@{
    Rules = @{
        PSUseConstrainedLanguageMode = @{
            Enable = $true
            IgnoreSignatures = $true  # Enforce full CLM compliance for all scripts
        }
    }
}

次のようなときは IgnoreSignatures = $true を使います。

  • 署名付きスクリプトの完全なCLM互換性の監査
  • 信頼できない環境向けのスクリプト準備
  • 組織全体での厳格なCLMコンプライアンスの施行
  • 開発やテストの際に、あらゆる潜在的な問題を把握するために

こちらも参照ください