@@ -25,25 +25,36 @@ module UnsafeDeserialization {
25
25
/** A source of remote user input, considered as a flow source for unsafe deserialization. */
26
26
class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource { }
27
27
28
+ private API:: Node unsafeYamlSchema ( ) {
29
+ result = API:: moduleImport ( "js-yaml" ) .getMember ( "DEFAULT_FULL_SCHEMA" ) // from older versions
30
+ or
31
+ result = API:: moduleImport ( "js-yaml-js-types" ) .getMember ( [ "all" , "function" ] )
32
+ or
33
+ result = unsafeYamlSchema ( ) .getMember ( "extend" ) .getReceiver ( )
34
+ or
35
+ exists ( API:: CallNode call |
36
+ call .getAParameter ( ) .refersTo ( unsafeYamlSchema ( ) ) and
37
+ call .getCalleeName ( ) = "extend" and
38
+ result = call .getReturn ( )
39
+ )
40
+ }
41
+
28
42
/**
29
43
* An expression passed to one of the unsafe load functions of the `js-yaml` package.
44
+ *
45
+ * `js-yaml` since v4 defaults to being safe, but is unsafe when invoked with a schema
46
+ * that permits unsafe values.
30
47
*/
31
48
class JsYamlUnsafeLoad extends Sink {
32
49
JsYamlUnsafeLoad ( ) {
33
- exists ( DataFlow:: ModuleImportNode mi | mi .getPath ( ) = "js-yaml" |
34
- // the first argument to a call to `load` or `loadAll`
35
- exists ( string n | n = "load" or n = "loadAll" | this = mi .getAMemberCall ( n ) .getArgument ( 0 ) )
36
- or
37
- // the first argument to a call to `safeLoad` or `safeLoadAll` where
38
- // the schema is specified to be `DEFAULT_FULL_SCHEMA`
39
- exists ( string n , DataFlow:: CallNode c , DataFlow:: Node fullSchema |
40
- n = "safeLoad" or n = "safeLoadAll"
41
- |
42
- c = mi .getAMemberCall ( n ) and
43
- this = c .getArgument ( 0 ) and
44
- fullSchema = c .getOptionArgument ( c .getNumArgument ( ) - 1 , "schema" ) and
45
- mi .getAPropertyRead ( "DEFAULT_FULL_SCHEMA" ) .flowsTo ( fullSchema )
46
- )
50
+ exists ( API:: CallNode call |
51
+ // Note: we include the old 'safeLoad' and 'safeLoadAll' functon because they were also unsafe when invoked with an unsafe schema.
52
+ call =
53
+ API:: moduleImport ( "js-yaml" )
54
+ .getMember ( [ "load" , "loadAll" , "safeLoad" , "safeLoadAll" ] )
55
+ .getACall ( ) and
56
+ call .getAParameter ( ) .getMember ( "schema" ) .refersTo ( unsafeYamlSchema ( ) ) and
57
+ this = call .getArgument ( 0 )
47
58
)
48
59
}
49
60
}
0 commit comments