@@ -6,7 +6,9 @@ import csharp
66private import Remote
77private import semmle.code.csharp.commons.Loggers
88private import semmle.code.csharp.frameworks.system.Web
9+ private import semmle.code.csharp.frameworks.system.IO
910private import semmle.code.csharp.dataflow.ExternalFlow
11+ private import semmle.code.csharp.dataflow.DataFlow
1012
1113/**
1214 * An external location sink.
@@ -63,3 +65,66 @@ class CookieStorageSink extends ExternalLocationSink, RemoteFlowSink {
6365 )
6466 }
6567}
68+
69+ private predicate isFileWriteCall ( Expr stream , Expr data ) {
70+ exists ( MethodCall mc , Method m | mc .getTarget ( ) = m .getAnOverrider * ( ) |
71+ mc .getTarget ( ) .hasQualifiedName ( "System.IO" , "Stream" , [ "Write" , "WriteAsync" ] ) and
72+ stream = mc .getQualifier ( ) and
73+ data = mc .getArgument ( 0 )
74+ or
75+ mc .getTarget ( )
76+ .hasQualifiedName ( "System.IO" , "TextWriter" ,
77+ [ "Write" , "WriteAsync" , "WriteLine" , "WriteLineAsync" ] ) and
78+ stream = mc .getQualifier ( ) and
79+ data = mc .getArgument ( 0 )
80+ or
81+ mc .getTarget ( ) .hasQualifiedName ( "System.Xml.Linq" , "XDocument" , [ "Save" , "SaveAsync" ] ) and
82+ data = mc .getQualifier ( ) and
83+ stream = mc .getArgument ( 0 )
84+ )
85+ }
86+
87+ private module LocalFileOutputStreamConfig implements DataFlow:: ConfigSig {
88+ predicate isSource ( DataFlow:: Node src ) {
89+ exists ( MethodCall mc | mc = src .asExpr ( ) |
90+ mc .getTarget ( ) .hasQualifiedName ( "System.IO" , "File" , [ "Open" , "Create" , "OpenWrite" ] )
91+ or
92+ mc .getTarget ( )
93+ .hasQualifiedName ( "System.IO" , "FileInfo" ,
94+ [ "AppendText" , "Create" , "CreateText" , "Open" , "OpenText" , "OpenWrite" ] )
95+ )
96+ or
97+ exists ( ObjectCreation oc | oc = src .asExpr ( ) |
98+ oc .getObjectType ( ) instanceof SystemIOStreamWriterClass and
99+ oc .getArgument ( 0 ) .getType ( ) instanceof StringType
100+ )
101+ }
102+
103+ predicate isSink ( DataFlow:: Node sink ) { isFileWriteCall ( sink .asExpr ( ) , _) }
104+
105+ predicate isBarrier ( DataFlow:: Node node ) {
106+ node .asExpr ( )
107+ .( ObjectCreation )
108+ .getObjectType ( )
109+ .hasQualifiedName ( "System.Security.Cryptography" , "CryptoStream" )
110+ }
111+
112+ predicate isAdditionalFlowStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
113+ exists ( ObjectCreation oc |
114+ node2 .asExpr ( ) = oc and
115+ node1 .asExpr ( ) = oc .getArgument ( 0 ) and
116+ oc .getObjectType ( ) instanceof SystemIOStreamWriterClass
117+ )
118+ }
119+ }
120+
121+ private module LocalFileOutputStreamFlow = DataFlow:: Make< LocalFileOutputStreamConfig > ;
122+
123+ class LocalFileOutputSink extends ExternalLocationSink {
124+ LocalFileOutputSink ( ) {
125+ exists ( DataFlow:: Node streamSink |
126+ LocalFileOutputStreamFlow:: hasFlow ( _, streamSink ) and
127+ isFileWriteCall ( streamSink .asExpr ( ) , this .asExpr ( ) )
128+ )
129+ }
130+ }
0 commit comments