diff --git a/java/src/security/CWE-016/SpringBootActuators.java b/java/src/security/CWE-016/SpringBootActuators.java deleted file mode 100644 index 53862055..00000000 --- a/java/src/security/CWE-016/SpringBootActuators.java +++ /dev/null @@ -1,22 +0,0 @@ -@Configuration(proxyBeanMethods = false) -public class SpringBootActuators extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - // BAD: Unauthenticated access to Spring Boot actuator endpoints is allowed - http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests((requests) -> - requests.anyRequest().permitAll()); - } -} - -@Configuration(proxyBeanMethods = false) -public class ActuatorSecurity extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - // GOOD: only users with ENDPOINT_ADMIN role are allowed to access the actuator endpoints - http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests((requests) -> - requests.anyRequest().hasRole("ENDPOINT_ADMIN")); - http.httpBasic(); - } -} \ No newline at end of file diff --git a/java/src/security/CWE-016/SpringBootActuators.qhelp b/java/src/security/CWE-016/SpringBootActuators.qhelp deleted file mode 100644 index 53ee653a..00000000 --- a/java/src/security/CWE-016/SpringBootActuators.qhelp +++ /dev/null @@ -1,39 +0,0 @@ - - - -

Spring Boot includes a number of additional features called actuators that let you monitor -and interact with your web application. Exposing unprotected actuator endpoints via JXM or HTTP -can, however, lead to information disclosure or even to remote code execution vulnerability.

-
- - -

Since actuator endpoints may contain sensitive information, careful consideration should be -given about when to expose them. You should take care to secure exposed HTTP endpoints in the same -way that you would any other sensitive URL. If Spring Security is present, endpoints are secured by -default using Spring Security’s content-negotiation strategy. If you wish to configure custom -security for HTTP endpoints, for example, only allow users with a certain role to access them, -Spring Boot provides some convenient RequestMatcher objects that can be used in -combination with Spring Security.

-
- - -

In the first example, the custom security configuration allows unauthenticated access to all -actuator endpoints. This may lead to sensitive information disclosure and should be avoided.

-

In the second example, only users with ENDPOINT_ADMIN role are allowed to access -the actuator endpoints.

