Only the latest version on main is supported with security updates.
| Branch | Supported |
|---|---|
| main | Yes |
If you discover a security vulnerability, please report it responsibly:
- Do not open a public issue
- Use GitHub Security Advisories to report privately
- You should receive an acknowledgment within 48 hours
The following areas are in scope for security reports:
- Profile code (
Microsoft.PowerShell_profile.ps1) - command injection, unintended code execution - Setup scripts (
setup.ps1,setprofile.ps1) - privilege escalation, unsafe downloads - Update mechanism (
Update-Profile) - hash verification bypass, MITM concerns - Credential handling - API key exposure (e.g., VirusTotal), PSReadLine history filtering
- Remote setup and
Update-Profilerequire SHA-256 hash input before applying a downloaded install bundle, or explicit-SkipHashCheck.Invoke-ProfileWizardpins the downloadedsetup.ps1with-ExpectedSha256and forwards the install-bundle pin with-BundleExpectedSha256. What this protects: file integrity (truncated/corrupted downloads) and reproducible installs (the same expected hash always resolves to the same applied content). What this does NOT protect against: a first-time install where the attacker controls the download path. The initial SHA the profile prints is computed over what was just fetched; a MITMed first download would produce a hash that matches the malicious payload, not the real upstream. For real trust pinning, verify the published commit SHA out-of-band (e.g. againsthttps://github.com/26zl/PowerShellPerfect/commits/mainin a browser) before running with an expected hash. - PSReadLine history filters out lines containing:
password,secret,token,api[_-]?key,connectionstring,credential,bearer, VirusTotal API key variable names, direct JWT values, and sensitive command forms such aspwnd <candidate>andjwtd <token>. - Repository download URLs are centralized (not hardcoded inline)
- When in CI or when
$env:AI_AGENTis set, the profile and setup skip network calls and interactive prompts, reducing exposure in automated or AI/agent environments
The profile has four mechanisms that execute code from places other than the main profile file. All are user-owned and opt-in, but the trust model should be explicit:
profile_user.ps1- dot-sourced every profile load. Lives in the user's$PROFILEdirectory. Equivalent to editing the profile itself.plugins/*.ps1- dot-sourced every profile load. Lives in%LOCALAPPDATA%\PowerShellProfile\plugins\. Each file is isolated so one crash doesn't break others, but a plugin has full profile trust.user-settings.jsoncommandOverrides- values are passed to[scriptblock]::Create()and defined as functions. Default off - requires explicit opt-in viafeatures.commandOverrides = truein the same file, so a silently-edited JSON file cannot redefine commands on next shell launch. When the feature is off but entries exist, the profile prints a notice at startup and ignores them. Do not copyuser-settings.jsonfrom untrusted sources..psprc.ps1per-directory profiles - auto-loaded oncdinto a trusted directory only. Trust is explicit and per-directory viaAdd-TrustedDirectory; untrusted directories only print a warning. This is modeled afterdirenv.
Because all four surfaces require local filesystem write access (or explicit Add-TrustedDirectory for .psprc.ps1), they are not exploitable by remote attackers without first achieving arbitrary file write. Treat user-settings.json and plugin files as carefully as any dotfile.
Commands that send your data to a third party (all over HTTPS):
| Command | Endpoint | Data sent |
|---|---|---|
ipinfo [ip] |
ipwho.is |
The IP you pass, or none (your public IP is then revealed to the service) |
weather [city] |
wttr.in, fallback open-meteo.com + ipinfo.io |
City name; with no city, your public IP is used for geolocation |
hb <file> |
bin.christitus.com |
The entire file contents, posted to a public paste. Confirms first (-Force/-Confirm:$false to skip) |
vtscan <file> |
VirusTotal API | File SHA-256 first; uploads the file only if VT hasn't seen the hash. Needs VTCLI_APIKEY/VT_API_KEY |
Commands that only contact targets you explicitly name (http, whois, nslook, checkport, portscan, tlscert, speedtest, ssh) send no profile-owned data. Update-Profile/setup.ps1 and tool installs download from raw.githubusercontent.com, GitHub releases, and winget; they upload nothing.