Bagikan melalui


UseConstrainedLanguageMode

Tingkat Tingkat Keparahan: Peringatan

Deskripsi

Aturan ini mengidentifikasi pola PowerShell yang dibatasi atau tidak diizinkan dalam Mode Bahasa Terbatas (CLM).

Mode Bahasa Terbatas adalah fitur keamanan PowerShell yang membatasi:

  • Jenis .NET yang dapat digunakan
  • Objek COM yang dapat dibuat
  • Perintah yang dapat dieksekusi
  • Fitur bahasa yang dapat digunakan

CLM biasanya digunakan dalam:

  • Lingkungan Kontrol Aplikasi (Kontrol Aplikasi untuk Bisnis, AppLocker)
  • Titik akhir Administrasi yang Cukup (JEA)
  • Lingkungan aman yang memerlukan pembatasan PowerShell tambahan

Skrip yang ditandatangani secara digital dari penerbit tepercaya dijalankan dalam Mode Bahasa Penuh (FLM) bahkan di lingkungan CLM. Aturan mendeteksi blok tanda tangan (# SIG # Begin signature block) dan menyesuaikan pemeriksaan yang sesuai. Sebagian besar pembatasan tidak berlaku untuk skrip yang ditandatangani, tetapi pemeriksaan tertentu (sumber titik, jenis parameter, praktik terbaik manifes) selalu diterapkan.

Penting

Aturan ini melakukan pemeriksaan teks sederhana untuk blok tanda tangan dan TIDAK memvalidasi keaslian tanda tangan atau kepercayaan sertifikat. Validasi tanda tangan aktual dilakukan oleh PowerShell saat runtime.

Batasan Mode Bahasa Terbatas

Skrip yang Tidak Ditandatangani (Pemeriksaan CLM Penuh)

Berikut ini ditandai untuk skrip yang tidak ditandatangani:

  1. Add-Type - Kompilasi kode tidak diizinkan
  2. Objek COM yang Tidak Diizinkan - Hanya Scripting.Dictionary, Scripting.FileSystemObject, VBScript.RegExp yang diizinkan
  3. Jenis .NET yang Tidak Diizinkan - Hanya ~70 jenis yang diizinkan (string, int, hashtable, pscredential, dll.)
  4. Batasan Jenis - Pada parameter dan variabel
  5. Ekspresi Jenis - Referensi jenis statis seperti [Type]::Method()
  6. Jenis Cast - Mengonversi ke jenis yang tidak diizinkan
  7. Pemanggilan Anggota - Metode/properti pada jenis yang tidak diizinkan
  8. Kelas - classPowerShell kata kunci tidak diizinkan
  9. XAML/WPF - Tidak diizinkan
  10. Invoke-Expression - Dibatasi
  11. Dot-Sourcing - Mungkin dibatasi tergantung pada file yang bersumber
  12. Karakter Karakter Ganti Manifes Modul - Ekspor karakter pengganti tidak disarankan
  13. File .ps1 Manifes Modul - Modul skrip yang diakhiri dengan .ps1 tidak diizinkan

Selalu diterapkan, bahkan untuk skrip yang ditandatangani

Skrip yang Ditandatangani (Pemeriksaan Selektif)

Untuk skrip dengan blok tanda tangan, hanya ini yang dicentang:

  • Sumber titik
  • Batasan jenis parameter
  • Karakter pengganti manifes modul (file .psd1)
  • Modul skrip manifes modul (file .psd1)

Konfigurasi

Konfigurasi Dasar

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

Parameter-parameternya

Aktifkan: bool (Nilai default adalah $false)

Aktifkan atau nonaktifkan aturan selama pemanggilan ScriptAnalyzer. Aturan ini dinonaktifkan secara default karena tidak semua skrip memerlukan kompatibilitas CLM.

IgnoreSignatures: bool (Nilai default adalah $false)

Kontrol perilaku deteksi tanda tangan:

  • $false (default): Mendeteksi tanda tangan secara otomatis. Skrip yang ditandatangani mendapatkan pemeriksaan selektif, tidak ditandatangani mendapatkan pemeriksaan penuh.
  • $true: Lewati deteksi tanda tangan. SEMUA skrip mendapatkan pemeriksaan CLM penuh terlepas dari status tanda tangan.
@{
    Rules = @{
        PSUseConstrainedLanguageMode = @{
            Enable = $true
            IgnoreSignatures = $true  # Enforce full CLM compliance for all scripts
        }
    }
}

Gunakan IgnoreSignatures = $true saat:

  • Mengaudit skrip yang ditandatangani untuk kompatibilitas CLM lengkap
  • Menyiapkan skrip untuk lingkungan yang tidak tepercaya
  • Menegakkan kepatuhan CLM yang ketat di seluruh organisasi
  • Pengembangan/pengujian untuk melihat semua potensi masalah

Cara Memperbaiki

Ganti Add-Type

Gunakan cmdlet yang diizinkan atau rakitan pra-kompilasi.

Ganti Objek COM yang Tidak Diizinkan

Gunakan hanya objek COM yang diizinkan (Scripting.Dictionary, Scripting.FileSystemObject, VBScript.RegExp) atau cmdlet PowerShell.

Ganti Jenis yang Tidak Diizinkan

Gunakan akselerator jenis yang diizinkan ([string], [int], , [hashtable]dll.) atau cmdlet yang diizinkan alih-alih jenis .NET yang tidak diizinkan.

Mengganti Kelas PowerShell

Gunakan New-Object PSObject dengan atau hashtables alih-alih Add-Member kelas.

Penting

[PSCustomObject]@{} sintaks TIDAK diizinkan di CLM karena menggunakan jenis casting.

Hindari XAML

Jangan gunakan WPF/XAML dalam skrip yang kompatibel dengan CLM.

Ganti Invoke-Expression

Gunakan eksekusi langsung (&) atau alternatif yang lebih aman.

Ganti Dot-Sourcing

Gunakan modul dengan Import-Module alih-alih dot-sourcing jika memungkinkan.

Perbaiki Manifes Modul

  • Ganti ekspor karakter pengganti (*) dengan daftar eksplisit.
  • Gunakan .psm1 atau .dll sebagai pengganti .ps1 untuk RootModule/NestedModules.
  • Jangan gunakan ScriptsToProcess. Skrip ini dimuat dalam cakupan penelepon dan diblokir.

Examples

Contoh 1: Add-Type

Salah

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

Benar

 # Code sign your scripts/modules using proper signing tools
 #   (for example, Set-AuthenticodeSignature or external signing processes)
 # Use allowed cmdlets instead of Add-Type-defined types where possible
 # Or pre-compile, sign, and load the assembly (for example, via Add-Type -Path)

Contoh 2: Objek COM

Salah

$excel = New-Object -ComObject Excel.Application

Benar

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

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

Contoh 3: Jenis yang Tidak Diizinkan

Salah

# 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)

Benar

# 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
}

