Skip to content

Commit c31fb17

Browse files
Jami CogswellJami Cogswell
authored andcommitted
Java: minor refactoring
1 parent fcbcc2d commit c31fb17

File tree

3 files changed

+44
-47
lines changed

3 files changed

+44
-47
lines changed

java/ql/lib/semmle/code/configfiles/ConfigFiles.qll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,12 @@ class ConfigValue extends @configValue, ConfigLocatable {
7070
override string toString() { result = this.getValue() }
7171
}
7272

73+
/** A `.properties` file. */
74+
class PropertiesFile extends File {
75+
PropertiesFile() { this.getExtension() = "properties" }
76+
}
77+
7378
/** A Java property is a name-value pair in a `.properties` file. */
7479
class JavaProperty extends ConfigPair {
75-
JavaProperty() { this.getFile().getExtension() = "properties" }
80+
JavaProperty() { this.getFile() instanceof PropertiesFile }
7681
}

java/ql/lib/semmle/code/java/security/SpringBootActuatorsConfigQuery.qll

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,30 @@ private import semmle.code.configfiles.ConfigFiles
77
private import semmle.code.xml.MavenPom
88

99
/** The parent node of the `org.springframework.boot` group. */
10-
class SpringBootParent extends Parent {
10+
private class SpringBootParent extends Parent {
1111
SpringBootParent() { this.getGroup().getValue() = "org.springframework.boot" }
1212
}
1313

14-
/** Class of Spring Boot dependencies. */
14+
// TODO: private once done with version string debugging in alert msg.
15+
/** A `Pom` with a Spring Boot parent node. */
1516
class SpringBootPom extends Pom {
1617
SpringBootPom() { this.getParentElement() instanceof SpringBootParent }
1718

18-
/** Holds if the Spring Boot Actuator module `spring-boot-starter-actuator` is used in the project. */
19-
predicate isSpringBootActuatorUsed() {
20-
this.getADependency().getArtifact().getValue() = "spring-boot-starter-actuator"
21-
}
22-
23-
/**
24-
* Holds if the Spring Boot Security module is used in the project, which brings in other security
25-
* related libraries.
26-
*/
19+
/** Holds if the Spring Boot Security module is used in the project. */
2720
predicate isSpringBootSecurityUsed() {
2821
this.getADependency().getArtifact().getValue() = "spring-boot-starter-security"
2922
}
3023
}
3124

32-
/** The properties file `application.properties`. */
33-
class ApplicationPropertiesFile extends File {
34-
ApplicationPropertiesFile() { this.getBaseName() = "application.properties" }
35-
}
36-
37-
/** A name-value pair stored in an `application.properties` file. */
38-
class ApplicationPropertiesConfigPair extends ConfigPair {
39-
ApplicationPropertiesConfigPair() { this.getFile() instanceof ApplicationPropertiesFile }
25+
/** A dependency with artifactId `spring-boot-starter-actuator`. */
26+
class SpringBootStarterActuatorDependency extends Dependency {
27+
SpringBootStarterActuatorDependency() {
28+
this.getArtifact().getValue() = "spring-boot-starter-actuator"
29+
}
4030
}
4131

42-
/** The configuration property `management.security.enabled`. */
43-
class ManagementSecurityConfig extends ApplicationPropertiesConfigPair {
32+
/** The Spring Boot configuration property `management.security.enabled`. */
33+
private class ManagementSecurityConfig extends JavaProperty {
4434
ManagementSecurityConfig() { this.getNameElement().getName() = "management.security.enabled" }
4535

4636
/** Gets the whitespace-trimmed value of this property. */
@@ -50,8 +40,8 @@ class ManagementSecurityConfig extends ApplicationPropertiesConfigPair {
5040
predicate hasSecurityDisabled() { this.getValue() = "false" }
5141
}
5242

53-
/** The configuration property `management.endpoints.web.exposure.include`. */
54-
class ManagementEndPointInclude extends ApplicationPropertiesConfigPair {
43+
/** The Spring Boot configuration property `management.endpoints.web.exposure.include`. */
44+
private class ManagementEndPointInclude extends JavaProperty {
5545
ManagementEndPointInclude() {
5646
this.getNameElement().getName() = "management.endpoints.web.exposure.include"
5747
}
@@ -62,13 +52,13 @@ class ManagementEndPointInclude extends ApplicationPropertiesConfigPair {
6252

6353
private newtype TOption =
6454
TNone() or
65-
TSome(ApplicationPropertiesConfigPair ap)
55+
TSome(JavaProperty jp)
6656

6757
/**
6858
* An option type that is either a singleton `None` or a `Some` wrapping
69-
* the `ApplicationPropertiesConfigPair` type.
59+
* the `JavaProperty` type.
7060
*/
71-
class ApplicationPropertiesOption extends TOption {
61+
class JavaPropertyOption extends TOption {
7262
/** Gets a textual representation of this element. */
7363
string toString() {
7464
this = TNone() and result = "(none)"
@@ -80,48 +70,50 @@ class ApplicationPropertiesOption extends TOption {
8070
Location getLocation() { result = this.asSome().getLocation() }
8171

8272
/** Gets the wrapped element, if any. */
83-
ApplicationPropertiesConfigPair asSome() { this = TSome(result) }
73+
JavaProperty asSome() { this = TSome(result) }
8474

8575
/** Holds if this option is the singleton `None`. */
8676
predicate isNone() { this = TNone() }
8777
}
8878

8979
/**
90-
* Holds if `ApplicationProperties` ap of a repository managed by `SpringBootPom` pom
91-
* has a vulnerable configuration of Spring Boot Actuator management endpoints.
80+
* Holds if `JavaPropertyOption` jpOption of a repository using `SpringBootStarterActuatorDependency`
81+
* d exposes sensitive Spring Boot Actuator endpoints.
9282
*/
93-
predicate hasConfidentialEndPointExposed(SpringBootPom pom, ApplicationPropertiesOption apOption) {
94-
pom.isSpringBootActuatorUsed() and
95-
not pom.isSpringBootSecurityUsed() and
96-
exists(ApplicationPropertiesFile apFile |
97-
apFile
83+
predicate exposesSensitiveEndPoint(
84+
SpringBootStarterActuatorDependency d, JavaPropertyOption jpOption
85+
) {
86+
exists(PropertiesFile propFile, SpringBootPom pom |
87+
d = pom.getADependency() and
88+
not pom.isSpringBootSecurityUsed() and
89+
propFile
9890
.getParentContainer()
9991
.getAbsolutePath()
10092
.matches(pom.getFile().getParentContainer().getAbsolutePath() + "%") and // in the same sub-directory
10193
exists(string springBootVersion |
10294
springBootVersion = pom.getParentElement().getVersionString()
10395
|
10496
springBootVersion.regexpMatch("1\\.[0-4].*") and // version 1.0, 1.1, ..., 1.4
105-
not exists(ManagementSecurityConfig me | me.getFile() = apFile) and
106-
apOption.isNone()
97+
not exists(ManagementSecurityConfig me | me.getFile() = propFile) and
98+
jpOption.isNone()
10799
or
108100
springBootVersion.regexpMatch("1\\.[0-5].*") and // version 1.0, 1.1, ..., 1.5
109101
exists(ManagementSecurityConfig me |
110-
me.hasSecurityDisabled() and me.getFile() = apFile and me = apOption.asSome()
102+
me.hasSecurityDisabled() and me.getFile() = propFile and me = jpOption.asSome()
111103
)
112104
or
113105
springBootVersion.matches(["2.%", "3.%"]) and //version 2.x and 3.x
114106
exists(ManagementEndPointInclude mi |
115-
mi.getFile() = apFile and
116-
mi = apOption.asSome() and
107+
mi.getFile() = propFile and
108+
mi = jpOption.asSome() and
117109
(
118-
mi.getValue() = "*" // all endpoints are enabled
110+
mi.getValue() = "*" // all endpoints are exposed
119111
or
120112
mi.getValue()
121113
.matches([
122114
"%dump%", "%trace%", "%logfile%", "%shutdown%", "%startup%", "%mappings%",
123115
"%env%", "%beans%", "%sessions%"
124-
]) // confidential endpoints to check although all endpoints apart from '/health' are considered sensitive by Spring
116+
]) // sensitive endpoints to check although all endpoints apart from '/health' are considered sensitive by Spring
125117
)
126118
)
127119
)

java/ql/src/Security/CWE/CWE-200/InsecureSpringActuatorConfig/InsecureSpringActuatorConfig.ql

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ import java
1515
import semmle.code.xml.MavenPom
1616
import semmle.code.java.security.SpringBootActuatorsConfigQuery
1717

18-
from SpringBootPom pom, Dependency d, ApplicationPropertiesOption apOption
18+
from SpringBootStarterActuatorDependency d, JavaPropertyOption jpOption, SpringBootPom pom
1919
where
20-
hasConfidentialEndPointExposed(pom, apOption) and
21-
d = pom.getADependency() and
22-
d.getArtifact().getValue() = "spring-boot-starter-actuator"
20+
exposesSensitiveEndPoint(d, jpOption) and
21+
// TODO: remove pom; for debugging versions
22+
d = pom.getADependency()
2323
select d,
2424
"Insecure $@ of Spring Boot Actuator exposes sensitive endpoints (" +
25-
pom.getParentElement().getVersionString() + ").", apOption, "configuration"
25+
pom.getParentElement().getVersionString() + ").", jpOption, "configuration"

0 commit comments

Comments
 (0)