33 */
44
55import javascript
6+ import semmle.javascript.Promises
67
78module SQL {
89 /** A string-valued expression that is interpreted as a SQL command. */
@@ -81,6 +82,8 @@ private module MySql {
8182 )
8283 }
8384
85+ override DataFlow:: Node getAResult ( ) { result = this .getCallback ( _) .getParameter ( 1 ) }
86+
8487 override DataFlow:: Node getAQueryArgument ( ) { result = this .getArgument ( 0 ) }
8588 }
8689
@@ -178,6 +181,16 @@ private module Postgres {
178181 private class QueryCall extends DatabaseAccess , DataFlow:: MethodCallNode {
179182 QueryCall ( ) { this = [ client ( ) , pool ( ) ] .getMember ( "query" ) .getACall ( ) }
180183
184+ override DataFlow:: Node getAResult ( ) {
185+ this .getNumArgument ( ) = 2 and
186+ result = this .getCallback ( 1 ) .getParameter ( 1 )
187+ or
188+ this .getNumArgument ( ) = 1 and
189+ result = this .getAMethodCall ( "then" ) .getCallback ( 0 ) .getParameter ( 0 )
190+ or
191+ PromiseFlow:: loadStep ( this .getALocalUse ( ) , result , Promises:: valueProp ( ) )
192+ }
193+
181194 override DataFlow:: Node getAQueryArgument ( ) { result = this .getArgument ( 0 ) }
182195 }
183196
@@ -322,6 +335,10 @@ private module Postgres {
322335 )
323336 }
324337
338+ override DataFlow:: Node getAResult ( ) {
339+ PromiseFlow:: loadStep ( this .getALocalUse ( ) , result , Promises:: valueProp ( ) )
340+ }
341+
325342 override DataFlow:: Node getAQueryArgument ( ) {
326343 result = this .getADirectQueryArgument ( )
327344 or
@@ -370,6 +387,11 @@ private module Sqlite {
370387 this = database ( ) .getMember ( "prepare" ) .getACall ( )
371388 }
372389
390+ override DataFlow:: Node getAResult ( ) {
391+ result = this .getCallback ( 1 ) .getParameter ( 1 ) or
392+ PromiseFlow:: loadStep ( this .getALocalUse ( ) , result , Promises:: valueProp ( ) )
393+ }
394+
373395 override DataFlow:: Node getAQueryArgument ( ) { result = this .getArgument ( 0 ) }
374396 }
375397
@@ -413,13 +435,17 @@ private module MsSql {
413435 API:: Node pool ( ) { result = mssqlClass ( "ConnectionPool" ) }
414436
415437 /** A tagged template evaluated as a query. */
416- private class QueryTemplateExpr extends DatabaseAccess , DataFlow:: ValueNode {
438+ private class QueryTemplateExpr extends DatabaseAccess , DataFlow:: ValueNode , DataFlow :: SourceNode {
417439 override TaggedTemplateExpr astNode ;
418440
419441 QueryTemplateExpr ( ) {
420442 mssql ( ) .getMember ( "query" ) .getAUse ( ) = DataFlow:: valueNode ( astNode .getTag ( ) )
421443 }
422444
445+ override DataFlow:: Node getAResult ( ) {
446+ PromiseFlow:: loadStep ( this .getALocalUse ( ) , result , Promises:: valueProp ( ) )
447+ }
448+
423449 override DataFlow:: Node getAQueryArgument ( ) {
424450 result = DataFlow:: valueNode ( astNode .getTemplate ( ) .getAnElement ( ) )
425451 }
@@ -429,6 +455,12 @@ private module MsSql {
429455 private class QueryCall extends DatabaseAccess , DataFlow:: MethodCallNode {
430456 QueryCall ( ) { this = [ mssql ( ) , request ( ) ] .getMember ( [ "query" , "batch" ] ) .getACall ( ) }
431457
458+ override DataFlow:: Node getAResult ( ) {
459+ result = this .getCallback ( 1 ) .getParameter ( 1 )
460+ or
461+ PromiseFlow:: loadStep ( this .getALocalUse ( ) , result , Promises:: valueProp ( ) )
462+ }
463+
432464 override DataFlow:: Node getAQueryArgument ( ) { result = this .getArgument ( 0 ) }
433465 }
434466
@@ -505,6 +537,12 @@ private module Sequelize {
505537 ]
506538 }
507539 }
540+
541+ class SequelizeSource extends ModelInput:: SourceModelCsv {
542+ override predicate row ( string row ) {
543+ row = "sequelize;Sequelize;Member[query].ReturnValue.Awaited;database-access-result"
544+ }
545+ }
508546}
509547
510548private module SpannerCsv {
@@ -516,7 +554,10 @@ private module SpannerCsv {
516554 "@google-cloud/spanner;;@google-cloud/spanner;;Member[Spanner]" ,
517555 "@google-cloud/spanner;Database;@google-cloud/spanner;;ReturnValue.Member[instance].ReturnValue.Member[database].ReturnValue" ,
518556 "@google-cloud/spanner;v1.SpannerClient;@google-cloud/spanner;;Member[v1].Member[SpannerClient].Instance" ,
519- "@google-cloud/spanner;Transaction;@google-cloud/spanner;Database;Member[runTransaction,runTransactionAsync].Argument[0..1].Parameter[1]" ,
557+ "@google-cloud/spanner;Transaction;@google-cloud/spanner;Database;Member[runTransaction,runTransactionAsync,getTransaction].Argument[0..1].Parameter[1]" ,
558+ "@google-cloud/spanner;Transaction;@google-cloud/spanner;Database;Member[getTransaction].ReturnValue.Awaited" ,
559+ "@google-cloud/spanner;Snapshot;@google-cloud/spanner;Database;Member[getSnapshot].Argument[0..1].Parameter[1]" ,
560+ "@google-cloud/spanner;Snapshot;@google-cloud/spanner;Database;Member[getSnapshot].ReturnValue.Awaited" ,
520561 "@google-cloud/spanner;BatchTransaction;@google-cloud/spanner;Database;Member[batchTransaction].ReturnValue" ,
521562 "@google-cloud/spanner;BatchTransaction;@google-cloud/spanner;Database;Member[createBatchTransaction].ReturnValue.Awaited" ,
522563 "@google-cloud/spanner;~SqlExecutorDirect;@google-cloud/spanner;Database;Member[run,runPartitionedUpdate,runStream]" ,
@@ -539,4 +580,23 @@ private module SpannerCsv {
539580 ]
540581 }
541582 }
583+
584+ class SpannerSources extends ModelInput:: SourceModelCsv {
585+ string spannerClass ( ) { result = [ "v1.SpannerClient" , "Database" , "Transaction" , "Snapshot" , ] }
586+
587+ string resultPath ( ) {
588+ result =
589+ [
590+ "Member[executeSql].Argument[0..].Parameter[1]" ,
591+ "Member[executeSql].ReturnValue.Awaited.Member[0]" , "Member[run].ReturnValue.Awaited" ,
592+ "Member[run].Argument[0..].Parameter[1]" ,
593+ ]
594+ }
595+
596+ override predicate row ( string row ) {
597+ row =
598+ "@google-cloud/spanner;" + this .spannerClass ( ) + ";" + this .resultPath ( ) +
599+ ";database-access-result"
600+ }
601+ }
542602}
0 commit comments