10.1 : ExecutionPolicy et signature de scripts

Sophie ferme le dernier chantier API : « On a construit énormément de scripts depuis le début de cette formation. Certains touchent l’AD, d’autres exposent des données via une API, d’autres encore tournent seuls chaque nuit. Il est temps de reparler sérieusement de sécurité, cette fois en profondeur. » Vous avez croisé l’ExecutionPolicy dès la leçon 5.1, réglée à la va-vite avec RemoteSigned pour pouvoir avancer. Cette leçon revient dessus avec le niveau d’exigence attendu en environnement de production.

Rappel et approfondissement de l’ExecutionPolicy

Les cinq niveaux principaux, du plus restrictif au plus permissif :

NiveauComportement
RestrictedAucun script ne s’exécute (réglage par défaut sur beaucoup de postes Windows)
AllSignedTous les scripts doivent être signés numériquement, y compris les vôtres
RemoteSignedScripts locaux libres, scripts téléchargés doivent être signés
UnrestrictedTous les scripts s’exécutent, avec un simple avertissement pour les scripts téléchargés
BypassAucune vérification, aucun avertissement

Point de vigilance : l’ExecutionPolicy n’est pas un mécanisme de sécurité au sens strict — Microsoft le présente officiellement comme un filet de sécurité contre l’exécution accidentelle, pas comme une protection contre un attaquant déterminé. Elle se contourne d’ailleurs trivialement (powershell -ExecutionPolicy Bypass -File script.ps1). La vraie protection en entreprise repose sur la combinaison de plusieurs mécanismes : signature de scripts, restrictions via GPO, et solutions de contrôle applicatif comme AppLocker ou WDAC (Windows Defender Application Control), qui dépassent le cadre de cette formation mais qu’il est important de connaître.

Signer un script avec un certificat

Sur AllSigned ou pour des scripts destinés à circuler entre plusieurs postes Nordika en RemoteSigned, signer un script garantit son intégrité (personne ne l’a modifié depuis sa signature) et son origine (on sait qui l’a signé).

Générer un certificat de signature de code (pour un usage interne à Nordika, un certificat auto-signé suffit en test ; en production, on utilisera plutôt un certificat émis par une autorité de certification d’entreprise) :

$certificat = New-SelfSignedCertificate -Subject "CN=Nordika Script Signing" `
                                          -Type CodeSigningCert `
                                          -CertStoreLocation "Cert:\CurrentUser\My"

On retrouve ici le Provider Cert: vu en leçon 4.1 : le certificat est stocké et manipulable exactement comme n’importe quel autre lecteur PowerShell.

Signer le script avec ce certificat :

Set-AuthenticodeSignature -FilePath "C:\Nordika\Scripts\rapport-supervision.ps1" -Certificate $certificat

Une fois signé, le fichier .ps1 contient désormais un bloc de signature ajouté en fin de fichier — visible si on l’ouvre dans un éditeur de texte, mais qui n’affecte pas l’exécution du code lui-même.

Vérifier la signature d’un script

Get-AuthenticodeSignature -FilePath "C:\Nordika\Scripts\rapport-supervision.ps1"

Le champ Status indique si la signature est Valid, NotSigned, ou HashMismatch (signe que le script a été modifié après sa signature, sans être re-signé — un signal d’alerte à ne jamais ignorer).

Retour d’expérience terrain : un script modifié après signature ne redevient pas automatiquement invalide de façon visible à l’exécution — PowerShell continue de l’exécuter tant que l’ExecutionPolicy en vigueur ne l’en empêche pas explicitement (sur AllSigned uniquement, une signature invalide bloque réellement l’exécution). C’est pourquoi la vérification de Get-AuthenticodeSignature doit faire partie intégrante d’un pipeline CI/CD sérieux (vu en section 8), avant tout déploiement d’un module comme NordikaTools sur l’ensemble du parc.

Un exemple concret Nordika : intégrer la signature au processus de déploiement

En reprenant le pipeline CI/CD de la leçon 8.3, on ajoute une étape de vérification avant tout déploiement :

$signature = Get-AuthenticodeSignature -FilePath ".\NordikaTools\NordikaTools.psm1"

if ($signature.Status -ne "Valid") {
    throw "Le module n'est pas correctement signé (statut : $($signature.Status)). Déploiement annulé."
}

Write-Output "Signature valide, déploiement autorisé"

throw (déjà rencontré en 9.3) interrompt ici le pipeline avant tout déploiement si la signature n’est pas conforme — un garde-fou simple, mais efficace, contre un module altéré ou non signé qui se propagerait sur l’ensemble du parc Nordika.

Ce que l’ExecutionPolicy ne remplace pas

Pour clore cette leçon, un point de synthèse essentiel avec tout ce qui a été vu depuis la section 6 sur la sécurité AD : ExecutionPolicy et signature de scripts protègent contre l’exécution accidentelle ou l’altération d’un script, mais ne remplacent en rien le principe du moindre privilège (compte de service dédié, droits délégués) ni la protection des secrets (vue dans la prochaine leçon). Ce sont des couches complémentaires, pas substituables les unes aux autres.

Source officielle : la documentation Microsoft about_Execution_Policies (mentionnée dès la leçon 5.1) et about_Signing détaillent l’ensemble du mécanisme de signature Authenticode appliqué à PowerShell, y compris les scénarios avec certificats émis par une autorité de certification d’entreprise plutôt qu’auto-signés.

Retenez le message central de cette leçon : la sécurité d’un script ne se joue jamais sur un seul mécanisme. ExecutionPolicy limite l’exécution accidentelle, la signature garantit l’intégrité et l’origine — mais aucun des deux ne protège un secret oublié en clair dans le code, le sujet précis de la prochaine leçon.

Dans la prochaine leçon, on s’attaque à la gestion propre des secrets avec le module SecretManagement, plutôt que le mot de passe en clair utilisé volontairement à des fins pédagogiques depuis le début de cette formation.