diff --git a/powershell/ql/lib/utils/test/InlineExpectationsTest.qll b/powershell/ql/lib/utils/test/InlineExpectationsTest.qll new file mode 100644 index 000000000000..c1e2172ec8c9 --- /dev/null +++ b/powershell/ql/lib/utils/test/InlineExpectationsTest.qll @@ -0,0 +1,8 @@ +/** + * Inline expectation tests for Powershell. + * See `shared/util/codeql/util/test/InlineExpectationsTest.qll` + */ + +private import codeql.util.test.InlineExpectationsTest +private import internal.InlineExpectationsTestImpl +import Make diff --git a/powershell/ql/lib/utils/test/InlineExpectationsTestQuery.ql b/powershell/ql/lib/utils/test/InlineExpectationsTestQuery.ql new file mode 100644 index 000000000000..8238b30e09b8 --- /dev/null +++ b/powershell/ql/lib/utils/test/InlineExpectationsTestQuery.ql @@ -0,0 +1,21 @@ +/** + * @kind test-postprocess + */ + +private import powershell +private import codeql.util.test.InlineExpectationsTest as T +private import internal.InlineExpectationsTestImpl +import T::TestPostProcessing +import T::TestPostProcessing::Make + +private module Input implements T::TestPostProcessing::InputSig { + string getRelativeUrl(Location location) { + exists(File f, int startline, int startcolumn, int endline, int endcolumn | + location.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and + f = location.getFile() + | + result = + f.getRelativePath() + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn + ) + } +} diff --git a/powershell/ql/lib/utils/test/internal/InlineExpectationsTestImpl.qll b/powershell/ql/lib/utils/test/internal/InlineExpectationsTestImpl.qll new file mode 100644 index 000000000000..b6a5137fc21d --- /dev/null +++ b/powershell/ql/lib/utils/test/internal/InlineExpectationsTestImpl.qll @@ -0,0 +1,13 @@ +private import powershell as P +private import codeql.util.test.InlineExpectationsTest + +module Impl implements InlineExpectationsTestSig { + /** + * A class representing line comments in Powershell. + */ + class ExpectationComment extends P::SingleLineComment { + string getContents() { result = this.getCommentContents().getValue().suffix(1) } + } + + class Location = P::Location; +} diff --git a/powershell/ql/test/query-tests/security/ConvertToSecureStringAsPlainText/ConvertToSecureStringAsPlainText.qlref b/powershell/ql/test/query-tests/security/ConvertToSecureStringAsPlainText/ConvertToSecureStringAsPlainText.qlref index 1b720d5d77b1..504bd8818c13 100644 --- a/powershell/ql/test/query-tests/security/ConvertToSecureStringAsPlainText/ConvertToSecureStringAsPlainText.qlref +++ b/powershell/ql/test/query-tests/security/ConvertToSecureStringAsPlainText/ConvertToSecureStringAsPlainText.qlref @@ -1 +1,2 @@ -experimental/ConvertToSecureStringAsPlainText.ql \ No newline at end of file +query: experimental/ConvertToSecureStringAsPlainText.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/ConvertToSecureStringAsPlainText/test.ps1 b/powershell/ql/test/query-tests/security/ConvertToSecureStringAsPlainText/test.ps1 index dfc4c457dd48..3f01719f5187 100644 --- a/powershell/ql/test/query-tests/security/ConvertToSecureStringAsPlainText/test.ps1 +++ b/powershell/ql/test/query-tests/security/ConvertToSecureStringAsPlainText/test.ps1 @@ -1,4 +1,4 @@ $UserInput = Read-Host 'Please enter your secure code' -$EncryptedInput = ConvertTo-SecureString -String $UserInput -AsPlainText -Force +$EncryptedInput = ConvertTo-SecureString -String $UserInput -AsPlainText -Force # $ Alert $SecureUserInput = Read-Host 'Please enter your secure code' -AsSecureString \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/HardcodedComputerName/HardcodedComputerName.qlref b/powershell/ql/test/query-tests/security/HardcodedComputerName/HardcodedComputerName.qlref index 8e4160a9463d..61a6df31e4b2 100644 --- a/powershell/ql/test/query-tests/security/HardcodedComputerName/HardcodedComputerName.qlref +++ b/powershell/ql/test/query-tests/security/HardcodedComputerName/HardcodedComputerName.qlref @@ -1 +1,2 @@ -experimental/HardcodedComputerName.ql \ No newline at end of file +query: experimental/HardcodedComputerName.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/HardcodedComputerName/test.ps1 b/powershell/ql/test/query-tests/security/HardcodedComputerName/test.ps1 index 8a31f46d0f4e..03d8a99beb9c 100644 --- a/powershell/ql/test/query-tests/security/HardcodedComputerName/test.ps1 +++ b/powershell/ql/test/query-tests/security/HardcodedComputerName/test.ps1 @@ -1,6 +1,6 @@ Function Invoke-MyRemoteCommand () { - Invoke-Command -Port 343 -ComputerName hardcoderemotehostname + Invoke-Command -Port 343 -ComputerName hardcoderemotehostname # $ Alert } Function Invoke-MyCommand ($ComputerName) @@ -10,7 +10,7 @@ Function Invoke-MyCommand ($ComputerName) Function Invoke-MyLocalCommand () { - Invoke-Command -Port 343 -ComputerName hardcodelocalhostname + Invoke-Command -Port 343 -ComputerName hardcodelocalhostname # $ Alert } Function Invoke-MyLocalCommand () diff --git a/powershell/ql/test/query-tests/security/UseOfReservedCmdletChar/UseOfReservedCmdletChar.qlref b/powershell/ql/test/query-tests/security/UseOfReservedCmdletChar/UseOfReservedCmdletChar.qlref index 70451a74a560..d566474951de 100644 --- a/powershell/ql/test/query-tests/security/UseOfReservedCmdletChar/UseOfReservedCmdletChar.qlref +++ b/powershell/ql/test/query-tests/security/UseOfReservedCmdletChar/UseOfReservedCmdletChar.qlref @@ -1 +1,2 @@ -experimental/UseOfReservedCmdletChar.ql \ No newline at end of file +query: experimental/UseOfReservedCmdletChar.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/UseOfReservedCmdletChar/test.ps1 b/powershell/ql/test/query-tests/security/UseOfReservedCmdletChar/test.ps1 index 79eefefc67e3..4328a79d392f 100644 --- a/powershell/ql/test/query-tests/security/UseOfReservedCmdletChar/test.ps1 +++ b/powershell/ql/test/query-tests/security/UseOfReservedCmdletChar/test.ps1 @@ -1,2 +1,2 @@ function MyFunction[1] -{...} \ No newline at end of file +{...} # $ Alert Alert \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/UsernameOrPasswordParameter/UsernameOrPasswordParameter.qlref b/powershell/ql/test/query-tests/security/UsernameOrPasswordParameter/UsernameOrPasswordParameter.qlref index 8207783cd526..0b0d18774186 100644 --- a/powershell/ql/test/query-tests/security/UsernameOrPasswordParameter/UsernameOrPasswordParameter.qlref +++ b/powershell/ql/test/query-tests/security/UsernameOrPasswordParameter/UsernameOrPasswordParameter.qlref @@ -1 +1,2 @@ -experimental/UsernameOrPasswordParameter.ql \ No newline at end of file +query: experimental/UsernameOrPasswordParameter.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/UsernameOrPasswordParameter/test.ps1 b/powershell/ql/test/query-tests/security/UsernameOrPasswordParameter/test.ps1 index bf313dd416e9..acd462f1c91d 100644 --- a/powershell/ql/test/query-tests/security/UsernameOrPasswordParameter/test.ps1 +++ b/powershell/ql/test/query-tests/security/UsernameOrPasswordParameter/test.ps1 @@ -4,8 +4,8 @@ function Test-Script Param ( [String] - $Username, + $Username, # $ Alert [SecureString] - $Password + $Password # $ Alert ) } \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/cwe-022/test.ps1 b/powershell/ql/test/query-tests/security/cwe-022/test.ps1 index f0593424d182..e1ad2ede216c 100644 --- a/powershell/ql/test/query-tests/security/cwe-022/test.ps1 +++ b/powershell/ql/test/query-tests/security/cwe-022/test.ps1 @@ -3,27 +3,27 @@ Add-Type -AssemblyName System.IO.Compression.FileSystem $zip = [System.IO.Compression.ZipFile]::OpenRead("MyPath\to\archive.zip") foreach ($entry in $zip.Entries) { - $targetPath = Join-Path $extractPath $entry.FullName + $targetPath = Join-Path $extractPath $entry.FullName # $ Alert $fullTargetPath = [System.IO.Path]::GetFullPath($targetPath) - [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $fullTargetPath) # BAD + [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $fullTargetPath) # $ Sink } foreach ($entry in $zip.Entries) { - $targetPath = Join-Path $extractPath $entry.FullName + $targetPath = Join-Path $extractPath $entry.FullName # $ Alert $fullTargetPath = [System.IO.Path]::GetFullPath($targetPath) - $stream = [System.IO.File]::Open($fullTargetPath, 'Create') # BAD + $stream = [System.IO.File]::Open($fullTargetPath, 'Create') # $ Sink $entry.Open().CopyTo($stream) $stream.Close() } foreach ($entry in $zip.Entries) { - $targetPath = Join-Path $extractPath $entry.FullName + $targetPath = Join-Path $extractPath $entry.FullName # $ Alert $fullTargetPath = [System.IO.Path]::GetFullPath($targetPath) $extractRoot = [System.IO.Path]::GetFullPath($extractPath) if ($fullTargetPath.StartsWith($extractRoot)) { - [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $fullTargetPath) # GOOD [FALSE POSITIVE] + [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $fullTargetPath) # $ Sink } } \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/cwe-022/zipslip.qlref b/powershell/ql/test/query-tests/security/cwe-022/zipslip.qlref index 1fb40016ea52..21015b657c2e 100644 --- a/powershell/ql/test/query-tests/security/cwe-022/zipslip.qlref +++ b/powershell/ql/test/query-tests/security/cwe-022/zipslip.qlref @@ -1 +1,2 @@ -queries/security/cwe-022/ZipSlip.ql \ No newline at end of file +query: queries/security/cwe-022/ZipSlip.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/cwe-078/CommandInjection/CommandInjection.qlref b/powershell/ql/test/query-tests/security/cwe-078/CommandInjection/CommandInjection.qlref index 06653bc5ac7c..0d34a5d40c71 100644 --- a/powershell/ql/test/query-tests/security/cwe-078/CommandInjection/CommandInjection.qlref +++ b/powershell/ql/test/query-tests/security/cwe-078/CommandInjection/CommandInjection.qlref @@ -1 +1,2 @@ -queries/security/cwe-078/CommandInjection.ql \ No newline at end of file +query: queries/security/cwe-078/CommandInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/cwe-078/CommandInjection/test.ps1 b/powershell/ql/test/query-tests/security/cwe-078/CommandInjection/test.ps1 index f79decd563c7..60662cc86584 100644 --- a/powershell/ql/test/query-tests/security/cwe-078/CommandInjection/test.ps1 +++ b/powershell/ql/test/query-tests/security/cwe-078/CommandInjection/test.ps1 @@ -1,43 +1,43 @@ function Invoke-InvokeExpressionInjection1 { param($UserInput) - Invoke-Expression "Get-Process -Name $UserInput" # BAD + Invoke-Expression "Get-Process -Name $UserInput" # $ Alert } function Invoke-InvokeExpressionInjection2 { param($UserInput) - iex "Get-Process -Name $UserInput" # BAD + iex "Get-Process -Name $UserInput" # $ Alert } function Invoke-InvokeExpressionInjection3 { param($UserInput) - $executionContext.InvokeCommand.InvokeScript("Get-Process -Name $UserInput") # BAD + $executionContext.InvokeCommand.InvokeScript("Get-Process -Name $UserInput") # $ Alert } function Invoke-InvokeExpressionInjection4 { param($UserInput) - $host.Runspace.CreateNestedPipeline("Get-Process -Name $UserInput", $false).Invoke() # BAD + $host.Runspace.CreateNestedPipeline("Get-Process -Name $UserInput", $false).Invoke() # $ Alert } function Invoke-InvokeExpressionInjection5 { param($UserInput) - [PowerShell]::Create().AddScript("Get-Process -Name $UserInput").Invoke() # BAD + [PowerShell]::Create().AddScript("Get-Process -Name $UserInput").Invoke() # $ Alert } function Invoke-InvokeExpressionInjection6 { param($UserInput) - Add-Type "public class Foo { $UserInput }" # BAD + Add-Type "public class Foo { $UserInput }" # $ Alert } function Invoke-InvokeExpressionInjection7 { param($UserInput) - Add-Type -TypeDefinition "public class Foo { $UserInput }" # BAD + Add-Type -TypeDefinition "public class Foo { $UserInput }" # $ Alert } function Invoke-InvokeExpressionInjection8 @@ -45,7 +45,7 @@ function Invoke-InvokeExpressionInjection8 param($UserInput) $code = "public class Foo { $UserInput }" - Add-Type -TypeDefinition $code # BAD + Add-Type -TypeDefinition $code # $ Alert } function Invoke-InvokeExpressionInjectionFP @@ -72,21 +72,21 @@ function Invoke-ExploitableCommandInjection1 { param($UserInput) - powershell -command "Get-Process -Name $UserInput" # BAD + powershell -command "Get-Process -Name $UserInput" # $ Alert } function Invoke-ExploitableCommandInjection2 { param($UserInput) - powershell "Get-Process -Name $UserInput" # BAD + powershell "Get-Process -Name $UserInput" # $ Alert } function Invoke-ExploitableCommandInjection3 { param($UserInput) - cmd /c "ping $UserInput" # BAD + cmd /c "ping $UserInput" # $ Alert } function Invoke-ScriptBlockInjection1 @@ -95,7 +95,7 @@ function Invoke-ScriptBlockInjection1 ## Often used when making remote connections - $sb = [ScriptBlock]::Create("Get-Process -Name $UserInput") # BAD + $sb = [ScriptBlock]::Create("Get-Process -Name $UserInput") # $ Alert Invoke-Command RemoteServer $sb } @@ -105,7 +105,7 @@ function Invoke-ScriptBlockInjection2 ## Often used when making remote connections - $sb = $executionContext.InvokeCommand.NewScriptBlock("Get-Process -Name $UserInput") # BAD + $sb = $executionContext.InvokeCommand.NewScriptBlock("Get-Process -Name $UserInput") # $ Alert Invoke-Command RemoteServer $sb } @@ -113,14 +113,14 @@ function Invoke-MethodInjection1 { param($UserInput) - Get-Process | Foreach-Object $UserInput # BAD + Get-Process | Foreach-Object $UserInput # $ Alert } function Invoke-MethodInjection2 { param($UserInput) - (Get-Process -Id $pid).$UserInput() # BAD + (Get-Process -Id $pid).$UserInput() # $ Alert } @@ -128,7 +128,7 @@ function Invoke-MethodInjection3 { param($UserInput) - (Get-Process -Id $pid).$UserInput.Invoke() # BAD + (Get-Process -Id $pid).$UserInput.Invoke() # $ Alert } function Invoke-ExpandStringInjection1 @@ -136,7 +136,7 @@ function Invoke-ExpandStringInjection1 param($UserInput) ## Used to attempt a variable resolution - $executionContext.InvokeCommand.ExpandString($UserInput) # BAD + $executionContext.InvokeCommand.ExpandString($UserInput) # $ Alert } function Invoke-ExpandStringInjection2 @@ -144,24 +144,24 @@ function Invoke-ExpandStringInjection2 param($UserInput) ## Used to attempt a variable resolution - $executionContext.SessionState.InvokeCommand.ExpandString($UserInput) # BAD + $executionContext.SessionState.InvokeCommand.ExpandString($UserInput) # $ Alert } function Invoke-InvokeExpressionInjectionCmdletBinding { [CmdletBinding()] param($UserInput) - Invoke-Expression "Get-Process -Name $UserInput" # BAD + Invoke-Expression "Get-Process -Name $UserInput" # $ Alert } function Invoke-StartProcessInjection { param($UserInput) - Start-Process -FilePath $UserInput # BAD + Start-Process -FilePath $UserInput # $ Alert } -$input = Read-Host "enter input" +$input = Read-Host "enter input" # $ Source Invoke-InvokeExpressionInjection1 -UserInput $input Invoke-InvokeExpressionInjection2 -UserInput $input @@ -251,10 +251,10 @@ Invoke-InvokeExpressionInjectionSafe5 -UserInput $input function false-positive-in-call-operator($d) { - $o = Read-Host "enter input" + $o = Read-Host "enter input" # $ Source & unzip -o "$o" -d $d # GOOD - . "$o" # BAD + . "$o" # $ Alert } function flow-through-env-var() { @@ -262,9 +262,9 @@ function flow-through-env-var() { . "$x" # GOOD # we don't consider environment vars flow sources - $input = Read-Host "enter input" + $input = Read-Host "enter input" # $ Source $env:bar = $input $y = $env:bar - . "$y" # BAD # but we have flow through them + . "$y" # $ Alert # but we have flow through them } \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/cwe-078/DoNotUseInvokeExpression/DoNotUseInvokeExpression.qlref b/powershell/ql/test/query-tests/security/cwe-078/DoNotUseInvokeExpression/DoNotUseInvokeExpression.qlref index a006f78d20b4..f1789ba525aa 100644 --- a/powershell/ql/test/query-tests/security/cwe-078/DoNotUseInvokeExpression/DoNotUseInvokeExpression.qlref +++ b/powershell/ql/test/query-tests/security/cwe-078/DoNotUseInvokeExpression/DoNotUseInvokeExpression.qlref @@ -1 +1,2 @@ -queries/security/cwe-078/DoNotUseInvokeExpression.ql \ No newline at end of file +query: queries/security/cwe-078/DoNotUseInvokeExpression.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/cwe-078/DoNotUseInvokeExpression/test.ps1 b/powershell/ql/test/query-tests/security/cwe-078/DoNotUseInvokeExpression/test.ps1 index e075312b4b68..da72cffb946d 100644 --- a/powershell/ql/test/query-tests/security/cwe-078/DoNotUseInvokeExpression/test.ps1 +++ b/powershell/ql/test/query-tests/security/cwe-078/DoNotUseInvokeExpression/test.ps1 @@ -1,2 +1,2 @@ $command = "Get-Process" -Invoke-Expression $Command \ No newline at end of file +Invoke-Expression $Command # $ Alert \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/cwe-089/SqlInjection.qlref b/powershell/ql/test/query-tests/security/cwe-089/SqlInjection.qlref index 302dc18db398..3491aeeb8f5c 100644 --- a/powershell/ql/test/query-tests/security/cwe-089/SqlInjection.qlref +++ b/powershell/ql/test/query-tests/security/cwe-089/SqlInjection.qlref @@ -1 +1,2 @@ -queries/security/cwe-089/SqlInjection.ql \ No newline at end of file +query: queries/security/cwe-089/SqlInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/cwe-089/test.ps1 b/powershell/ql/test/query-tests/security/cwe-089/test.ps1 index c2aee3af258e..13ae28d61893 100644 --- a/powershell/ql/test/query-tests/security/cwe-089/test.ps1 +++ b/powershell/ql/test/query-tests/security/cwe-089/test.ps1 @@ -1,12 +1,12 @@ -$userinput = Read-Host "Please enter a value" +$userinput = Read-Host "Please enter a value" # $ Source # Example using Invoke-Sqlcmd with string interpolation $query = "SELECT * FROM MyTable WHERE MyColumn = '$userinput'" -Invoke-Sqlcmd -ServerInstance "MyServer" -Database "MyDatabase" -Query $query # BAD +Invoke-Sqlcmd -ServerInstance "MyServer" -Database "MyDatabase" -Query $query # $ Alert # Example using Invoke-Sqlcmd with string concatenation $query = "SELECT * FROM MyTable WHERE " + $userinput -Invoke-Sqlcmd -ServerInstance "MyServer" -Database "MyDatabase" -Query $query # BAD +Invoke-Sqlcmd -ServerInstance "MyServer" -Database "MyDatabase" -Query $query # $ Alert #Example using System.Data.SqlClient $connection = New-Object System.Data.SqlClient.SqlConnection @@ -14,7 +14,7 @@ $connection.ConnectionString = "Server=MyServer;Database=MyDatabase;" $connection.Open() $command = $connection.CreateCommand() -$command.CommandText = "SELECT * FROM MyTable WHERE MyColumn = '$userinput'" # BAD +$command.CommandText = "SELECT * FROM MyTable WHERE MyColumn = '$userinput'" # $ Alert $reader = $command.ExecuteReader() $reader.Close() $connection.Close() @@ -25,7 +25,7 @@ $connection.ConnectionString = "Provider=SQLOLEDB;Data Source=MyServer;Initial C $connection.Open() $command = $connection.CreateCommand() -$command.CommandText = "SELECT * FROM MyTable WHERE MyColumn = '$userinput'" # BAD +$command.CommandText = "SELECT * FROM MyTable WHERE MyColumn = '$userinput'" # $ Alert $reader = $command.ExecuteReader() $reader.Close() $connection.Close() @@ -78,7 +78,7 @@ $QueryConn2 = @{ Query = "SELECT * FROM Customers WHERE id = $userinput" } -Invoke-Sqlcmd @QueryConn2 # BAD +Invoke-Sqlcmd @QueryConn2 # $ Alert function TakesTypedParameters([int]$i, [long]$l, [float]$f, [double]$d, [decimal]$dec, [char]$c, [bool]$b, [datetime]$dt) { $query1 = "SELECT * FROM MyTable WHERE MyColumn = '$i'" @@ -122,7 +122,7 @@ function With-Validation() { ) Invoke-Sqlcmd -unknown $userinput -ServerInstance "MyServer" -Database "MyDatabase" -q $validated # GOOD - Invoke-Sqlcmd -unknown $userinput -ServerInstance "MyServer" -Database "MyDatabase" -q "SELECT * FROM Customers where id = $($unvalidated)" # BAD + Invoke-Sqlcmd -unknown $userinput -ServerInstance "MyServer" -Database "MyDatabase" -q "SELECT * FROM Customers where id = $($unvalidated)" # $ Alert } With-Validation $userinput $userinput diff --git a/powershell/ql/test/query-tests/security/cwe-250/InsecureExecutionPolicy.qlref b/powershell/ql/test/query-tests/security/cwe-250/InsecureExecutionPolicy.qlref index 9d375368846e..f593fe9d4a5e 100644 --- a/powershell/ql/test/query-tests/security/cwe-250/InsecureExecutionPolicy.qlref +++ b/powershell/ql/test/query-tests/security/cwe-250/InsecureExecutionPolicy.qlref @@ -1 +1,2 @@ -queries/security/cwe-250/InsecureExecutionPolicy.ql \ No newline at end of file +query: queries/security/cwe-250/InsecureExecutionPolicy.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/cwe-250/test.ps1 b/powershell/ql/test/query-tests/security/cwe-250/test.ps1 index bb8b5b0b137c..8fea77ebecba 100644 --- a/powershell/ql/test/query-tests/security/cwe-250/test.ps1 +++ b/powershell/ql/test/query-tests/security/cwe-250/test.ps1 @@ -1,10 +1,10 @@ -Set-ExecutionPolicy Bypass -Force # BAD +Set-ExecutionPolicy Bypass -Force # $ Alert Set-ExecutionPolicy RemoteSigned -Force # GOOD Set-ExecutionPolicy Bypass -Scope Process -Force # GOOD Set-ExecutionPolicy RemoteSigned -Scope Process -Force # GOOD -Set-ExecutionPolicy Bypass -Scope MachinePolicy -Force # BAD +Set-ExecutionPolicy Bypass -Scope MachinePolicy -Force # $ Alert -Set-ExecutionPolicy Bypass -Force:$true # BAD +Set-ExecutionPolicy Bypass -Force:$true # $ Alert Set-ExecutionPolicy Bypass -Force:$false # GOOD Set-ExecutionPolicy Bypass # GOOD diff --git a/powershell/ql/test/query-tests/security/cwe-319/UnsafeSMBSettings.qlref b/powershell/ql/test/query-tests/security/cwe-319/UnsafeSMBSettings.qlref index d925516eb6b5..e9cd301ec574 100644 --- a/powershell/ql/test/query-tests/security/cwe-319/UnsafeSMBSettings.qlref +++ b/powershell/ql/test/query-tests/security/cwe-319/UnsafeSMBSettings.qlref @@ -1 +1,2 @@ -queries/security/cwe-319/UnsafeSMBSettings.ql \ No newline at end of file +query: queries/security/cwe-319/UnsafeSMBSettings.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/cwe-319/test.ps1 b/powershell/ql/test/query-tests/security/cwe-319/test.ps1 index 0ae794115d6b..862a5035db90 100644 --- a/powershell/ql/test/query-tests/security/cwe-319/test.ps1 +++ b/powershell/ql/test/query-tests/security/cwe-319/test.ps1 @@ -2,19 +2,19 @@ #Bad Examples -Set-SmbServerConfiguration -Smb2DialectMin None +Set-SmbServerConfiguration -Smb2DialectMin None # $ Alert -Set-SmbClientConfiguration -Smb2DialectMin SMB210 +Set-SmbClientConfiguration -Smb2DialectMin SMB210 # $ Alert -Set-SmbServerConfiguration -encryptdata $false -rejectunencryptedaccess $false +Set-SmbServerConfiguration -encryptdata $false -rejectunencryptedaccess $false # $ Alert Alert -Set-SmbClientConfiguration -RequireEncryption $false +Set-SmbClientConfiguration -RequireEncryption $false # $ Alert -Set-SMbClientConfiguration -BlockNTLM $false +Set-SMbClientConfiguration -BlockNTLM $false # $ Alert -Set-SMbClientConfiguration -BlockNTLM $false -RequireEncryption $false -Smb2DialectMin SMB210 +Set-SMbClientConfiguration -BlockNTLM $false -RequireEncryption $false -Smb2DialectMin SMB210 # $ Alert Alert Alert -Set-SmbServerConfiguration -Smb2DialectMin None -encryptdata $false -rejectunencryptedaccess $false +Set-SmbServerConfiguration -Smb2DialectMin None -encryptdata $false -rejectunencryptedaccess $false # $ Alert Alert Alert #Good Examples diff --git a/powershell/ql/test/query-tests/security/cwe-327/ApprovedCipherMode/ApprovedCipherMode.qlref b/powershell/ql/test/query-tests/security/cwe-327/ApprovedCipherMode/ApprovedCipherMode.qlref index 650fdb0a2212..75d981b50a3c 100644 --- a/powershell/ql/test/query-tests/security/cwe-327/ApprovedCipherMode/ApprovedCipherMode.qlref +++ b/powershell/ql/test/query-tests/security/cwe-327/ApprovedCipherMode/ApprovedCipherMode.qlref @@ -1 +1,2 @@ -queries/security/cwe-327/ApprovedCipherMode.ql +query: queries/security/cwe-327/ApprovedCipherMode.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/powershell/ql/test/query-tests/security/cwe-327/ApprovedCipherMode/Test.ps1 b/powershell/ql/test/query-tests/security/cwe-327/ApprovedCipherMode/Test.ps1 index da289f6f03d2..99e6ac5d1d7a 100644 --- a/powershell/ql/test/query-tests/security/cwe-327/ApprovedCipherMode/Test.ps1 +++ b/powershell/ql/test/query-tests/security/cwe-327/ApprovedCipherMode/Test.ps1 @@ -4,13 +4,13 @@ $aes = [System.Security.Cryptography.Aes]::Create() $aesManaged = New-Object "System.Security.Cryptography.AesManaged" #Setting weak modes via CipherMode enum -$badMode = [System.Security.Cryptography.CipherMode]::ECB +$badMode = [System.Security.Cryptography.CipherMode]::ECB # $ Source $aes.Mode = $badMode -$aesManaged.Mode = $badMode +$aesManaged.Mode = $badMode # $ Alert $aes.Mode = [System.Security.Cryptography.CipherMode]::ECB -$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::ECB +$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::ECB # $ Alert # Setting weak modes directly $aes.Mode = "ecb" -$aesManaged.Mode = "ecb" \ No newline at end of file +$aesManaged.Mode = "ecb" # $ Alert \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/cwe-327/ObsoleteKDFAlgorithm/ObsoleteKDFAlgorithm.ps1 b/powershell/ql/test/query-tests/security/cwe-327/ObsoleteKDFAlgorithm/ObsoleteKDFAlgorithm.ps1 index 24e482657297..553836402fb9 100644 --- a/powershell/ql/test/query-tests/security/cwe-327/ObsoleteKDFAlgorithm/ObsoleteKDFAlgorithm.ps1 +++ b/powershell/ql/test/query-tests/security/cwe-327/ObsoleteKDFAlgorithm/ObsoleteKDFAlgorithm.ps1 @@ -24,7 +24,7 @@ function Test-PasswordDeriveBytesCryptDeriveKey { $pdb = New-Object System.Security.Cryptography.PasswordDeriveBytes($password, $salt) try { - $key = $pdb.CryptDeriveKey("TripleDES", "SHA1", 192, $iv) + $key = $pdb.CryptDeriveKey("TripleDES", "SHA1", 192, $iv) # $ Alert return $key } catch { @@ -53,7 +53,7 @@ function Test-Rfc2898DeriveBytes { $kdf = New-Object System.Security.Cryptography.Rfc2898DeriveBytes($password, $salt) try { - $key = $kdf.CryptDeriveKey("TripleDES", "SHA1", 192, $iv) + $key = $kdf.CryptDeriveKey("TripleDES", "SHA1", 192, $iv) # $ Alert return $key } catch { diff --git a/powershell/ql/test/query-tests/security/cwe-327/ObsoleteKDFAlgorithm/ObsoleteKDFAlgorithm.qlref b/powershell/ql/test/query-tests/security/cwe-327/ObsoleteKDFAlgorithm/ObsoleteKDFAlgorithm.qlref index 595905bee105..721805faf8af 100644 --- a/powershell/ql/test/query-tests/security/cwe-327/ObsoleteKDFAlgorithm/ObsoleteKDFAlgorithm.qlref +++ b/powershell/ql/test/query-tests/security/cwe-327/ObsoleteKDFAlgorithm/ObsoleteKDFAlgorithm.qlref @@ -1 +1,2 @@ -queries/security/cwe-327/ObsoleteKDFAlgorithm.ql +query: queries/security/cwe-327/ObsoleteKDFAlgorithm.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/powershell/ql/test/query-tests/security/cwe-327/WeakAsymmetricKeySize/WeakAsymmetricKeySize.qlref b/powershell/ql/test/query-tests/security/cwe-327/WeakAsymmetricKeySize/WeakAsymmetricKeySize.qlref index 67e632a55e00..7a9f31d4182e 100644 --- a/powershell/ql/test/query-tests/security/cwe-327/WeakAsymmetricKeySize/WeakAsymmetricKeySize.qlref +++ b/powershell/ql/test/query-tests/security/cwe-327/WeakAsymmetricKeySize/WeakAsymmetricKeySize.qlref @@ -1 +1,2 @@ -queries/security/cwe-327/WeakAsymmetricKeySize.ql +query: queries/security/cwe-327/WeakAsymmetricKeySize.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/powershell/ql/test/query-tests/security/cwe-327/WeakAsymmetricKeySize/test.ps1 b/powershell/ql/test/query-tests/security/cwe-327/WeakAsymmetricKeySize/test.ps1 index 12fd3c84331f..a9bcd0c6d057 100644 --- a/powershell/ql/test/query-tests/security/cwe-327/WeakAsymmetricKeySize/test.ps1 +++ b/powershell/ql/test/query-tests/security/cwe-327/WeakAsymmetricKeySize/test.ps1 @@ -3,13 +3,13 @@ # =================================================================== # --- Case 1: RSA.Create with 1024-bit key --- -$rsa = [System.Security.Cryptography.RSA]::Create(1024) # BAD +$rsa = [System.Security.Cryptography.RSA]::Create(1024) # $ Alert # --- Case 2: RSA.Create with 512-bit key --- -$rsa = [System.Security.Cryptography.RSA]::Create(512) # BAD +$rsa = [System.Security.Cryptography.RSA]::Create(512) # $ Alert # --- Case 3: RSACryptoServiceProvider with 1024-bit key via ::new() --- -$rsa = [System.Security.Cryptography.RSACryptoServiceProvider]::new(1024) # BAD +$rsa = [System.Security.Cryptography.RSACryptoServiceProvider]::new(1024) # $ Alert # =================================================================== # ========== TRUE NEGATIVES (should NOT trigger alert) ============== diff --git a/powershell/ql/test/query-tests/security/cwe-327/WeakHashes/WeakHashes.qlref b/powershell/ql/test/query-tests/security/cwe-327/WeakHashes/WeakHashes.qlref index 0745221129c8..629b4f7095b2 100644 --- a/powershell/ql/test/query-tests/security/cwe-327/WeakHashes/WeakHashes.qlref +++ b/powershell/ql/test/query-tests/security/cwe-327/WeakHashes/WeakHashes.qlref @@ -1 +1,2 @@ -queries/security/cwe-327/WeakHashes.ql \ No newline at end of file +query: queries/security/cwe-327/WeakHashes.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql \ No newline at end of file diff --git a/powershell/ql/test/query-tests/security/cwe-327/WeakHashes/test.ps1 b/powershell/ql/test/query-tests/security/cwe-327/WeakHashes/test.ps1 index e6f8e79236e7..3f71f7be659b 100644 --- a/powershell/ql/test/query-tests/security/cwe-327/WeakHashes/test.ps1 +++ b/powershell/ql/test/query-tests/security/cwe-327/WeakHashes/test.ps1 @@ -1,31 +1,31 @@ # BAD: Using MD5 - cryptographically broken -$md5 = [System.Security.Cryptography.MD5]::Create() +$md5 = [System.Security.Cryptography.MD5]::Create() # $ Alert $md5Hash = $md5.ComputeHash([System.Text.Encoding]::UTF8.GetBytes("password123")) # BAD: Using MD5CryptoServiceProvider -$md5Provider = New-Object System.Security.Cryptography.MD5CryptoServiceProvider +$md5Provider = New-Object System.Security.Cryptography.MD5CryptoServiceProvider # $ Alert $md5ProviderHash = $md5Provider.ComputeHash([System.Text.Encoding]::UTF8.GetBytes("secret")) # BAD: Using SHA1 - cryptographically weak -$sha1 = [System.Security.Cryptography.SHA1]::Create() +$sha1 = [System.Security.Cryptography.SHA1]::Create() # $ Alert $sha1Hash = $sha1.ComputeHash([System.Text.Encoding]::UTF8.GetBytes("password123")) # BAD: Using SHA1CryptoServiceProvider -$sha1Provider = New-Object System.Security.Cryptography.SHA1CryptoServiceProvider +$sha1Provider = New-Object System.Security.Cryptography.SHA1CryptoServiceProvider # $ Alert $sha1ProviderHash = $sha1Provider.ComputeHash([System.Text.Encoding]::UTF8.GetBytes("secret")) # BAD: Creating weak hash algorithms from name -$o = [System.Security.Cryptography.CryptoConfig]::CreateFromName("MD5") -$o = [System.Security.Cryptography.CryptoConfig]::CreateFromName("System.Security.Cryptography.MD5") -$o = [System.Security.Cryptography.CryptoConfig]::CreateFromName("SHA1") -$o = [System.Security.Cryptography.CryptoConfig]::CreateFromName("System.Security.Cryptography.SHA1") +$o = [System.Security.Cryptography.CryptoConfig]::CreateFromName("MD5") # $ Alert +$o = [System.Security.Cryptography.CryptoConfig]::CreateFromName("System.Security.Cryptography.MD5") # $ Alert +$o = [System.Security.Cryptography.CryptoConfig]::CreateFromName("SHA1") # $ Alert +$o = [System.Security.Cryptography.CryptoConfig]::CreateFromName("System.Security.Cryptography.SHA1") # $ Alert # BAD: Using Get-FileHash with MD5 -Get-FileHash -Path "C:\file.txt" -Algorithm MD5 +Get-FileHash -Path "C:\file.txt" -Algorithm MD5 # $ Alert # BAD: Using Get-FileHash with SHA1 -Get-FileHash -Path "C:\file.txt" -Algorithm SHA1 +Get-FileHash -Path "C:\file.txt" -Algorithm SHA1 # $ Alert # --------------------------------------------------------- # GOOD: Safe usage of cryptographically secure algorithms diff --git a/powershell/ql/test/query-tests/security/cwe-327/WeakSymmetricAlgorithm/WeakSymmetricAlgorithm.ps1 b/powershell/ql/test/query-tests/security/cwe-327/WeakSymmetricAlgorithm/WeakSymmetricAlgorithm.ps1 index de691e311085..aa2e9edeef94 100644 --- a/powershell/ql/test/query-tests/security/cwe-327/WeakSymmetricAlgorithm/WeakSymmetricAlgorithm.ps1 +++ b/powershell/ql/test/query-tests/security/cwe-327/WeakSymmetricAlgorithm/WeakSymmetricAlgorithm.ps1 @@ -5,22 +5,22 @@ function Test-CreateRC2 { param() # BAD: RC2 created - $r1 = [System.Security.Cryptography.RC2]::Create() + $r1 = [System.Security.Cryptography.RC2]::Create() # $ Alert # BAD: RC2 created via SymmetricAlgorithm - $r2 = [System.Security.Cryptography.SymmetricAlgorithm]::Create("RC2") + $r2 = [System.Security.Cryptography.SymmetricAlgorithm]::Create("RC2") # $ Alert # BAD: RC2 created with explicit name - $r3 = [System.Security.Cryptography.RC2]::Create("RC2") + $r3 = [System.Security.Cryptography.RC2]::Create("RC2") # $ Alert # BAD: RC2 created with full type name - $r4 = [System.Security.Cryptography.SymmetricAlgorithm]::Create("System.Security.Cryptography.RC2") + $r4 = [System.Security.Cryptography.SymmetricAlgorithm]::Create("System.Security.Cryptography.RC2") # $ Alert # BAD: RC2CryptoServiceProvider created - $r5 = New-Object System.Security.Cryptography.RC2CryptoServiceProvider + $r5 = New-Object System.Security.Cryptography.RC2CryptoServiceProvider # $ Alert # BAD: RC2 created using CryptoConfig.CreateFromName - $r6 = [System.Security.Cryptography.CryptoConfig]::CreateFromName("RC2") + $r6 = [System.Security.Cryptography.CryptoConfig]::CreateFromName("RC2") # $ Alert return $r5 } diff --git a/powershell/ql/test/query-tests/security/cwe-327/WeakSymmetricAlgorithm/WeakSymmetricAlgorithm.qlref b/powershell/ql/test/query-tests/security/cwe-327/WeakSymmetricAlgorithm/WeakSymmetricAlgorithm.qlref index 96f4390fb561..8c8f3743a8b4 100644 --- a/powershell/ql/test/query-tests/security/cwe-327/WeakSymmetricAlgorithm/WeakSymmetricAlgorithm.qlref +++ b/powershell/ql/test/query-tests/security/cwe-327/WeakSymmetricAlgorithm/WeakSymmetricAlgorithm.qlref @@ -1 +1,2 @@ -queries/security/cwe-327/WeakSymmetricAlgorithm.ql +query: queries/security/cwe-327/WeakSymmetricAlgorithm.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/powershell/ql/test/query-tests/security/cwe-347/JwtNoneAlgorithm/JwtNoneAlgorithm.qlref b/powershell/ql/test/query-tests/security/cwe-347/JwtNoneAlgorithm/JwtNoneAlgorithm.qlref index 454d269bd3d2..73c6545a4393 100644 --- a/powershell/ql/test/query-tests/security/cwe-347/JwtNoneAlgorithm/JwtNoneAlgorithm.qlref +++ b/powershell/ql/test/query-tests/security/cwe-347/JwtNoneAlgorithm/JwtNoneAlgorithm.qlref @@ -1 +1,2 @@ -queries/security/cwe-347/JwtNoneAlgorithm.ql +query: queries/security/cwe-347/JwtNoneAlgorithm.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/powershell/ql/test/query-tests/security/cwe-347/JwtNoneAlgorithm/test.ps1 b/powershell/ql/test/query-tests/security/cwe-347/JwtNoneAlgorithm/test.ps1 index 4be810003ab5..f08f6abcab73 100644 --- a/powershell/ql/test/query-tests/security/cwe-347/JwtNoneAlgorithm/test.ps1 +++ b/powershell/ql/test/query-tests/security/cwe-347/JwtNoneAlgorithm/test.ps1 @@ -4,10 +4,10 @@ # --- Case 1: .NET JwtSecurityTokenHandler.CreateToken with "none" --- $handler = [System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler]::new() -$token = $handler.CreateToken("none") # BAD +$token = $handler.CreateToken("none") # $ Alert # --- Case 2: .NET JwtSecurityTokenHandler.CreateEncodedJwt with "none" --- -$token = $handler.CreateEncodedJwt("none") # BAD +$token = $handler.CreateEncodedJwt("none") # $ Alert # =================================================================== # ========== TRUE NEGATIVES (should NOT trigger alert) ============== diff --git a/powershell/ql/test/query-tests/security/cwe-502/UnsafeDeserialization.qlref b/powershell/ql/test/query-tests/security/cwe-502/UnsafeDeserialization.qlref index abfb453d723d..12e3c7a9b6ca 100644 --- a/powershell/ql/test/query-tests/security/cwe-502/UnsafeDeserialization.qlref +++ b/powershell/ql/test/query-tests/security/cwe-502/UnsafeDeserialization.qlref @@ -1 +1,2 @@ -queries/security/cwe-502/UnsafeDeserialization.ql \ No newline at end of file +query: queries/security/cwe-502/UnsafeDeserialization.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/powershell/ql/test/query-tests/security/cwe-502/test.ps1 b/powershell/ql/test/query-tests/security/cwe-502/test.ps1 index d35ef352cd38..40959c7fe2b2 100644 --- a/powershell/ql/test/query-tests/security/cwe-502/test.ps1 +++ b/powershell/ql/test/query-tests/security/cwe-502/test.ps1 @@ -1,4 +1,4 @@ -$untrustedBase64 = Read-Host "Enter user input" +$untrustedBase64 = Read-Host "Enter user input" # $ Source $formatter = New-Object System.Runtime.Serialization.Formatters.Binary.BinaryFormatter $stream = [System.IO.MemoryStream]::new([Convert]::FromBase64String($untrustedBase64)) -$obj = $formatter.Deserialize($stream) +$obj = $formatter.Deserialize($stream) # $ Alert diff --git a/powershell/ql/test/query-tests/security/cwe-757/DeprecatedTls/DeprecatedTls.qlref b/powershell/ql/test/query-tests/security/cwe-757/DeprecatedTls/DeprecatedTls.qlref index 6ef6aa8af337..ddde729a4047 100644 --- a/powershell/ql/test/query-tests/security/cwe-757/DeprecatedTls/DeprecatedTls.qlref +++ b/powershell/ql/test/query-tests/security/cwe-757/DeprecatedTls/DeprecatedTls.qlref @@ -1 +1,2 @@ -queries/security/cwe-757/DeprecatedTls.ql +query: queries/security/cwe-757/DeprecatedTls.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/powershell/ql/test/query-tests/security/cwe-757/DeprecatedTls/test.ps1 b/powershell/ql/test/query-tests/security/cwe-757/DeprecatedTls/test.ps1 index 49e2448be73d..cec64c45afa2 100644 --- a/powershell/ql/test/query-tests/security/cwe-757/DeprecatedTls/test.ps1 +++ b/powershell/ql/test/query-tests/security/cwe-757/DeprecatedTls/test.ps1 @@ -3,16 +3,16 @@ # =================================================================== # --- Case 1: SSL 3.0 --- -[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Ssl3 # BAD +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Ssl3 # $ Alert # --- Case 2: TLS 1.0 --- -[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls # BAD +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls # $ Alert # --- Case 3: TLS 1.1 --- -[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls11 # BAD +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls11 # $ Alert # --- Case 4: Full namespace TLS 1.0 --- -[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls # BAD +[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls # $ Alert # =================================================================== # ========== TRUE NEGATIVES (should NOT trigger alert) ==============