-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Java: CWE-016 Query to detect insecure configuration of Spring Boot Actuator #5384
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
smowton
merged 5 commits into
github:main
from
luchua-bc:java/insecure-spring-actuator-config
Apr 12, 2021
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
eeac7e3
Query to detect insecure configuration of Spring Boot Actuator
luchua-bc c8b1bc3
Enhance the query
luchua-bc 1a2e341
Refactor the business logic of the query into a separate predicate
luchua-bc a72b134
Add a comment on how to run the query
luchua-bc bb23866
Add missing doc comments
smowton File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
47 changes: 47 additions & 0 deletions
47
java/ql/src/experimental/Security/CWE/CWE-016/InsecureSpringActuatorConfig.qhelp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd"> | ||
<qhelp> | ||
<overview> | ||
<p>Spring Boot is a popular framework that facilitates the development of stand-alone applications | ||
and micro services. Spring Boot Actuator helps to expose production-ready support features against | ||
Spring Boot applications.</p> | ||
|
||
<p>Endpoints of Spring Boot Actuator allow to monitor and interact with a Spring Boot application. | ||
Exposing unprotected actuator endpoints through configuration files can lead to information disclosure | ||
or even remote code execution vulnerability.</p> | ||
|
||
<p>Rather than programmatically permitting endpoint requests or enforcing access control, frequently | ||
developers simply leave management endpoints publicly accessible in the application configuration file | ||
<code>application.properties</code> without enforcing access control through Spring Security.</p> | ||
</overview> | ||
|
||
<recommendation> | ||
<p>Declare the Spring Boot Starter Security module in XML configuration or programmatically enforce | ||
security checks on management endpoints using Spring Security. Otherwise accessing management endpoints | ||
on a different HTTP port other than the port that the web application is listening on also helps to | ||
improve the security.</p> | ||
</recommendation> | ||
|
||
<example> | ||
<p>The following examples show both 'BAD' and 'GOOD' configurations. In the 'BAD' configuration, | ||
no security module is declared and sensitive management endpoints are exposed. In the 'GOOD' configuration, | ||
security is enforced and only endpoints requiring exposure are exposed.</p> | ||
<sample src="pom_good.xml" /> | ||
<sample src="pom_bad.xml" /> | ||
<sample src="application.properties" /> | ||
</example> | ||
|
||
<references> | ||
<li> | ||
Spring Boot documentation: | ||
<a href="https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html">Spring Boot Actuator: Production-ready Features</a> | ||
</li> | ||
<li> | ||
VERACODE Blog: | ||
<a href="https://www.veracode.com/blog/research/exploiting-spring-boot-actuators">Exploiting Spring Boot Actuators</a> | ||
</li> | ||
<li> | ||
HackerOne Report: | ||
<a href="https://hackerone.com/reports/862589">Spring Actuator endpoints publicly available, leading to account takeover</a> | ||
</li> | ||
</references> | ||
</qhelp> |
116 changes: 116 additions & 0 deletions
116
java/ql/src/experimental/Security/CWE/CWE-016/InsecureSpringActuatorConfig.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/** | ||
* @name Insecure Spring Boot Actuator Configuration | ||
* @description Exposed Spring Boot Actuator through configuration files without declarative or procedural | ||
* security enforcement leads to information leak or even remote code execution. | ||
* @kind problem | ||
* @id java/insecure-spring-actuator-config | ||
* @tags security | ||
* external/cwe-016 | ||
*/ | ||
|
||
/* | ||
* Note this query requires properties files to be indexed before it can produce results. | ||
* If creating your own database with the CodeQL CLI, you should run | ||
* `codeql database index-files --language=properties ...` | ||
* If using lgtm.com, you should add `properties_files: true` to the index block of your | ||
* lgtm.yml file (see https://lgtm.com/help/lgtm/java-extraction) | ||
*/ | ||
|
||
import java | ||
import semmle.code.configfiles.ConfigFiles | ||
import semmle.code.xml.MavenPom | ||
|
||
/** The parent node of the `org.springframework.boot` group. */ | ||
class SpringBootParent extends Parent { | ||
SpringBootParent() { this.getGroup().getValue() = "org.springframework.boot" } | ||
} | ||
|
||
/** Class of Spring Boot dependencies. */ | ||
class SpringBootPom extends Pom { | ||
SpringBootPom() { this.getParentElement() instanceof SpringBootParent } | ||
|
||
/** Holds if the Spring Boot Actuator module `spring-boot-starter-actuator` is used in the project. */ | ||
predicate isSpringBootActuatorUsed() { | ||
this.getADependency().getArtifact().getValue() = "spring-boot-starter-actuator" | ||
} | ||
|
||
/** | ||
* Holds if the Spring Boot Security module is used in the project, which brings in other security | ||
* related libraries. | ||
*/ | ||
predicate isSpringBootSecurityUsed() { | ||
this.getADependency().getArtifact().getValue() = "spring-boot-starter-security" | ||
} | ||
} | ||
|
||
/** The properties file `application.properties`. */ | ||
class ApplicationProperties extends ConfigPair { | ||
ApplicationProperties() { this.getFile().getBaseName() = "application.properties" } | ||
} | ||
|
||
/** The configuration property `management.security.enabled`. */ | ||
class ManagementSecurityConfig extends ApplicationProperties { | ||
ManagementSecurityConfig() { this.getNameElement().getName() = "management.security.enabled" } | ||
|
||
/** Gets the whitespace-trimmed value of this property. */ | ||
string getValue() { result = this.getValueElement().getValue().trim() } | ||
smowton marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** Holds if `management.security.enabled` is set to `false`. */ | ||
predicate hasSecurityDisabled() { getValue() = "false" } | ||
smowton marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** Holds if `management.security.enabled` is set to `true`. */ | ||
predicate hasSecurityEnabled() { getValue() = "true" } | ||
smowton marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
/** The configuration property `management.endpoints.web.exposure.include`. */ | ||
class ManagementEndPointInclude extends ApplicationProperties { | ||
ManagementEndPointInclude() { | ||
this.getNameElement().getName() = "management.endpoints.web.exposure.include" | ||
} | ||
|
||
/** Gets the whitespace-trimmed value of this property. */ | ||
string getValue() { result = this.getValueElement().getValue().trim() } | ||
smowton marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
/** | ||
* 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) { | ||
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() | | ||
luchua-bc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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 | ||
) | ||
) | ||
) | ||
} | ||
|
||
from SpringBootPom pom, ApplicationProperties ap, Dependency d | ||
where | ||
hasConfidentialEndPointExposed(pom, ap) and | ||
d = pom.getADependency() and | ||
d.getArtifact().getValue() = "spring-boot-starter-actuator" | ||
select d, "Insecure configuration of Spring Boot Actuator exposes sensitive endpoints." |
22 changes: 22 additions & 0 deletions
22
java/ql/src/experimental/Security/CWE/CWE-016/application.properties
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#management.endpoints.web.base-path=/admin | ||
|
||
|
||
#### BAD: All management endpoints are accessible #### | ||
# vulnerable configuration (spring boot 1.0 - 1.4): exposes actuators by default | ||
|
||
# vulnerable configuration (spring boot 1.5+): requires value false to expose sensitive actuators | ||
management.security.enabled=false | ||
|
||
# vulnerable configuration (spring boot 2+): exposes health and info only by default, here overridden to expose everything | ||
management.endpoints.web.exposure.include=* | ||
|
||
|
||
#### GOOD: All management endpoints have access control #### | ||
# safe configuration (spring boot 1.0 - 1.4): exposes actuators by default | ||
management.security.enabled=true | ||
|
||
# safe configuration (spring boot 1.5+): requires value false to expose sensitive actuators | ||
management.security.enabled=true | ||
|
||
# safe configuration (spring boot 2+): exposes health and info only by default, here overridden to expose one additional endpoint which we assume is intentional and safe. | ||
management.endpoints.web.exposure.include=beans,info,health |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<groupId>spring-boot-actuator-app</groupId> | ||
<artifactId>spring-boot-actuator-app</artifactId> | ||
<version>1.0-SNAPSHOT</version> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
<maven.compiler.source>1.8</maven.compiler.source> | ||
<maven.compiler.target>1.8</maven.compiler.target> | ||
</properties> | ||
|
||
<parent> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-parent</artifactId> | ||
<version>2.3.8.RELEASE</version> | ||
<relativePath/> | ||
</parent> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-web</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-actuator</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-devtools</artifactId> | ||
</dependency> | ||
|
||
<!-- BAD: No Spring Security enabled --> | ||
<!-- dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-security</artifactId> | ||
</dependency --> | ||
|
||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-test</artifactId> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
50 changes: 50 additions & 0 deletions
50
java/ql/src/experimental/Security/CWE/CWE-016/pom_good.xml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<groupId>spring-boot-actuator-app</groupId> | ||
<artifactId>spring-boot-actuator-app</artifactId> | ||
<version>1.0-SNAPSHOT</version> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
<maven.compiler.source>1.8</maven.compiler.source> | ||
<maven.compiler.target>1.8</maven.compiler.target> | ||
</properties> | ||
|
||
<parent> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-parent</artifactId> | ||
<version>2.3.8.RELEASE</version> | ||
<relativePath/> | ||
</parent> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-web</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-actuator</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-devtools</artifactId> | ||
</dependency> | ||
|
||
<!-- GOOD: Enable Spring Security --> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-security</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-test</artifactId> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
1 change: 1 addition & 0 deletions
1
java/ql/test/experimental/query-tests/security/CWE-016/InsecureSpringActuatorConfig.expected
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
| pom.xml:29:9:32:22 | dependency | Insecure configuration of Spring Boot Actuator exposes sensitive endpoints. | |
1 change: 1 addition & 0 deletions
1
java/ql/test/experimental/query-tests/security/CWE-016/InsecureSpringActuatorConfig.qlref
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
experimental/Security/CWE/CWE-016/InsecureSpringActuatorConfig.ql |
13 changes: 13 additions & 0 deletions
13
java/ql/test/experimental/query-tests/security/CWE-016/SensitiveInfo.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
|
||
@Controller | ||
public class SensitiveInfo { | ||
@RequestMapping | ||
public void handleLogin(@RequestParam String username, @RequestParam String password) throws Exception { | ||
if (!username.equals("") && password.equals("")) { | ||
//Blank processing | ||
} | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
java/ql/test/experimental/query-tests/security/CWE-016/application.properties
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#management.endpoints.web.base-path=/admin | ||
|
||
# vulnerable configuration (spring boot 1.0 - 1.4): exposes actuators by default | ||
|
||
# vulnerable configuration (spring boot 1.5+): requires value false to expose sensitive actuators | ||
management.security.enabled=false | ||
|
||
# vulnerable configuration (spring boot 2+): exposes health and info only by default, here overridden to expose everything | ||
management.endpoints.web.exposure.include=* | ||
management.endpoints.web.exposure.exclude=beans | ||
|
||
management.endpoint.shutdown.enabled=true | ||
|
||
management.endpoint.health.show-details=when_authorized |
47 changes: 47 additions & 0 deletions
47
java/ql/test/experimental/query-tests/security/CWE-016/pom.xml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<groupId>spring-boot-actuator-app</groupId> | ||
<artifactId>spring-boot-actuator-app</artifactId> | ||
<version>1.0-SNAPSHOT</version> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
<maven.compiler.source>1.8</maven.compiler.source> | ||
<maven.compiler.target>1.8</maven.compiler.target> | ||
</properties> | ||
|
||
<parent> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-parent</artifactId> | ||
<version>2.3.8.RELEASE</version> | ||
<relativePath/> | ||
</parent> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-web</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-actuator</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-devtools</artifactId> | ||
</dependency> | ||
<!-- dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-security</artifactId> | ||
</dependency --> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-test</artifactId> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.