Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Tasks/AzureFileCopyV1/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"version": {
"Major": 1,
"Minor": 276,
"Patch": 0
"Patch": 1
},
Comment thread
wawanawna marked this conversation as resolved.
"demands": [
"azureps"
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzureFileCopyV1/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"version": {
"Major": 1,
"Minor": 276,
"Patch": 0
"Patch": 1
},
"demands": [
"azureps"
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzureFileCopyV2/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"version": {
"Major": 2,
"Minor": 276,
"Patch": 0
"Patch": 1
},
Comment thread
wawanawna marked this conversation as resolved.
"demands": [
"azureps"
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzureFileCopyV2/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"version": {
"Major": 2,
"Minor": 276,
"Patch": 0
"Patch": 1
},
"demands": [
"azureps"
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzureFileCopyV3/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"version": {
"Major": 3,
"Minor": 276,
"Patch": 0
"Patch": 1
},
Comment thread
wawanawna marked this conversation as resolved.
"demands": [
"azureps"
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzureFileCopyV3/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"version": {
"Major": 3,
"Minor": 276,
"Patch": 0
"Patch": 1
},
"demands": [
"azureps"
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzureFileCopyV4/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"version": {
"Major": 4,
"Minor": 276,
"Patch": 0
"Patch": 2
},
"demands": [
"azureps"
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzureFileCopyV4/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"version": {
"Major": 4,
"Minor": 276,
"Patch": 0
"Patch": 2
},
"demands": [
"azureps"
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzureFileCopyV5/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"version": {
"Major": 5,
"Minor": 276,
"Patch": 0
"Patch": 2
},
"demands": [
"azureps"
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzureFileCopyV5/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"version": {
"Major": 5,
"Minor": 276,
"Patch": 0
"Patch": 2
},
"demands": [
"azureps"
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzureFileCopyV6/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"version": {
"Major": 6,
"Minor": 276,
"Patch": 0
"Patch": 2
},
"demands": [
"azureps"
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzureFileCopyV6/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"version": {
"Major": 6,
"Minor": 276,
"Patch": 0
"Patch": 2
},
"demands": [
"azureps"
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzurePowerShellV2/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"version": {
"Major": 2,
"Minor": 276,
"Patch": 0
"Patch": 1
},
Comment thread
wawanawna marked this conversation as resolved.
"demands": [
"azureps"
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzurePowerShellV2/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"version": {
"Major": 2,
"Minor": 276,
"Patch": 0
"Patch": 1
},
"demands": [
"azureps"
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzurePowerShellV3/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"version": {
"Major": 3,
"Minor": 276,
"Patch": 0
"Patch": 1
},
Comment thread
wawanawna marked this conversation as resolved.
"releaseNotes": "Added support for Fail on standard error and ErrorActionPreference",
"demands": [
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzurePowerShellV3/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"version": {
"Major": 3,
"Minor": 276,
"Patch": 0
"Patch": 1
},
"releaseNotes": "ms-resource:loc.releaseNotes",
"demands": [
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzurePowerShellV4/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"version": {
"Major": 4,
"Minor": 276,
"Patch": 0
"Patch": 2
},
"releaseNotes": "Added support for Az Module and cross platform agents.",
"groups": [
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzurePowerShellV4/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"version": {
"Major": 4,
"Minor": 276,
"Patch": 0
"Patch": 2
},
"releaseNotes": "ms-resource:loc.releaseNotes",
"groups": [
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzurePowerShellV5/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"version": {
"Major": 5,
"Minor": 276,
"Patch": 0
"Patch": 2
},
"releaseNotes": "Added support for Az Module and cross platform agents.",
"groups": [
Expand Down
2 changes: 1 addition & 1 deletion Tasks/AzurePowerShellV5/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"version": {
"Major": 5,
"Minor": 276,
"Patch": 0
"Patch": 2
},
"releaseNotes": "ms-resource:loc.releaseNotes",
"groups": [
Expand Down
6 changes: 4 additions & 2 deletions Tasks/Common/Sanitizer/ArgumentsSanitizer.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,11 @@ function Get-SanitizedArguments([string]$inputArgs) {

## PowerShell Regex is case insensitive by default, so we don't need to specify a-zA-Z.
## ('?<!`') - checking if before character no backtick.
## ([^\w` _'"-=\/:\.*,+~?%\n#]) - checking if character is allowed. Insead replacing to #removed#
## ([^\w` _'"-=\/:\.*,+~?%\n#@{}\[\]]) - checking if character is allowed. Instead it is replaced with #removed#
## (?!true|false) - checking if after characters sequence no $true or $false.
$regex = '(?<!`)([^\w\\` _''"\-=\/:\.*,+~?%\n#])(?!true|false)'
## @ { } [ ] are PowerShell data constructors (hashtable, splatting, array index, type accelerator) -
## they are not execution primitives, so they pass; $ ( ) ; & | remain blocked (unless escaped), and ` is allowed as the escape character.
$regex = '(?<!`)([^\w\\` _''"\-=\/:\.*,+~?%\n#@{}\[\]])(?!true|false)'

# We're splitting by ``, removing all suspicious characters and then join
$argsArr = $inputArgs -split $argsSplitSymbols;
Expand Down
6 changes: 6 additions & 0 deletions Tasks/Common/Sanitizer/Tests/L0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ describe('Security Suite', function () {
});
}

if (psm.testSupported()) {
it('Protect-ScriptArguments should allow PowerShell data constructors (@ { } [ ])', (done) => {
psr.run(path.join(__dirname, 'L0Protect-ScriptArguments.AllowsDataConstructors.ps1'), done);
});
}

if (psm.testSupported()) {
it('Protect-ScriptArguments should throw', (done) => {
psr.run(path.join(__dirname, 'L0Protect-ScriptArguments.Throws.ps1'), done);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ $powershellArgumentsFormats = @(
"/p:Parameter=Value", # Specific syntax for tools like MSBuild or NuGet
"--Parameter Value", # Used by cmdlets or scripts for cross-platform compatibility
"--Parameter=Value", # Used by cross-platform tools
"parameter value.txt" # Argument with dot in the middle
"parameter value.txt", # Argument with dot in the middle
"-Tag @{ Owner = `"team`" }", # Hashtable literal — PR #22249/this PR
"Invoke-Build @params", # Splatting
"-Cast [string]", # Type accelerator
"-Index [0]" # Literal index
)

foreach ($argument in $powershellArgumentsFormats) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
[CmdletBinding()]
param()

Set-Item -Path env:AZP_75787_ENABLE_NEW_LOGIC -Value 'true'

. $PSScriptRoot\..\..\..\..\Tests\lib\Initialize-Test.ps1
. $PSScriptRoot\..\ArgumentsSanitizer.ps1

# PowerShell data constructors (@ { } [ ]) are not execution primitives and
# must pass so customers can pass `-Tag @{...}`, splatting `@params`, type
# accelerators `[string]`, and literal indices `[0]` in scriptArguments
# (PR #22171 regression follow-up; mirrors AzureCLI fix in PR #22249).
$testSuites = @(
@{
Name = 'Accepts hashtable literal @{ K = "v" }'
Input = '-Tag @{ Owner = "team" }'
},
@{
Name = 'Accepts hashtable with newline separators (YAML folded scalar)'
Input = "-Tag @{ Solution = ""RunnerImagesGeneration""`n ManagedBy = ""Platform-Team"" }"
},
@{
Name = 'Accepts splatting @params'
Input = 'Invoke-Build @params'
},
@{
Name = 'Accepts type accelerator [string]'
Input = '-Cast [string]'
},
@{
Name = 'Accepts literal index [0]'
Input = '-Index [0]'
},
@{
Name = 'Accepts hashtable value containing @ (email)'
Input = '-Tag @{ Owner = "team@contoso.com" }'
},
@{
Name = 'Accepts hashtable with $env: substitution in value (no dangerous chars)'
Input = '-Tag @{ RequestedFor = $env:requestedFor }'
Variables = @('requestedFor=someone@contoso.com')
}
)

foreach ($test in $testSuites) {
if ($null -eq $test.Variables) {
$test.Variables = @()
}
$test.Variables | ForEach-Object {
$name, $value = $_.Split('=')
if ($value) {
Set-Item -Path env:$name -Value $value
}
Comment thread
wawanawna marked this conversation as resolved.
else {
Remove-Item env:$name -ErrorAction SilentlyContinue
}
}

try {
Protect-ScriptArguments $test.Input
}
catch {
throw "Error occurred in '$($test.Name)' suite with input '$($test.Input)': $($_.Exception.Message)"
}
finally {
$test.Variables | ForEach-Object {
$name, $value = $_.Split('=')
Remove-Item env:$name -ErrorAction SilentlyContinue
}
Comment thread
wawanawna marked this conversation as resolved.
}
}
22 changes: 22 additions & 0 deletions Tasks/Common/Sanitizer/Tests/L0Protect-ScriptArguments.Throws.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,28 @@ $testSuites = @(
Name = 'If inside args line not correct env syntax'
Input = 'test $venv:VAR1 test'
Variables = @('VAR1=123')
},
# Attack primitives ($ ( ) ; & |) must remain blocked even when wrapped
# in otherwise-allowed PowerShell data constructors @ { } [ ].
@{
Name = 'Hashtable value with $(subexpression) still blocked'
Input = '-Tag @{ Cmd = "$(Get-Date)" }'
},
@{
Name = '$(rm -rf /) subexpression still blocked'
Input = '-Path $(rm -rf /)'
},
@{
Name = '& call operator still blocked'
Input = '-Cmd & evil.exe'
},
@{
Name = 'Array literal @(...) still blocked (parens are execution-position)'
Input = '-Items @("a","b","c")'
},
@{
Name = 'Hashtable with semicolon separator still blocked'
Input = '-Tag @{ a = 1; b = 2 }'
}
)

Expand Down
2 changes: 1 addition & 1 deletion Tasks/PowerShellOnTargetMachinesV3/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"version": {
"Major": 3,
"Minor": 276,
"Patch": 0
"Patch": 1
},
"groups": [
{
Expand Down
2 changes: 1 addition & 1 deletion Tasks/PowerShellOnTargetMachinesV3/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"version": {
"Major": 3,
"Minor": 276,
"Patch": 0
"Patch": 1
},
"groups": [
{
Expand Down
2 changes: 1 addition & 1 deletion Tasks/PowerShellV2/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"version": {
"Major": 2,
"Minor": 276,
"Patch": 0
"Patch": 1
},
"releaseNotes": "Script task consistency. Added support for macOS and Linux.",
"minimumAgentVersion": "2.115.0",
Expand Down
2 changes: 1 addition & 1 deletion Tasks/PowerShellV2/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"version": {
"Major": 2,
"Minor": 276,
"Patch": 0
"Patch": 1
},
"releaseNotes": "ms-resource:loc.releaseNotes",
"minimumAgentVersion": "2.115.0",
Expand Down
2 changes: 1 addition & 1 deletion Tasks/ServiceFabricPowerShellV1/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"version": {
"Major": 1,
"Minor": 276,
"Patch": 0
"Patch": 1
},
"demands": [
"Cmd"
Expand Down
2 changes: 1 addition & 1 deletion Tasks/ServiceFabricPowerShellV1/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"version": {
"Major": 1,
"Minor": 276,
"Patch": 0
"Patch": 1
},
"demands": [
"Cmd"
Expand Down
2 changes: 1 addition & 1 deletion Tasks/SqlAzureDacpacDeploymentV1/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"version": {
"Major": 1,
"Minor": 276,
"Patch": 1
"Patch": 2
},
"demands": [
"sqlpackage"
Expand Down
2 changes: 1 addition & 1 deletion Tasks/SqlAzureDacpacDeploymentV1/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"version": {
"Major": 1,
"Minor": 276,
"Patch": 1
"Patch": 2
},
"demands": [
"sqlpackage"
Expand Down
Loading
Loading