diff --git a/csharp/ql/lib/semmle/code/asp/WebConfig.qll b/csharp/ql/lib/semmle/code/asp/WebConfig.qll index 34fa9cf3972..49e42fce5c1 100644 --- a/csharp/ql/lib/semmle/code/asp/WebConfig.qll +++ b/csharp/ql/lib/semmle/code/asp/WebConfig.qll @@ -11,6 +11,13 @@ class WebConfigXml extends XmlFile { WebConfigXml() { this.getName().matches("%Web.config") } } +/** + * A `Web.config` transformation file. + */ +class WebConfigReleaseTransformXml extends XmlFile { + WebConfigReleaseTransformXml() { this.getName().matches("%Web.Release.config") } +} + /** DEPRECATED: Alias for WebConfigXml */ deprecated class WebConfigXML = WebConfigXml; @@ -19,6 +26,11 @@ class ConfigurationXmlElement extends XmlElement { ConfigurationXmlElement() { this.getName().toLowerCase() = "configuration" } } +/** A `` tag in an ASP.NET configuration file. */ +class CompilationXmlElement extends XmlElement { + CompilationXmlElement() { this.getName().toLowerCase() = "compilation" } +} + /** DEPRECATED: Alias for ConfigurationXmlElement */ deprecated class ConfigurationXMLElement = ConfigurationXmlElement; @@ -149,3 +161,15 @@ class HttpCookiesElement extends XmlElement { /** DEPRECATED: Alias for isRequireSsl */ deprecated predicate isRequireSSL() { this.isRequireSsl() } } + +/** A `Transform` attribute in a Web.config transformation file. */ +class TransformXmlAttribute extends XmlAttribute { + TransformXmlAttribute() { this.getName().toLowerCase() = "transform" } + + /** + * Gets the list of attribute removals in `Transform=RemoveAttributes(list)`. + */ + string getRemoveAttributes() { + result = this.getValue().regexpCapture("RemoveAttributes\\((.*)\\)", 1).splitAt(",") + } +} diff --git a/csharp/ql/src/Security Features/CWE-011/ASPNetDebug.ql b/csharp/ql/src/Security Features/CWE-011/ASPNetDebug.ql index 1180d4990f8..308f3eeeac2 100644 --- a/csharp/ql/src/Security Features/CWE-011/ASPNetDebug.ql +++ b/csharp/ql/src/Security Features/CWE-011/ASPNetDebug.ql @@ -19,6 +19,17 @@ import semmle.code.asp.WebConfig from SystemWebXmlElement web, XmlAttribute debugAttribute where - debugAttribute = web.getAChild("compilation").getAttribute("debug") and - not debugAttribute.getValue().toLowerCase() = "false" + exists(CompilationXmlElement compilation | compilation.getParent() = web | + debugAttribute = compilation.getAttribute("debug") and + not debugAttribute.getValue().toLowerCase() = "false" + ) and + not exists( + TransformXmlAttribute attribute, CompilationXmlElement compilation, + WebConfigReleaseTransformXml file + | + compilation = attribute.getElement() and + file = compilation.getFile() and + attribute.getRemoveAttributes() = "debug" and + file.getParentContainer() = web.getFile().getParentContainer() + ) select debugAttribute, "The 'debug' flag is set for an ASP.NET configuration file."