@@ -498,6 +498,42 @@ private module StdlibPrivate {
498498 override string getFormat ( ) { result = "pickle" }
499499 }
500500
501+ // ---------------------------------------------------------------------------
502+ // shelve
503+ // ---------------------------------------------------------------------------
504+ /**
505+ * A call to `shelve.open`
506+ * See https://docs.python.org/3/library/shelve.html#shelve.open
507+ *
508+ * Claiming there is decoding of the input to `shelve.open` is a bit questionable, since
509+ * it's not the filename, but the contents of the file that is decoded.
510+ *
511+ * However, we definitely want to be able to alert if a user is able to control what
512+ * file is used, since that can lead to code execution (even if that file is free of
513+ * path injection).
514+ *
515+ * So right now the best way we have of modeling this seems to be to treat the filename
516+ * argument as being deserialized...
517+ */
518+ private class ShelveOpenCall extends Decoding:: Range , FileSystemAccess:: Range ,
519+ DataFlow:: CallCfgNode {
520+ ShelveOpenCall ( ) { this = API:: moduleImport ( "shelve" ) .getMember ( "open" ) .getACall ( ) }
521+
522+ override predicate mayExecuteInput ( ) { any ( ) }
523+
524+ override DataFlow:: Node getAnInput ( ) {
525+ result in [ this .getArg ( 0 ) , this .getArgByName ( "filename" ) ]
526+ }
527+
528+ override DataFlow:: Node getAPathArgument ( ) {
529+ result in [ this .getArg ( 0 ) , this .getArgByName ( "filename" ) ]
530+ }
531+
532+ override DataFlow:: Node getOutput ( ) { result = this }
533+
534+ override string getFormat ( ) { result = "pickle" }
535+ }
536+
501537 // ---------------------------------------------------------------------------
502538 // popen2
503539 // ---------------------------------------------------------------------------
0 commit comments