Bezpieczeństwo: credentiale, SecureString, brak haseł w kodzie
Probe'y ZEUS łączą się z kontrolerami domeny i zdalnymi maszynami — operują na
wrażliwych poświadczeniach. W produkcie bezpieczeństwa nasze własne skrypty muszą
być wzorem: żadnych haseł w kodzie, poświadczenia jako PSCredential.
Nigdy haseł w skrypcie
Hasło w kodzie trafia do repozytorium, logów i historii git na zawsze.
# źle — hasło w kodzie, wyciek na zawsze
$pass = "P@ssw0rd123"
$cred = New-Object PSCredential("corp\svc", (ConvertTo-SecureString $pass -AsPlainText -Force))
# dobrze — poświadczenia podane z zewnątrz jako parametr
param([Parameter(Mandatory)][pscredential]$Credential)
Standard ProfessNet: skrypt probe nie zawiera żadnego hasła ani tokenu. Poświadczenia przyjmuje jako parametr
[pscredential]albo pobiera z bezpiecznego magazynu. Plain-text password w kodzie = krytyczny błąd review.
PSCredential — standardowy typ poświadczeń
PSCredential przechowuje nazwę użytkownika i hasło jako SecureString.
Wszystkie cmdlety zdalne (Invoke-Command, New-PSSession) przyjmują go przez
-Credential.
[CmdletBinding()]
param(
[Parameter(Mandatory)][string]$ComputerName,
[Parameter(Mandatory)][pscredential]$Credential
)
Invoke-Command -ComputerName $ComputerName -Credential $Credential -ScriptBlock {
Get-Service
}
Interaktywnie poświadczenia pobieramy bezpiecznie przez Get-Credential:
$cred = Get-Credential -UserName "corp\svc-zeus" -Message "Poświadczenia probe"
SecureString — czemu nie zwykły string
SecureString trzyma dane zaszyfrowane w pamięci i pozwala je wymazać.
Nie pojawia się przypadkiem w logach ani transkrypcji.
# konwersja, gdy naprawdę trzeba (np. do API wymagającego plain)
$plain = $Credential.GetNetworkCredential().Password # użyj i od razu wyczyść
Standard ProfessNet: plain-text z
SecureStringwyciągamy tylko w momencie użycia (na granicy z API, które inaczej nie potrafi) i nie przechowujemy go w zmiennej dłużej niż to konieczne. Nigdy nie logujemy tej wartości.
Magazyn poświadczeń — SecretManagement
Do trwałego przechowywania używamy modułu Microsoft.PowerShell.SecretManagement
z vaultem (np. Windows Credential Manager), a nie plików.
# zapis raz, poza kodem
Set-Secret -Name "ZeusProbeCred" -Secret $cred
# odczyt w skrypcie — brak hasła w kodzie
$cred = Get-Secret -Name "ZeusProbeCred"
Wykonanie zdalne i WinRM
Połączenia zdalne idą przez WinRM z poświadczeniami i, gdzie to możliwe, po szyfrowanym transporcie.
$session = New-PSSession -ComputerName $dc -Credential $Credential -UseSSL
try {
Invoke-Command -Session $session -ScriptBlock { Get-ADForest }
}
finally {
Remove-PSSession $session
}
| Zasada | Realizacja |
|---|---|
| Brak haseł w kodzie | parametr [pscredential] lub SecretManagement |
| Bezpieczne hasło w pamięci | SecureString / PSCredential |
| Pobranie interaktywne | Get-Credential |
| Trwałe poświadczenia | Get-Secret / Set-Secret (vault) |
| Brak wycieku do logów | nie logujemy hasła, sprzątamy sesje |
Wskazówka: wyłącz transkrypcję wrażliwych fragmentów i pamiętaj, że
ConvertTo-SecureString ... -AsPlainTextw kodzie to czerwona flaga — oznacza, że plain-text jest gdzieś w skrypcie.
Poświadczenia jako PSCredential, sekrety w vaultcie, plain-text tylko na
moment użycia i nigdy w repo. W probe'ach ZEUS bezpieczeństwo poświadczeń to nie
dodatek — to definicja poprawnie napisanego skryptu.