66import csharp
77
88module XSS {
9- import semmle.code.csharp.security.dataflow.flowsources.Remote
10- import semmle.code.csharp.frameworks.microsoft.AspNetCore
9+ import semmle.code.asp.AspNet
1110 import semmle.code.csharp.frameworks.system.Net
1211 import semmle.code.csharp.frameworks.system.Web
13- import semmle.code.csharp.frameworks.system.web.Mvc
14- import semmle.code.csharp.frameworks.system.web.WebPages
1512 import semmle.code.csharp.frameworks.system.web.UI
16- import semmle.code.csharp.frameworks.system.web.ui.WebControls
17- import semmle.code.csharp.frameworks.system.windows.Forms
1813 import semmle.code.csharp.security.Sanitizers
19- import semmle.code.asp.AspNet
14+ import semmle.code.csharp.security.dataflow.flowsinks.Html
15+ import semmle.code.csharp.security.dataflow.flowsources.Remote
2016
2117 /**
2218 * Holds if there is tainted flow from `source` to `sink` that may lead to a
@@ -166,78 +162,21 @@ module XSS {
166162 UrlEncodeSanitizer ( ) { this .getExpr ( ) instanceof UrlSanitizedExpr }
167163 }
168164
169- /** A sink where the value of the expression may be rendered as HTML. */
170- abstract class HtmlSink extends DataFlow:: Node { }
171-
172- /**
173- * An expression that is used as an argument to an XSS sink method on
174- * `HttpResponse`.
175- */
176- private class HttpResponseSink extends Sink , HtmlSink {
177- HttpResponseSink ( ) {
178- exists ( Method m , SystemWebHttpResponseClass responseClass |
179- m = responseClass .getAWriteMethod ( ) or
180- m = responseClass .getAWriteFileMethod ( ) or
181- m = responseClass .getATransmitFileMethod ( ) or
182- m = responseClass .getABinaryWriteMethod ( )
183- |
184- // Calls to these methods, or overrides of them
185- this .getExpr ( ) = m .getAnOverrider * ( ) .getParameter ( 0 ) .getAnAssignedArgument ( )
186- )
187- }
188- }
189-
190- /**
191- * An expression that is used as an argument to an XSS sink method on
192- * `HtmlTextWriter`.
193- */
194- private class HtmlTextWriterSink extends Sink , HtmlSink {
195- HtmlTextWriterSink ( ) {
196- exists ( SystemWebUIHtmlTextWriterClass writeClass , Method m , Call c , int paramPos |
197- paramPos = 0 and
198- (
199- m = writeClass .getAWriteMethod ( ) or
200- m = writeClass .getAWriteLineMethod ( ) or
201- m = writeClass .getAWriteLineNoTabsMethod ( ) or
202- m = writeClass .getAWriteBeginTagMethod ( ) or
203- m = writeClass .getAWriteAttributeMethod ( )
204- )
205- or
206- // The second parameter to the `WriteAttribute` method is the attribute value, which we
207- // should only consider as tainted if the call does not ask for the attribute value to be
208- // encoded using the final parameter.
209- m = writeClass .getAWriteAttributeMethod ( ) and
210- paramPos = 1 and
211- not c .getArgumentForParameter ( m .getParameter ( 2 ) ) .( BoolLiteral ) .getBoolValue ( ) = true
212- |
213- c = m .getACall ( ) and
214- this .getExpr ( ) = c .getArgumentForParameter ( m .getParameter ( paramPos ) )
215- )
216- }
217- }
218-
219- /**
220- * An expression that is used as an argument to an XSS sink method on
221- * `AttributeCollection`.
222- */
223- private class AttributeCollectionSink extends Sink , HtmlSink {
224- AttributeCollectionSink ( ) {
225- exists ( SystemWebUIAttributeCollectionClass ac , Parameter p |
226- p = ac .getAddMethod ( ) .getParameter ( 1 ) or
227- p = ac .getItemProperty ( ) .getSetter ( ) .getParameter ( 0 )
228- |
229- this .getExpr ( ) = p .getAnAssignedArgument ( )
230- )
231- }
232- }
165+ private class HtmlSinkSink extends Sink {
166+ HtmlSinkSink ( ) { this instanceof HtmlSink }
233167
234- /**
235- * An expression that is used as the second argument `HtmlElement.SetAttribute`.
236- */
237- private class SetAttributeSink extends Sink , HtmlSink {
238- SetAttributeSink ( ) {
239- this .getExpr ( ) =
240- any ( SystemWindowsFormsHtmlElement c ) .getSetAttributeMethod ( ) .getACall ( ) .getArgument ( 1 )
168+ override string explanation ( ) {
169+ this instanceof WebPageWriteLiteralSink and
170+ result = "System.Web.WebPages.WebPage.WriteLiteral() method"
171+ or
172+ this instanceof WebPageWriteLiteralToSink and
173+ result = "System.Web.WebPages.WebPage.WriteLiteralTo() method"
174+ or
175+ this instanceof MicrosoftAspNetCoreMvcHtmlHelperRawSink and
176+ result = "Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper.Raw() method"
177+ or
178+ this instanceof MicrosoftAspNetRazorPageWriteLiteralSink and
179+ result = "Microsoft.AspNetCore.Mvc.Razor.RazorPageBase.WriteLiteral() method"
241180 }
242181 }
243182
@@ -285,31 +224,6 @@ module XSS {
285224 }
286225 }
287226
288- /**
289- * An expression that is used as an argument to an XSS sink setter, on
290- * a class within the `System.Web.UI` namespace.
291- */
292- private class SystemWebSetterHtmlSink extends Sink , HtmlSink {
293- SystemWebSetterHtmlSink ( ) {
294- exists ( Property p , string name , ValueOrRefType declaringType |
295- declaringType = p .getDeclaringType ( ) and
296- any ( SystemWebUINamespace n ) .getAChildNamespace * ( ) = declaringType .getNamespace ( ) and
297- this .getExpr ( ) = p .getSetter ( ) .getParameter ( 0 ) .getAnAssignedArgument ( ) and
298- p .hasName ( name )
299- |
300- name = "Caption" and
301- ( declaringType .hasName ( "Calendar" ) or declaringType .hasName ( "Table" ) )
302- or
303- name = "InnerHtml"
304- )
305- or
306- exists ( SystemWebUIWebControlsLabelClass c |
307- // Unlike `Text` properties of other web controls, `Label.Text` is not automatically HTML encoded
308- this .getExpr ( ) = c .getTextProperty ( ) .getSetter ( ) .getParameter ( 0 ) .getAnAssignedArgument ( )
309- )
310- }
311- }
312-
313227 /**
314228 * An expression that is used as an argument to an XSS sink setter, on
315229 * a class within the `System.Web.UI` namespace.
@@ -345,16 +259,6 @@ module XSS {
345259 }
346260 }
347261
348- /**
349- * An expression that is used as an argument to `HtmlHelper.Raw`, typically in
350- * a `.cshtml` file.
351- */
352- private class SystemWebMvcHtmlHelperRawSink extends Sink , HtmlSink {
353- SystemWebMvcHtmlHelperRawSink ( ) {
354- this .getExpr ( ) = any ( SystemWebMvcHtmlHelperClass h ) .getRawMethod ( ) .getACall ( ) .getAnArgument ( )
355- }
356- }
357-
358262 /**
359263 * Gets a member which is accessed by the given `AspInlineCode`.
360264 * The code body must consist only of an access to the member, possibly with qualified
@@ -493,31 +397,6 @@ module XSS {
493397 }
494398 }
495399
496- /** An expression that is returned from a `ToHtmlString` method. */
497- private class ToHtmlString extends Sink , HtmlSink {
498- ToHtmlString ( ) {
499- exists ( Method toHtmlString |
500- toHtmlString =
501- any ( SystemWebIHtmlString i ) .getToHtmlStringMethod ( ) .getAnUltimateImplementor ( ) and
502- toHtmlString .canReturn ( this .getExpr ( ) )
503- )
504- }
505- }
506-
507- /**
508- * An expression passed to the constructor of an `HtmlString` or a `MvcHtmlString`.
509- */
510- private class HtmlString extends Sink , HtmlSink {
511- HtmlString ( ) {
512- exists ( Class c |
513- c = any ( SystemWebMvcMvcHtmlString m ) or
514- c = any ( SystemWebHtmlString m )
515- |
516- this .getExpr ( ) = c .getAConstructor ( ) .getACall ( ) .getAnArgument ( )
517- )
518- }
519- }
520-
521400 /**
522401 * An expression passed as the `content` argument to the constructor of `StringContent`.
523402 */
@@ -529,75 +408,6 @@ module XSS {
529408 ) .getArgumentForName ( "content" )
530409 }
531410 }
532-
533- /**
534- * An expression that is used as an argument to `Page.WriteLiteral`, typically in
535- * a `.cshtml` file.
536- */
537- class WebPageWriteLiteralSink extends Sink , HtmlSink {
538- WebPageWriteLiteralSink ( ) {
539- this .getExpr ( ) = any ( WebPageClass h ) .getWriteLiteralMethod ( ) .getACall ( ) .getAnArgument ( )
540- }
541-
542- override string explanation ( ) { result = "System.Web.WebPages.WebPage.WriteLiteral() method" }
543- }
544-
545- /**
546- * An expression that is used as an argument to `Page.WriteLiteralTo`, typically in
547- * a `.cshtml` file.
548- */
549- class WebPageWriteLiteralToSink extends Sink , HtmlSink {
550- WebPageWriteLiteralToSink ( ) {
551- this .getExpr ( ) = any ( WebPageClass h ) .getWriteLiteralToMethod ( ) .getACall ( ) .getAnArgument ( )
552- }
553-
554- override string explanation ( ) { result = "System.Web.WebPages.WebPage.WriteLiteralTo() method" }
555- }
556-
557- abstract class AspNetCoreSink extends Sink , HtmlSink { }
558-
559- /**
560- * An expression that is used as an argument to `HtmlHelper.Raw`, typically in
561- * a `.cshtml` file.
562- */
563- class MicrosoftAspNetCoreMvcHtmlHelperRawSink extends AspNetCoreSink {
564- MicrosoftAspNetCoreMvcHtmlHelperRawSink ( ) {
565- this .getExpr ( ) =
566- any ( MicrosoftAspNetCoreMvcHtmlHelperClass h ) .getRawMethod ( ) .getACall ( ) .getAnArgument ( )
567- }
568-
569- override string explanation ( ) {
570- result = "Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper.Raw() method"
571- }
572- }
573-
574- /**
575- * An expression that is used as an argument to `Page.WriteLiteral` in ASP.NET 6.0 razor page, typically in
576- * a `.cshtml` file.
577- */
578- class MicrosoftAspNetRazorPageWriteLiteralSink extends AspNetCoreSink {
579- MicrosoftAspNetRazorPageWriteLiteralSink ( ) {
580- this .getExpr ( ) =
581- any ( MicrosoftAspNetCoreMvcRazorPageBase h )
582- .getWriteLiteralMethod ( )
583- .getACall ( )
584- .getAnArgument ( )
585- }
586-
587- override string explanation ( ) {
588- result = "Microsoft.AspNetCore.Mvc.Razor.RazorPageBase.WriteLiteral() method"
589- }
590- }
591-
592- /** `HtmlString` that may be rendered as is need to have sanitized value. */
593- class MicrosoftAspNetHtmlStringSink extends AspNetCoreSink {
594- MicrosoftAspNetHtmlStringSink ( ) {
595- exists ( ObjectCreation c , MicrosoftAspNetCoreHttpHtmlString s |
596- c .getTarget ( ) = s .getAConstructor ( ) and
597- this .asExpr ( ) = c .getAnArgument ( )
598- )
599- }
600- }
601411}
602412
603413private Type getMemberType ( Member m ) {
0 commit comments