Contoh 4: Kelas PowerShell

Salah

class MyClass {
    [string]$Name

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

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

Benar

# 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
}

Contoh 5: Manifes Modul

Salah

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

Benar

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

Contoh 6: Jenis Array

Salah

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

Benar

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

Pembatasan Terperinci

1. Add-Type

Add-Type memungkinkan kompilasi kode C# arbitrer dan tidak diizinkan di CLM.

Diberlakukan Untuk: Hanya skrip yang tidak ditandatangani

2. COM Objek

Hanya tiga objek COM yang diizinkan:

  • Scripting.Dictionary
  • Scripting.FileSystemObject
  • VBScript.RegExp

Semua lainnya (Excel.Application, WScript.Shell, dll.) ditandai.

Diberlakukan Untuk: Hanya skrip yang tidak ditandatangani

3. Jenis .NET

Hanya ~70 jenis yang diizinkan termasuk:

  • Primitif: string, , int, datetimedoubleboolbytechardecimaldll.
  • Koleksi: hashtable, , arrayarraylist
  • PowerShell: pscredential, , psobjectsecurestring
  • Utilitas: regex, , guid, version, uri, xml
  • Array: string[], int[][], dll. (array dari jenis apa pun yang diizinkan)

Aturan memeriksa penggunaan jenis di:

  • Batasan jenis parameter (selalu diterapkan, bahkan untuk skrip yang ditandatangani)
  • Batasan jenis variabel
  • New-Object -TypeName
  • Ketik ekspresi ([Type]::Method())
  • Jenis pemeran ([Type]$variable)
  • Pemanggilan anggota pada variabel yang diketik

Diterapkan untuk: Batasan parameter selalu; yang lain hanya tidak ditandatangani

4. Kelas PowerShell

class Kata kunci tidak diizinkan. Gunakan New-Object PSObject dengan Add-Member atau hashtables.

Catatan: [PSCustomObject]@{} juga tidak diperbolehkan karena menggunakan jenis casting.

Diberlakukan Untuk: Hanya skrip yang tidak ditandatangani

5. XAML / WPF

XAML dan WPF tidak diizinkan di CLM.

Diberlakukan Untuk: Hanya skrip yang tidak ditandatangani

6. Invoke-Expression

Invoke-Expression dibatasi di CLM.

Diberlakukan Untuk: Hanya skrip yang tidak ditandatangani

7. Dot-Sourcing

Dot-sourcing (. $PSScriptRoot\script.ps1) mungkin dibatasi tergantung pada lokasi sumber.

Diberlakukan Untuk: SEMUA skrip (tidak ditandatangani dan ditandatangani)

8. Praktik Terbaik Manifes Modul

Ekspor Wildcard

Jangan gunakan * di: FunctionsToExport, CmdletsToExport, AliasesToExport, VariablesToExport

Gunakan daftar eksplisit untuk keamanan dan kejelasan.

Diberlakukan Untuk: SEMUA file .psd1 (tidak ditandatangani dan ditandatangani)

File Modul Skrip

Jangan gunakan .ps1 file di: RootModule, ModuleToProcess, NestedModules

Gunakan .psm1 (modul skrip) atau .dll (modul biner) untuk kinerja dan kompatibilitas yang lebih baik.

Diberlakukan Untuk: SEMUA file .psd1 (tidak ditandatangani dan ditandatangani)

Informasi Lainnya