From 0d2a4222fd14fd2290b462d990efa10026d7efb7 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Tue, 15 Jul 2025 21:45:50 -0400 Subject: [PATCH] Java: add related location to alert message --- .../SpringBootActuatorsConfigQuery.qll | 41 +++++++++++++++---- .../InsecureSpringActuatorConfig.ql | 8 ++-- .../InsecureSpringActuatorConfig.expected | 8 ++-- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/SpringBootActuatorsConfigQuery.qll b/java/ql/lib/semmle/code/java/security/SpringBootActuatorsConfigQuery.qll index ccae3a4f929..f8ff20f9978 100644 --- a/java/ql/lib/semmle/code/java/security/SpringBootActuatorsConfigQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SpringBootActuatorsConfigQuery.qll @@ -48,9 +48,6 @@ class ManagementSecurityConfig extends ApplicationPropertiesConfigPair { /** Holds if `management.security.enabled` is set to `false`. */ predicate hasSecurityDisabled() { this.getValue() = "false" } - - /** Holds if `management.security.enabled` is set to `true`. */ - predicate hasSecurityEnabled() { this.getValue() = "true" } } /** The configuration property `management.endpoints.web.exposure.include`. */ @@ -63,11 +60,37 @@ class ManagementEndPointInclude extends ApplicationPropertiesConfigPair { string getValue() { result = this.getValueElement().getValue().trim() } } +private newtype TOption = + TNone() or + TSome(ApplicationPropertiesConfigPair ap) + +/** + * An option type that is either a singleton `None` or a `Some` wrapping + * the `ApplicationPropertiesConfigPair` type. + */ +class ApplicationPropertiesOption extends TOption { + /** Gets a textual representation of this element. */ + string toString() { + this = TNone() and result = "(none)" + or + result = this.asSome().toString() + } + + /** Gets the location of this element. */ + Location getLocation() { result = this.asSome().getLocation() } + + /** Gets the wrapped element, if any. */ + ApplicationPropertiesConfigPair asSome() { this = TSome(result) } + + /** Holds if this option is the singleton `None`. */ + predicate isNone() { this = TNone() } +} + /** * 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) { +predicate hasConfidentialEndPointExposed(SpringBootPom pom, ApplicationPropertiesOption apOption) { pom.isSpringBootActuatorUsed() and not pom.isSpringBootSecurityUsed() and exists(ApplicationPropertiesFile apFile | @@ -79,14 +102,18 @@ predicate hasConfidentialEndPointExposed(SpringBootPom pom) { 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) + not exists(ManagementSecurityConfig me | me.getFile() = apFile) and + apOption.isNone() or - springBootVersion.matches("1.5%") and // version 1.5 - exists(ManagementSecurityConfig me | me.hasSecurityDisabled() and me.getFile() = apFile) + springBootVersion.regexpMatch("1\\.[0-5].*") and // version 1.0, 1.1, ..., 1.5 + exists(ManagementSecurityConfig me | + me.hasSecurityDisabled() and me.getFile() = apFile and me = apOption.asSome() + ) or springBootVersion.matches("2.%") and //version 2.x exists(ManagementEndPointInclude mi | mi.getFile() = apFile and + mi = apOption.asSome() and ( mi.getValue() = "*" // all endpoints are enabled or 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 89f3777f0c2..2437a77953d 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,11 @@ import java import semmle.code.xml.MavenPom import semmle.code.java.security.SpringBootActuatorsConfigQuery -from SpringBootPom pom, Dependency d +from SpringBootPom pom, Dependency d, ApplicationPropertiesOption apOption where - hasConfidentialEndPointExposed(pom) and + hasConfidentialEndPointExposed(pom, apOption) and d = pom.getADependency() and d.getArtifact().getValue() = "spring-boot-starter-actuator" -select d, "Insecure configuration of Spring Boot Actuator exposes sensitive endpoints." +select d, + "Insecure $@ of Spring Boot Actuator exposes sensitive endpoints (" + + pom.getParentElement().getVersionString() + ").", apOption, "configuration" 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 d7043f403fb..70a6068ab3f 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,4 +1,4 @@ -| 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. | +| Version1.4-/bad/default/pom.xml:29:9:32:22 | dependency | Insecure $@ of Spring Boot Actuator exposes sensitive endpoints (1.2.6.RELEASE). | file://:0:0:0:0 | (none) | configuration | +| Version1.4-/bad/false/pom.xml:29:9:32:22 | dependency | Insecure $@ of Spring Boot Actuator exposes sensitive endpoints (1.2.6.RELEASE). | Version1.4-/bad/false/application.properties:2:1:2:33 | management.security.enabled=false | configuration | +| Version1.5/bad/pom.xml:29:9:32:22 | dependency | Insecure $@ of Spring Boot Actuator exposes sensitive endpoints (1.5.6.RELEASE). | Version1.5/bad/application.properties:2:1:2:33 | management.security.enabled=false | configuration | +| Version2+/bad/pom.xml:29:9:32:22 | dependency | Insecure $@ of Spring Boot Actuator exposes sensitive endpoints (2.2.6.RELEASE). | Version2+/bad/application.properties:2:1:2:43 | management.endpoints.web.exposure.include=* | configuration |