diff --git a/java/ql/lib/semmle/code/java/security/SpringBootActuatorsConfigQuery.qll b/java/ql/lib/semmle/code/java/security/SpringBootActuatorsConfigQuery.qll index 5cf54f3436c..241b64821e8 100644 --- a/java/ql/lib/semmle/code/java/security/SpringBootActuatorsConfigQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SpringBootActuatorsConfigQuery.qll @@ -28,12 +28,17 @@ class SpringBootPom extends Pom { } /** The properties file `application.properties`. */ -class ApplicationProperties extends ConfigPair { - ApplicationProperties() { this.getFile().getBaseName() = "application.properties" } +class ApplicationPropertiesFile extends File { + ApplicationPropertiesFile() { this.getBaseName() = "application.properties" } +} + +/** A name-value pair stored in an `application.properties` file. */ +class ApplicationPropertiesConfigPair extends ConfigPair { + ApplicationPropertiesConfigPair() { this.getFile() instanceof ApplicationPropertiesFile } } /** The configuration property `management.security.enabled`. */ -class ManagementSecurityConfig extends ApplicationProperties { +class ManagementSecurityConfig extends ApplicationPropertiesConfigPair { ManagementSecurityConfig() { this.getNameElement().getName() = "management.security.enabled" } /** Gets the whitespace-trimmed value of this property. */ @@ -47,7 +52,7 @@ class ManagementSecurityConfig extends ApplicationProperties { } /** The configuration property `management.endpoints.web.exposure.include`. */ -class ManagementEndPointInclude extends ApplicationProperties { +class ManagementEndPointInclude extends ApplicationPropertiesConfigPair { ManagementEndPointInclude() { this.getNameElement().getName() = "management.endpoints.web.exposure.include" } @@ -60,33 +65,35 @@ class ManagementEndPointInclude extends ApplicationProperties { * Holds if `ApplicationProperties` ap of a repository managed by `SpringBootPom` pom * has a vulnerable configuration of Spring Boot Actuator management endpoints. */ -predicate hasConfidentialEndPointExposed(SpringBootPom pom, ApplicationProperties ap) { +predicate hasConfidentialEndPointExposed(SpringBootPom pom) { pom.isSpringBootActuatorUsed() and not pom.isSpringBootSecurityUsed() and - ap.getFile() - .getParentContainer() - .getAbsolutePath() - .matches(pom.getFile().getParentContainer().getAbsolutePath() + "%") and // in the same sub-directory - exists(string springBootVersion | springBootVersion = pom.getParentElement().getVersionString() | - springBootVersion.regexpMatch("1\\.[0-4].*") and // version 1.0, 1.1, ..., 1.4 - not exists(ManagementSecurityConfig me | - me.hasSecurityEnabled() and me.getFile() = ap.getFile() - ) - or - springBootVersion.matches("1.5%") and // version 1.5 - exists(ManagementSecurityConfig me | me.hasSecurityDisabled() and me.getFile() = ap.getFile()) - or - springBootVersion.matches("2.%") and //version 2.x - exists(ManagementEndPointInclude mi | - mi.getFile() = ap.getFile() and - ( - mi.getValue() = "*" // all endpoints are enabled - or - mi.getValue() - .matches([ - "%dump%", "%trace%", "%logfile%", "%shutdown%", "%startup%", "%mappings%", "%env%", - "%beans%", "%sessions%" - ]) // confidential endpoints to check although all endpoints apart from '/health' and '/info' are considered sensitive by Spring + exists(ApplicationPropertiesFile apFile | + apFile + .getParentContainer() + .getAbsolutePath() + .matches(pom.getFile().getParentContainer().getAbsolutePath() + "%") and // in the same sub-directory + exists(string springBootVersion | + springBootVersion = pom.getParentElement().getVersionString() + | + springBootVersion.regexpMatch("1\\.[0-4].*") and // version 1.0, 1.1, ..., 1.4 + not exists(ManagementSecurityConfig me | me.hasSecurityEnabled() and me.getFile() = apFile) + or + springBootVersion.matches("1.5%") and // version 1.5 + exists(ManagementSecurityConfig me | me.hasSecurityDisabled() and me.getFile() = apFile) + or + springBootVersion.matches("2.%") and //version 2.x + exists(ManagementEndPointInclude mi | + mi.getFile() = apFile and + ( + mi.getValue() = "*" // all endpoints are enabled + or + mi.getValue() + .matches([ + "%dump%", "%trace%", "%logfile%", "%shutdown%", "%startup%", "%mappings%", + "%env%", "%beans%", "%sessions%" + ]) // confidential endpoints to check although all endpoints apart from '/health' and '/info' are considered sensitive by Spring + ) ) ) ) diff --git a/java/ql/src/Security/CWE/CWE-200/InsecureSpringActuatorConfig/InsecureSpringActuatorConfig.ql b/java/ql/src/Security/CWE/CWE-200/InsecureSpringActuatorConfig/InsecureSpringActuatorConfig.ql index 66d9a52c2cf..89f3777f0c2 100644 --- a/java/ql/src/Security/CWE/CWE-200/InsecureSpringActuatorConfig/InsecureSpringActuatorConfig.ql +++ b/java/ql/src/Security/CWE/CWE-200/InsecureSpringActuatorConfig/InsecureSpringActuatorConfig.ql @@ -15,9 +15,9 @@ import java import semmle.code.xml.MavenPom import semmle.code.java.security.SpringBootActuatorsConfigQuery -from SpringBootPom pom, ApplicationProperties ap, Dependency d +from SpringBootPom pom, Dependency d where - hasConfidentialEndPointExposed(pom, ap) and + hasConfidentialEndPointExposed(pom) and d = pom.getADependency() and d.getArtifact().getValue() = "spring-boot-starter-actuator" select d, "Insecure configuration of Spring Boot Actuator exposes sensitive endpoints." diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/InsecureSpringActuatorConfig/InsecureSpringActuatorConfig.expected b/java/ql/test/query-tests/security/CWE-200/semmle/tests/InsecureSpringActuatorConfig/InsecureSpringActuatorConfig.expected index da7a570f982..d7043f403fb 100644 --- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/InsecureSpringActuatorConfig/InsecureSpringActuatorConfig.expected +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/InsecureSpringActuatorConfig/InsecureSpringActuatorConfig.expected @@ -1,6 +1,4 @@ -#select +| Version1.4-/bad/default/pom.xml:29:9:32:22 | dependency | Insecure configuration of Spring Boot Actuator exposes sensitive endpoints. | | Version1.4-/bad/false/pom.xml:29:9:32:22 | dependency | Insecure configuration of Spring Boot Actuator exposes sensitive endpoints. | | Version1.5/bad/pom.xml:29:9:32:22 | dependency | Insecure configuration of Spring Boot Actuator exposes sensitive endpoints. | | Version2+/bad/pom.xml:29:9:32:22 | dependency | Insecure configuration of Spring Boot Actuator exposes sensitive endpoints. | -testFailures -| Version1.4-/bad/default/pom.xml:32:23:32:39 | $ Alert | Missing result: Alert |