diff --git a/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/Views/Test/Test.cshtml b/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/Views/Test/Test.cshtml index 74a8eab1c71..3489539fe87 100644 --- a/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/Views/Test/Test.cshtml +++ b/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/Views/Test/Test.cshtml @@ -1,7 +1,6 @@ -@namespace test +@page + @model UserData -@{ -} @if (Model != null) { diff --git a/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/Views/_ViewImports.cshtml b/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/Views/_ViewImports.cshtml new file mode 100644 index 00000000000..f4d0ca8def7 --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/Views/_ViewImports.cshtml @@ -0,0 +1,3 @@ +@using test + +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/XSS.expected b/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/XSS.expected index e69de29bb2d..c5e1e6db6d6 100644 --- a/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/XSS.expected +++ b/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/XSS.expected @@ -0,0 +1 @@ +| Views/Test/Test.cshtml:7:27:7:36 | access to property Name | Controllers/TestController.cs:13:40:13:47 | tainted1 : UserData | Views/Test/Test.cshtml:7:27:7:36 | access to property Name | $@ flows to here and is written to HTML or JavaScript: Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper.Raw() method. | Controllers/TestController.cs:13:40:13:47 | tainted1 : UserData | User-provided value | diff --git a/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/XSS.ql b/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/XSS.ql new file mode 100644 index 00000000000..762d792b92f --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/XSS.ql @@ -0,0 +1,21 @@ +/** + * @name Cross-site scripting + * @description Writing user input directly to a web page + * allows for a cross-site scripting vulnerability. + * @kind path-problem + * @problem.severity error + * @security-severity 6.1 + * @precision high + * @id cs/web/xss + * @tags security + * external/cwe/cwe-079 + * external/cwe/cwe-116 + */ + +import csharp +import semmle.code.csharp.security.dataflow.XSSQuery + +// import PathGraph // exclude query predicates with output dependant on the absolute filepath the tests are run in +from XssNode source, XssNode sink, string message +where xssFlow(source, sink, message) +select sink, source, sink, "$@ flows to here and " + message, source, "User-provided value" diff --git a/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/XSS.qlref b/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/XSS.qlref deleted file mode 100644 index faad1d6403c..00000000000 --- a/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/XSS.qlref +++ /dev/null @@ -1 +0,0 @@ -Security Features/CWE-079/XSS.ql \ No newline at end of file diff --git a/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/cshtml.csproj b/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/cshtml.csproj index e69de29bb2d..e580f24c65d 100644 --- a/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/cshtml.csproj +++ b/csharp/ql/integration-tests/all-platforms/cshtml_standalone_flowsteps/cshtml.csproj @@ -0,0 +1,9 @@ + + + + net7.0 + enable + enable + + + \ No newline at end of file diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Razor.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Razor.qll index f7989d1a0d7..0259585ec1b 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Razor.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Razor.qll @@ -69,9 +69,11 @@ class RazorPageClass extends Class { AssemblyAttribute attr; RazorPageClass() { - this.getBaseClass() - .getUnboundDeclaration() - .hasQualifiedName("Microsoft.AspNetCore.Mvc.Razor", "RazorPage<>") and + exists(Class baseClass | baseClass = this.getBaseClass().getUnboundDeclaration() | + baseClass.hasQualifiedName("Microsoft.AspNetCore.Mvc.Razor", "RazorPage<>") + or + baseClass.hasQualifiedName("Microsoft.AspNetCore.Mvc.RazorPages", "Page") + ) and attr.getFile() = this.getFile() and attr.getType() .hasQualifiedName("Microsoft.AspNetCore.Razor.Hosting", "RazorCompiledItemAttribute")