@@ -6,7 +6,9 @@ import csharp
6
6
private import Remote
7
7
private import semmle.code.csharp.commons.Loggers
8
8
private import semmle.code.csharp.frameworks.system.Web
9
+ private import semmle.code.csharp.frameworks.system.IO
9
10
private import semmle.code.csharp.dataflow.ExternalFlow
11
+ private import semmle.code.csharp.dataflow.DataFlow
10
12
11
13
/**
12
14
* An external location sink.
@@ -63,3 +65,66 @@ class CookieStorageSink extends ExternalLocationSink, RemoteFlowSink {
63
65
)
64
66
}
65
67
}
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