@@ -8,6 +8,7 @@ private import codeql.ruby.controlflow.CfgNodes
8
8
private import codeql.ruby.DataFlow
9
9
private import codeql.ruby.dataflow.RemoteFlowSources
10
10
private import codeql.ruby.ApiGraphs
11
+ private import codeql.ruby.typetracking.TypeTracking
11
12
private import codeql.ruby.frameworks.ActionDispatch
12
13
private import codeql.ruby.frameworks.ActionView
13
14
private import codeql.ruby.frameworks.Rails
@@ -505,6 +506,27 @@ private module ParamsSummaries {
505
506
]
506
507
}
507
508
509
+ /** Gets a field of an instance of `ActionController::Parameters` */
510
+ private DataFlow:: LocalSourceNode paramsField ( ) {
511
+ result =
512
+ [
513
+ paramsInstance ( ) ,
514
+ paramsInstance ( ) .getAMethodCall ( methodReturnsTaintFromSelf ( ) ) .getAnElementRead * ( )
515
+ ]
516
+ }
517
+
518
+ private DataFlow:: LocalSourceNode paramsFieldType ( TypeTracker t ) {
519
+ t .start ( ) and
520
+ result = paramsField ( )
521
+ or
522
+ exists ( TypeTracker t2 | result = paramsFieldType ( t2 ) .track ( t2 , t ) )
523
+ }
524
+
525
+ /** Gets a node with a type that can be a field of `ActionController::Parameters */
526
+ private DataFlow:: LocalSourceNode paramsFieldType ( ) {
527
+ paramsFieldType ( TypeTracker:: end ( ) ) .flowsTo ( result )
528
+ }
529
+
508
530
/**
509
531
* A flow summary for methods on `ActionController::Parameters` which
510
532
* propagate taint from receiver to return value.
@@ -569,6 +591,44 @@ private module ParamsSummaries {
569
591
preservesValue = false
570
592
}
571
593
}
594
+
595
+ /** Flow summaries for `ActiveDispatch::Http::UploadedFile`, which can be an field of `ActionController::Parameters`. */
596
+ module UploadedFileSummaries {
597
+ /** Flow summary for `ActiveDispatch::Http::UploadedFile.original_filename` */
598
+ private class UploadedFileOriginalFilenameSummary extends SummarizedCallable {
599
+ UploadedFileOriginalFilenameSummary ( ) {
600
+ this = "ActionDispatch::Http::UploadedFile::original_filename"
601
+ }
602
+
603
+ override MethodCall getACall ( ) {
604
+ result = paramsFieldType ( ) .getAMethodCall ( "original_filename" ) .asExpr ( ) .getExpr ( ) and
605
+ result .getNumberOfArguments ( ) = 0
606
+ }
607
+
608
+ override predicate propagatesFlow ( string input , string output , boolean preservesValue ) {
609
+ input = "Argument[self]" and output = "ReturnValue" and preservesValue = false
610
+ }
611
+ }
612
+
613
+ /**
614
+ * Flow summary for `ActiveDispatch::Http::UploadedFile.original_filename`,
615
+ * which propagates taint from the receiver to the return value or to the second (buffer) argument
616
+ */
617
+ private class UploadedFileReadSummary extends SummarizedCallable {
618
+ UploadedFileReadSummary ( ) { this = "ActionDispatch::Http::UploadedFile::read" }
619
+
620
+ override MethodCall getACall ( ) {
621
+ result = paramsFieldType ( ) .getAMethodCall ( "read" ) .asExpr ( ) .getExpr ( ) and
622
+ result .getNumberOfArguments ( ) in [ 0 .. 2 ]
623
+ }
624
+
625
+ override predicate propagatesFlow ( string input , string output , boolean preservesValue ) {
626
+ input = "Argument[self]" and
627
+ output = [ "ReturnValue" , "Argument[1]" ] and
628
+ preservesValue = false
629
+ }
630
+ }
631
+ }
572
632
}
573
633
574
634
/**
0 commit comments