- - -
- - -
  • -Spring Boot documentation: -Actuators. -
  • -
  • -Exploiting Spring Boot Actuators -
  • -
    -
    diff --git a/java/src/security/CWE-016/SpringBootActuators.ql b/java/src/security/CWE-016/SpringBootActuators.ql deleted file mode 100644 index cab31128..00000000 --- a/java/src/security/CWE-016/SpringBootActuators.ql +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @name Exposed Spring Boot actuators - * @description Exposing Spring Boot actuators may lead to internal application's information leak - * or even to remote code execution. - * @kind problem - * @problem.severity error - * @precision high - * @id githubsecuritylab/java/spring-boot-exposed-actuators - * @tags security - * external/cwe/cwe-16 - */ - -import java -import SpringBootActuators - -from PermitAllCall permitAllCall -where permitAllCall.permitsSpringBootActuators() -select permitAllCall, "Unauthenticated access to Spring Boot actuator is allowed." diff --git a/java/src/security/CWE-016/SpringBootActuators.qll b/java/src/security/CWE-016/SpringBootActuators.qll deleted file mode 100644 index 195de7a1..00000000 --- a/java/src/security/CWE-016/SpringBootActuators.qll +++ /dev/null @@ -1,155 +0,0 @@ -import java - -/** The class `org.springframework.security.config.annotation.web.builders.HttpSecurity`. */ -class TypeHttpSecurity extends Class { - TypeHttpSecurity() { - this.hasQualifiedName("org.springframework.security.config.annotation.web.builders", - "HttpSecurity") - } -} - -/** - * The class - * `org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer`. - */ -class TypeAuthorizedUrl extends Class { - TypeAuthorizedUrl() { - this.hasQualifiedName("org.springframework.security.config.annotation.web.configurers", - "ExpressionUrlAuthorizationConfigurer$AuthorizedUrl<>") - } -} - -/** - * The class `org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry`. - */ -class TypeAbstractRequestMatcherRegistry extends Class { - TypeAbstractRequestMatcherRegistry() { - this.hasQualifiedName("org.springframework.security.config.annotation.web", - "AbstractRequestMatcherRegistry>") - } -} - -/** - * The class `org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest`. - */ -class TypeEndpointRequest extends Class { - TypeEndpointRequest() { - this.hasQualifiedName("org.springframework.boot.actuate.autoconfigure.security.servlet", - "EndpointRequest") - } -} - -/** A call to `EndpointRequest.toAnyEndpoint` method. */ -class ToAnyEndpointCall extends MethodCall { - ToAnyEndpointCall() { - this.getMethod().hasName("toAnyEndpoint") and - this.getMethod().getDeclaringType() instanceof TypeEndpointRequest - } -} - -/** - * A call to `HttpSecurity.requestMatcher` method with argument `RequestMatcher.toAnyEndpoint()`. - */ -class RequestMatcherCall extends MethodCall { - RequestMatcherCall() { - this.getMethod().hasName("requestMatcher") and - this.getMethod().getDeclaringType() instanceof TypeHttpSecurity and - this.getArgument(0) instanceof ToAnyEndpointCall - } -} - -/** - * A call to `HttpSecurity.requestMatchers` method with lambda argument - * `RequestMatcher.toAnyEndpoint()`. - */ -class RequestMatchersCall extends MethodCall { - RequestMatchersCall() { - this.getMethod().hasName("requestMatchers") and - this.getMethod().getDeclaringType() instanceof TypeHttpSecurity and - this.getArgument(0).(LambdaExpr).getExprBody() instanceof ToAnyEndpointCall - } -} - -/** A call to `HttpSecurity.authorizeRequests` method. */ -class AuthorizeRequestsCall extends MethodCall { - AuthorizeRequestsCall() { - this.getMethod().hasName("authorizeRequests") and - this.getMethod().getDeclaringType() instanceof TypeHttpSecurity - } -} - -/** A call to `AuthorizedUrl.permitAll` method. */ -class PermitAllCall extends MethodCall { - PermitAllCall() { - this.getMethod().hasName("permitAll") and - this.getMethod().getDeclaringType() instanceof TypeAuthorizedUrl - } - - /** Holds if `permitAll` is called on request(s) mapped to actuator endpoint(s). */ - predicate permitsSpringBootActuators() { - exists(AuthorizeRequestsCall authorizeRequestsCall | - // .requestMatcher(EndpointRequest).authorizeRequests([...]).[...] - authorizeRequestsCall.getQualifier() instanceof RequestMatcherCall - or - // .requestMatchers(matcher -> EndpointRequest).authorizeRequests([...]).[...] - authorizeRequestsCall.getQualifier() instanceof RequestMatchersCall - | - // [...].authorizeRequests(r -> r.anyRequest().permitAll()) or - // [...].authorizeRequests(r -> r.requestMatchers(EndpointRequest).permitAll()) - authorizeRequestsCall.getArgument(0).(LambdaExpr).getExprBody() = this and - ( - this.getQualifier() instanceof AnyRequestCall or - this.getQualifier() instanceof RegistryRequestMatchersCall - ) - or - // [...].authorizeRequests().requestMatchers(EndpointRequest).permitAll() or - // [...].authorizeRequests().anyRequest().permitAll() - authorizeRequestsCall.getNumArgument() = 0 and - exists(RegistryRequestMatchersCall registryRequestMatchersCall | - registryRequestMatchersCall.getQualifier() = authorizeRequestsCall and - this.getQualifier() = registryRequestMatchersCall - ) - or - exists(AnyRequestCall anyRequestCall | - anyRequestCall.getQualifier() = authorizeRequestsCall and - this.getQualifier() = anyRequestCall - ) - ) - or - exists(AuthorizeRequestsCall authorizeRequestsCall | - // http.authorizeRequests([...]).[...] - authorizeRequestsCall.getQualifier() instanceof VarAccess - | - // [...].authorizeRequests(r -> r.requestMatchers(EndpointRequest).permitAll()) - authorizeRequestsCall.getArgument(0).(LambdaExpr).getExprBody() = this and - this.getQualifier() instanceof RegistryRequestMatchersCall - or - // [...].authorizeRequests().requestMatchers(EndpointRequest).permitAll() or - authorizeRequestsCall.getNumArgument() = 0 and - exists(RegistryRequestMatchersCall registryRequestMatchersCall | - registryRequestMatchersCall.getQualifier() = authorizeRequestsCall and - this.getQualifier() = registryRequestMatchersCall - ) - ) - } -} - -/** A call to `AbstractRequestMatcherRegistry.anyRequest` method. */ -class AnyRequestCall extends MethodCall { - AnyRequestCall() { - this.getMethod().hasName("anyRequest") and - this.getMethod().getDeclaringType() instanceof TypeAbstractRequestMatcherRegistry - } -} - -/** - * A call to `AbstractRequestMatcherRegistry.requestMatchers` method with an argument - * `RequestMatcher.toAnyEndpoint()`. - */ -class RegistryRequestMatchersCall extends MethodCall { - RegistryRequestMatchersCall() { - this.getMethod().hasName("requestMatchers") and - this.getMethod().getDeclaringType() instanceof TypeAbstractRequestMatcherRegistry and - this.getAnArgument() instanceof ToAnyEndpointCall - } -} diff --git a/java/test/security/CWE-016/SpringBootActuators.expected b/java/test/security/CWE-016/SpringBootActuators.expected deleted file mode 100644 index f2874e36..00000000 --- a/java/test/security/CWE-016/SpringBootActuators.expected +++ /dev/null @@ -1,7 +0,0 @@ -| SpringBootActuators.java:6:88:6:120 | permitAll(...) | Unauthenticated access to Spring Boot actuator is allowed. | -| SpringBootActuators.java:10:5:10:137 | permitAll(...) | Unauthenticated access to Spring Boot actuator is allowed. | -| SpringBootActuators.java:14:5:14:149 | permitAll(...) | Unauthenticated access to Spring Boot actuator is allowed. | -| SpringBootActuators.java:18:5:18:101 | permitAll(...) | Unauthenticated access to Spring Boot actuator is allowed. | -| SpringBootActuators.java:22:5:22:89 | permitAll(...) | Unauthenticated access to Spring Boot actuator is allowed. | -| SpringBootActuators.java:26:40:26:108 | permitAll(...) | Unauthenticated access to Spring Boot actuator is allowed. | -| SpringBootActuators.java:30:5:30:113 | permitAll(...) | Unauthenticated access to Spring Boot actuator is allowed. | diff --git a/java/test/security/CWE-016/SpringBootActuators.java b/java/test/security/CWE-016/SpringBootActuators.java deleted file mode 100644 index da59919f..00000000 --- a/java/test/security/CWE-016/SpringBootActuators.java +++ /dev/null @@ -1,104 +0,0 @@ -import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; - -public class SpringBootActuators { - protected void configure(HttpSecurity http) throws Exception { - http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests(requests -> requests.anyRequest().permitAll()); - } - - protected void configure2(HttpSecurity http) throws Exception { - http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll(); - } - - protected void configure3(HttpSecurity http) throws Exception { - http.requestMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll(); - } - - protected void configure4(HttpSecurity http) throws Exception { - http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests().anyRequest().permitAll(); - } - - protected void configure5(HttpSecurity http) throws Exception { - http.authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll(); - } - - protected void configure6(HttpSecurity http) throws Exception { - http.authorizeRequests(requests -> requests.requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()); - } - - protected void configure7(HttpSecurity http) throws Exception { - http.requestMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeRequests().anyRequest().permitAll(); - } - - protected void configureOk1(HttpSecurity http) throws Exception { - http.requestMatcher(EndpointRequest.toAnyEndpoint()); - } - - protected void configureOk2(HttpSecurity http) throws Exception { - http.requestMatchers().requestMatchers(EndpointRequest.toAnyEndpoint()); - } - - protected void configureOk3(HttpSecurity http) throws Exception { - http.authorizeRequests().anyRequest().permitAll(); - } - - protected void configureOk4(HttpSecurity http) throws Exception { - http.authorizeRequests(authz -> authz.anyRequest().permitAll()); - } - - protected void configureOkSafeEndpoints1(HttpSecurity http) throws Exception { - http.requestMatcher(EndpointRequest.to("health", "info")).authorizeRequests(requests -> requests.anyRequest().permitAll()); - } - - protected void configureOkSafeEndpoints2(HttpSecurity http) throws Exception { - http.requestMatcher(EndpointRequest.to("health")).authorizeRequests().requestMatchers(EndpointRequest.to("health")).permitAll(); - } - - protected void configureOkSafeEndpoints3(HttpSecurity http) throws Exception { - http.requestMatchers(matcher -> EndpointRequest.to("health", "info")).authorizeRequests().requestMatchers(EndpointRequest.to("health", "info")).permitAll(); - } - - protected void configureOkSafeEndpoints4(HttpSecurity http) throws Exception { - http.requestMatcher(EndpointRequest.to("health", "info")).authorizeRequests().anyRequest().permitAll(); - } - - protected void configureOkSafeEndpoints5(HttpSecurity http) throws Exception { - http.authorizeRequests().requestMatchers(EndpointRequest.to("health", "info")).permitAll(); - } - - protected void configureOkSafeEndpoints6(HttpSecurity http) throws Exception { - http.authorizeRequests(requests -> requests.requestMatchers(EndpointRequest.to("health", "info")).permitAll()); - } - - protected void configureOkSafeEndpoints7(HttpSecurity http) throws Exception { - http.requestMatchers(matcher -> EndpointRequest.to("health", "info")).authorizeRequests().anyRequest().permitAll(); - } - - protected void configureOkNoPermitAll1(HttpSecurity http) throws Exception { - http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests(requests -> requests.anyRequest()); - } - - protected void configureOkNoPermitAll2(HttpSecurity http) throws Exception { - http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()); - } - - protected void configureOkNoPermitAll3(HttpSecurity http) throws Exception { - http.requestMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()); - } - - protected void configureOkNoPermitAll4(HttpSecurity http) throws Exception { - http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests().anyRequest(); - } - - protected void configureOkNoPermitAll5(HttpSecurity http) throws Exception { - http.authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()); - } - - protected void configureOkNoPermitAll6(HttpSecurity http) throws Exception { - http.authorizeRequests(requests -> requests.requestMatchers(EndpointRequest.toAnyEndpoint())); - } - - protected void configureOkNoPermitAll7(HttpSecurity http) throws Exception { - http.requestMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeRequests().anyRequest(); - } -} diff --git a/java/test/security/CWE-016/SpringBootActuators.qlref b/java/test/security/CWE-016/SpringBootActuators.qlref deleted file mode 100644 index b62d155c..00000000 --- a/java/test/security/CWE-016/SpringBootActuators.qlref +++ /dev/null @@ -1 +0,0 @@ -security/CWE-016/SpringBootActuators.ql