@@ -52,20 +52,27 @@ module SqlInjection {
5252
5353 private string inputfile ( ) { result = [ "inputfile" , "i" ] }
5454
55+ bindingset [ call]
56+ pragma [ inline_late]
57+ private predicate sqlCmdSinkCommon ( DataFlow:: CallNode call , DataFlow:: Node s ) {
58+ s = call .getNamedArgument ( query ( ) )
59+ or
60+ // If the input is not provided as a query parameter or an input file
61+ // parameter then it's the first argument.
62+ not call .hasNamedArgument ( query ( ) ) and
63+ not call .hasNamedArgument ( inputfile ( ) ) and
64+ s = call .getArgument ( 0 )
65+ or
66+ // TODO: Here we really should pick a splat argument, but we don't yet extract whether an
67+ // argument is a splat argument.
68+ s = unique( | | call .getAnArgument ( ) )
69+ }
70+
5571 class InvokeSqlCmdSink extends Sink {
5672 InvokeSqlCmdSink ( ) {
57- exists ( DataFlow:: CallNode call | call .matchesName ( "Invoke-Sqlcmd" ) |
58- this = call .getNamedArgument ( query ( ) )
59- or
60- // If the input is not provided as a query parameter or an input file
61- // parameter then it's the first argument.
62- not call .hasNamedArgument ( query ( ) ) and
63- not call .hasNamedArgument ( inputfile ( ) ) and
64- this = call .getArgument ( 0 )
65- or
66- // TODO: Here we really should pick a splat argument, but we don't yet extract whether an
67- // argument is a splat argument.
68- this = unique( | | call .getAnArgument ( ) )
73+ exists ( DataFlow:: CallNode call |
74+ call .matchesName ( "Invoke-Sqlcmd" ) and
75+ sqlCmdSinkCommon ( call , this )
6976 )
7077 }
7178
@@ -94,11 +101,17 @@ module SqlInjection {
94101 override string getSinkType ( ) { result = "write to " + memberName }
95102 }
96103
104+ /**
105+ * A call of the form `&sqlcmd`.
106+ *
107+ * We don't know if this is actually a call to an SQL execution procedure, but it is
108+ * very common to define a `sqlcmd` variable and point it to an SQL execution program.
109+ */
97110 class SqlCmdSink extends Sink {
98111 SqlCmdSink ( ) {
99112 exists ( DataFlow:: CallOperatorNode call |
100113 call .getCommand ( ) .asExpr ( ) .getValue ( ) .stringMatches ( "sqlcmd" ) and
101- call . getAnArgument ( ) = this
114+ sqlCmdSinkCommon ( call , this )
102115 )
103116 }
104117
0 commit comments