@@ -353,12 +353,32 @@ class Libxml2BadOption extends EnumConstant {
353
353
}
354
354
355
355
/**
356
- * A configuration for tracking XML objects and their states .
356
+ * An XML library or interface .
357
357
*/
358
- class XXEConfiguration extends DataFlow:: Configuration {
359
- XXEConfiguration ( ) { this = "XXEConfiguration" }
358
+ abstract class XmlLibrary extends string {
359
+ bindingset [ this ]
360
+ XmlLibrary ( ) { any ( ) } // required characteristic predicate
360
361
361
- override predicate isSource ( DataFlow:: Node node , string flowstate ) {
362
+ /**
363
+ * The source node for a potentially unsafe configuration object for this XML
364
+ * library, along with `flowstate` representing its initial state.
365
+ */
366
+ abstract predicate configurationSource ( DataFlow:: Node node , string flowstate ) ;
367
+
368
+ /**
369
+ * The sink node where an unsafe configuration object is used to interpret
370
+ * XML.
371
+ */
372
+ abstract predicate configurationSink ( DataFlow:: Node node , string flowstate ) ;
373
+ }
374
+
375
+ /**
376
+ * The `XercesDOMParser` interface for the Xerces XML library.
377
+ */
378
+ class XercesDomParserLibrary extends XmlLibrary {
379
+ XercesDomParserLibrary ( ) { this = "XercesDomParserLibrary" }
380
+
381
+ override predicate configurationSource ( DataFlow:: Node node , string flowstate ) {
362
382
// source is the write on `this` of a call to the `XercesDOMParser`
363
383
// constructor.
364
384
exists ( CallInstruction call |
@@ -367,14 +387,46 @@ class XXEConfiguration extends DataFlow::Configuration {
367
387
call .getThisArgument ( ) and
368
388
encodeXercesFlowState ( flowstate , 0 , 1 ) // default configuration
369
389
)
370
- or
390
+ }
391
+
392
+ override predicate configurationSink ( DataFlow:: Node node , string flowstate ) {
393
+ // sink is the read of the qualifier of a call to `parse`.
394
+ exists ( Call call |
395
+ call .getTarget ( ) instanceof ParseFunction and
396
+ call .getQualifier ( ) = node .asConvertedExpr ( )
397
+ ) and
398
+ flowstate instanceof XercesFlowState and
399
+ not encodeXercesFlowState ( flowstate , 1 , 1 ) // safe configuration
400
+ }
401
+ }
402
+
403
+ /**
404
+ * The createLSParser interface for the Xerces XML library.
405
+ */
406
+ class CreateLSParserLibrary extends XmlLibrary {
407
+ CreateLSParserLibrary ( ) { this = "CreateLSParserLibrary" }
408
+
409
+ override predicate configurationSource ( DataFlow:: Node node , string flowstate ) {
371
410
// source is the result of a call to `createLSParser`.
372
411
exists ( Call call |
373
412
call .getTarget ( ) instanceof CreateLSParser and
374
413
call = node .asExpr ( ) and
375
414
encodeXercesFlowState ( flowstate , 0 , 1 ) // default configuration
376
415
)
377
- or
416
+ }
417
+
418
+ override predicate configurationSink ( DataFlow:: Node node , string flowstate ) {
419
+ none ( ) // uses the existing sinks from `XercesDomParserLibrary`
420
+ }
421
+ }
422
+
423
+ /**
424
+ * The SAXParser interface for the Xerces XML library.
425
+ */
426
+ class SaxParserLibrary extends XmlLibrary {
427
+ SaxParserLibrary ( ) { this = "SaxParserLibrary" }
428
+
429
+ override predicate configurationSource ( DataFlow:: Node node , string flowstate ) {
378
430
// source is the write on `this` of a call to the `SAXParser`
379
431
// constructor.
380
432
exists ( CallInstruction call |
@@ -383,18 +435,44 @@ class XXEConfiguration extends DataFlow::Configuration {
383
435
call .getThisArgument ( ) and
384
436
encodeXercesFlowState ( flowstate , 0 , 1 ) // default configuration
385
437
)
386
- or
438
+ }
439
+
440
+ override predicate configurationSink ( DataFlow:: Node node , string flowstate ) {
441
+ none ( ) // uses the existing sinks from `XercesDomParserLibrary`
442
+ }
443
+ }
444
+
445
+ /**
446
+ * The SAX2XMLReader interface for the Xerces XML library.
447
+ */
448
+ class Sax2XmlReaderLibrary extends XmlLibrary {
449
+ Sax2XmlReaderLibrary ( ) { this = "Sax2XmlReaderLibrary" }
450
+
451
+ override predicate configurationSource ( DataFlow:: Node node , string flowstate ) {
387
452
// source is the result of a call to `createXMLReader`.
388
453
exists ( Call call |
389
454
call .getTarget ( ) instanceof CreateXmlReader and
390
455
call = node .asExpr ( ) and
391
456
encodeXercesFlowState ( flowstate , 0 , 1 ) // default configuration
392
457
)
393
- or
394
- // source is an `options` argument on a `libxml2` parse call that specifies
458
+ }
459
+
460
+ override predicate configurationSink ( DataFlow:: Node node , string flowstate ) {
461
+ none ( ) // uses the existing sinks from `XercesDomParserLibrary`
462
+ }
463
+ }
464
+
465
+ /**
466
+ * The libxml2 XML library.
467
+ */
468
+ class LibXml2Library extends XmlLibrary {
469
+ LibXml2Library ( ) { this = "LibXml2Library" }
470
+
471
+ override predicate configurationSource ( DataFlow:: Node node , string flowstate ) {
472
+ // source is an `options` argument on a libxml2 parse call that specifies
395
473
// at least one unsafe option.
396
474
//
397
- // note: we don't need to track an XML object for ` libxml2` , so we don't
475
+ // note: we don't need to track an XML object for libxml2, so we don't
398
476
// really need data flow. Nevertheless we jam it into this configuration,
399
477
// with matching sources and sinks. This allows results to be presented by
400
478
// the same query, in a consistent way as other results with flow paths.
@@ -409,22 +487,29 @@ class XXEConfiguration extends DataFlow::Configuration {
409
487
)
410
488
}
411
489
412
- override predicate isSink ( DataFlow:: Node node , string flowstate ) {
413
- // sink is the read of the qualifier of a call to `parse`.
414
- exists ( Call call |
415
- call .getTarget ( ) instanceof ParseFunction and
416
- call .getQualifier ( ) = node .asConvertedExpr ( )
417
- ) and
418
- flowstate instanceof XercesFlowState and
419
- not encodeXercesFlowState ( flowstate , 1 , 1 ) // safe configuration
420
- or
490
+ override predicate configurationSink ( DataFlow:: Node node , string flowstate ) {
421
491
// sink is the `options` argument on a `libxml2` parse call.
422
492
exists ( Libxml2ParseCall call , Expr options |
423
493
options = call .getOptions ( ) and
424
494
node .asExpr ( ) = options and
425
495
flowstate = "libxml2"
426
496
)
427
497
}
498
+ }
499
+
500
+ /**
501
+ * A configuration for tracking XML objects and their states.
502
+ */
503
+ class XXEConfiguration extends DataFlow:: Configuration {
504
+ XXEConfiguration ( ) { this = "XXEConfiguration" }
505
+
506
+ override predicate isSource ( DataFlow:: Node node , string flowstate ) {
507
+ any ( XmlLibrary l ) .configurationSource ( node , flowstate )
508
+ }
509
+
510
+ override predicate isSink ( DataFlow:: Node node , string flowstate ) {
511
+ any ( XmlLibrary l ) .configurationSink ( node , flowstate )
512
+ }
428
513
429
514
override predicate isAdditionalFlowStep (
430
515
DataFlow:: Node node1 , string state1 , DataFlow:: Node node2 , string state2
0 commit comments