Skip to content

Commit 9681711

Browse files
authored
Merge pull request #282 from microsoft/sql-injection-powershell-more-barriers
PS: Remove from FPs from the SQL injection query.
2 parents 6df032d + 6a95515 commit 9681711

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

powershell/ql/lib/semmle/code/powershell/security/SqlInjectionCustomizations.qll

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ module SqlInjection {
7373

7474
override predicate allowImplicitRead(DataFlow::ContentSet cs) {
7575
cs.getAStoreContent().(DataFlow::Content::KnownKeyContent).getIndex().asString().toLowerCase() =
76-
["query", "inputfile"]
76+
query()
7777
}
7878
}
7979

@@ -106,4 +106,15 @@ module SqlInjection {
106106
}
107107

108108
class TypeSanitizer extends Sanitizer instanceof SimpleTypeSanitizer { }
109+
110+
class ValidateAttributeSanitizer extends Sanitizer {
111+
ValidateAttributeSanitizer() {
112+
exists(Function f, Attribute a, Parameter p |
113+
p = f.getAParameter() and
114+
p.getAnAttribute() = a and
115+
a.getAName() = ["ValidateScript", "ValidateSet", "ValidatePattern"] and
116+
this.asParameter() = p
117+
)
118+
}
119+
}
109120
}

powershell/ql/test/query-tests/security/cwe-089/SqlInjection.expected

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@ edges
44
| test.ps1:1:1:1:10 | userinput | test.ps1:17:24:17:76 | SELECT * FROM MyTable WHERE MyColumn = '$userinput' | provenance | |
55
| test.ps1:1:1:1:10 | userinput | test.ps1:28:24:28:76 | SELECT * FROM MyTable WHERE MyColumn = '$userinput' | provenance | |
66
| test.ps1:1:1:1:10 | userinput | test.ps1:78:13:78:22 | userinput | provenance | |
7+
| test.ps1:1:1:1:10 | userinput | test.ps1:128:28:128:37 | userinput | provenance | |
78
| test.ps1:1:14:1:45 | Call to read-host | test.ps1:1:1:1:10 | userinput | provenance | Src:MaD:0 |
89
| test.ps1:4:1:4:6 | query | test.ps1:5:72:5:77 | query | provenance | |
910
| test.ps1:8:1:8:6 | query | test.ps1:9:72:9:77 | query | provenance | |
1011
| test.ps1:72:1:72:11 | QueryConn2 [element Query] | test.ps1:81:15:81:25 | QueryConn2 | provenance | |
1112
| test.ps1:72:15:79:1 | ${...} [element Query] | test.ps1:72:1:72:11 | QueryConn2 [element Query] | provenance | |
1213
| test.ps1:78:13:78:22 | userinput | test.ps1:72:15:79:1 | ${...} [element Query] | provenance | |
14+
| test.ps1:121:9:121:56 | unvalidated | test.ps1:125:92:125:103 | unvalidated | provenance | |
15+
| test.ps1:128:28:128:37 | userinput | test.ps1:121:9:121:56 | unvalidated | provenance | |
1316
nodes
1417
| test.ps1:1:1:1:10 | userinput | semmle.label | userinput |
1518
| test.ps1:1:14:1:45 | Call to read-host | semmle.label | Call to read-host |
@@ -23,10 +26,14 @@ nodes
2326
| test.ps1:72:15:79:1 | ${...} [element Query] | semmle.label | ${...} [element Query] |
2427
| test.ps1:78:13:78:22 | userinput | semmle.label | userinput |
2528
| test.ps1:81:15:81:25 | QueryConn2 | semmle.label | QueryConn2 |
29+
| test.ps1:121:9:121:56 | unvalidated | semmle.label | unvalidated |
30+
| test.ps1:125:92:125:103 | unvalidated | semmle.label | unvalidated |
31+
| test.ps1:128:28:128:37 | userinput | semmle.label | userinput |
2632
subpaths
2733
#select
2834
| test.ps1:5:72:5:77 | query | test.ps1:1:14:1:45 | Call to read-host | test.ps1:5:72:5:77 | query | This SQL query depends on a $@. | test.ps1:1:14:1:45 | Call to read-host | read from stdin |
2935
| test.ps1:9:72:9:77 | query | test.ps1:1:14:1:45 | Call to read-host | test.ps1:9:72:9:77 | query | This SQL query depends on a $@. | test.ps1:1:14:1:45 | Call to read-host | read from stdin |
3036
| test.ps1:17:24:17:76 | SELECT * FROM MyTable WHERE MyColumn = '$userinput' | test.ps1:1:14:1:45 | Call to read-host | test.ps1:17:24:17:76 | SELECT * FROM MyTable WHERE MyColumn = '$userinput' | This SQL query depends on a $@. | test.ps1:1:14:1:45 | Call to read-host | read from stdin |
3137
| test.ps1:28:24:28:76 | SELECT * FROM MyTable WHERE MyColumn = '$userinput' | test.ps1:1:14:1:45 | Call to read-host | test.ps1:28:24:28:76 | SELECT * FROM MyTable WHERE MyColumn = '$userinput' | This SQL query depends on a $@. | test.ps1:1:14:1:45 | Call to read-host | read from stdin |
3238
| test.ps1:81:15:81:25 | QueryConn2 | test.ps1:1:14:1:45 | Call to read-host | test.ps1:81:15:81:25 | QueryConn2 | This SQL query depends on a $@. | test.ps1:1:14:1:45 | Call to read-host | read from stdin |
39+
| test.ps1:125:92:125:103 | unvalidated | test.ps1:1:14:1:45 | Call to read-host | test.ps1:125:92:125:103 | unvalidated | This SQL query depends on a $@. | test.ps1:1:14:1:45 | Call to read-host | read from stdin |

powershell/ql/test/query-tests/security/cwe-089/test.ps1

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,29 @@ TakesTypedParameters $userinput $userinput $userinput $userinput $userinput $use
111111
$query = "SELECT * FROM MyTable WHERE MyColumn = '$userinput'"
112112
Invoke-Sqlcmd -unknown $userinput -ServerInstance "MyServer" -Database "MyDatabase" -q "SELECT * FROM MyTable" # GOOD
113113

114-
Invoke-Sqlcmd -ServerInstance "MyServer" -Database "MyDatabase" -InputFile $userinput # GOOD # this is not really what this query is about.
114+
Invoke-Sqlcmd -ServerInstance "MyServer" -Database "MyDatabase" -InputFile $userinput # GOOD # this is not really what this query is about.
115+
116+
function With-Validation() {
117+
param(
118+
[ValidateSet("FirstName","LastName")]
119+
[parameter(Mandatory=$true)][string]$validated,
120+
121+
[parameter(Mandatory=$true)][string]$unvalidated
122+
)
123+
124+
Invoke-Sqlcmd -unknown $userinput -ServerInstance "MyServer" -Database "MyDatabase" -q $validated # GOOD
125+
Invoke-Sqlcmd -unknown $userinput -ServerInstance "MyServer" -Database "MyDatabase" -q $unvalidated # BAD
126+
}
127+
128+
With-Validation $userinput $userinput
129+
130+
$QueryConn3 = @{
131+
Database = "MyDB"
132+
ServerInstance = "MyServer"
133+
Username = "MyUserName"
134+
Password = "MyPassword"
135+
ConnectionTimeout = 0
136+
inputfile = $userinput
137+
}
138+
139+
Invoke-Sqlcmd @QueryConn3 # GOOD

0 commit comments

Comments
 (0)