Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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": 1
},
"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": 1
},
"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": 1
},
"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": 1
},
"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": 1
},
"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": 1
},
"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": 1
},
"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": 1
},
"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": 1
},
"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": 1
},
"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. Insead replacing to #removed#
Comment thread
Copilot marked this conversation as resolved.
Outdated
## (?!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; $ ( ) ; & | and unescaped backtick remain blocked.
Comment thread
Copilot marked this conversation as resolved.
Outdated
$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 occured in '$($test.Name)' suite with input '$($test.Input)': $($_.Exception.Message)"
Comment thread
Copilot marked this conversation as resolved.
Outdated
}
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