java.lang.security.audit.permissive-cors.permissive-cors
Verifed by r2c
Community Favorite

Author
98,391
Download Count*
License
https://find-sec-bugs.github.io/bugs.htm#PERMISSIVE_CORS Permissive CORS policy will allow a malicious application to communicate with the victim application in an inappropriate way, leading to spoofing, data theft, relay and other attacks.
Run Locally
Run in CI
Defintion
rules:
- id: permissive-cors
message: https://find-sec-bugs.github.io/bugs.htm#PERMISSIVE_CORS Permissive
CORS policy will allow a malicious application to communicate with the
victim application in an inappropriate way, leading to spoofing, data
theft, relay and other attacks.
metadata:
cwe:
- "CWE-183: Permissive List of Allowed Inputs"
asvs:
section: "V14: Configuration Verification Requirements"
control_id: 14.4.8 Permissive CORS
control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x22-V14-Config.md#v144-http-security-headers-requirements
version: "4"
category: security
technology:
- java
owasp:
- A04:2021 - Insecure Design
references:
- https://owasp.org/Top10/A04_2021-Insecure_Design
subcategory:
- audit
likelihood: LOW
impact: LOW
confidence: LOW
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
severity: WARNING
languages:
- java
pattern-either:
- pattern: |
HttpServletResponse $RES = ...;
...
$RES.addHeader("=~/access-control-allow-origin/i", "=~/^\*|null$/i");
- pattern: |
HttpServletResponse $RES = ...;
...
$RES.setHeader("=~/access-control-allow-origin/i", "=~/^\*|null$/i");
- pattern: >
ServerHttpResponse $RES = ...;
...
$RES.getHeaders().add("=~/access-control-allow-origin/i", "=~/^\*|null$/i");
- pattern: |
HttpHeaders $HEADERS = ...;
...
$HEADERS.set("=~/access-control-allow-origin/i", "=~/^\*|null$/i");
- pattern: >
ServerWebExchange $SWE = ...;
...
$SWE.getResponse().getHeaders().add("Access-Control-Allow-Origin", "*");
- pattern: >
$X $METHOD(...,HttpServletResponse $RES,...) {
...
$RES.addHeader("=~/access-control-allow-origin/i", "=~/^\*|null$/i");
...
}
- pattern: >
$X $METHOD(...,HttpServletResponse $RES,...) {
...
$RES.setHeader("=~/access-control-allow-origin/i", "=~/^\*|null$/i");
...
}
- pattern: >
$X $METHOD(...,ServerHttpResponse $RES,...) {
...
$RES.getHeaders().add("=~/access-control-allow-origin/i", "=~/^\*|null$/i");
...
}
- pattern: >
$X $METHOD(...,ServerWebExchange $SWE,...) {
...
$SWE.getResponse().getHeaders().add("=~/access-control-allow-origin/i", "=~/^\*|null$/i");
...
}
- pattern: ResponseEntity.$RES().header("=~/access-control-allow-origin/i",
"=~/^\*|null$/i")
- pattern: ServerResponse.$RES().header("=~/access-control-allow-origin/i",
"=~/^\*|null$/i")
Examples
permissive-cors.java
package foolet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class SuperWebFlet
*/
@WebServlet("/SuperWebFlet")
public class SuperWebFlet extends HttpServlet {
public SuperWebFlet() {
// Auto-generated constructor stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// ruleid: permissive-cors
HttpServletResponse res = (HttpServletResponse) response;
res.addHeader("Access-Control-Allow-Origin", "*");
chain.doFilter(request, response);
}
// ruleid: permissive-cors
@GetMapping({"", "/"})
@PreAuthorize("hasPermission('User', 'read')")
public List index(HttpServletRequest request, HttpServletResponse response) {
response.addHeader("access-control-allow-origin", "*");
return page.getContent().stream().map((item) -> {
Map<String, Object> ret = new HashMap();
ret.put("createdAt", item.getCreatedAt());
return ret;
}).collect(Collectors.toList());
}
// ruleid: permissive-cors
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
response.setHeader("Access-Control-Allow-Origin", "Null");
boolean ok = "OK".equals(ibookDbStatus);
if (!ok) {
response.setStatus(500);
}
}
catch (RuntimeException | IOException e) {
logger.log(Level.SEVERE, "RQ[HEALT] -> "+e.toString(), e);
throw e;
}
}
// ruleid: permissive-cors
public void setErrorsResponse(Errors errors, HttpStatus responseHttpStatus, HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setStatus(responseHttpStatus.value());
HttpResponseData responseData = getResponseData(errors, request);
if (responseData != null) {
response.addHeader("access-control-allow-origin", "*");
response.getWriter().write(responseData.getBody());
}
}
// ruleid: permissive-cors
public static void write(HttpServletResponse response, Object o) throws Exception {
response.setContentType("text/html;charset=utf-8");
response.addHeader("Access-Control-Allow-Origin", "*.test.com");
PrintWriter out = response.getWriter();
out.println(o.toString());
out.flush();
out.close();
}
@GetMapping("/response-entity-builder-with-http-headers")
public ResponseEntity<String> usingResponseEntityBuilderAndHttpHeaders() {
// ruleid: permissive-cors
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("Access-Control-Allow-Origin", "*");
return ResponseEntity.ok()
.headers(responseHeaders)
.body("Response with header using ResponseEntity");
}
// ruleid: permissive-cors
@GetMapping("/server-http-response")
public Mono<String> usingServerHttpResponse(ServerHttpResponse response) {
response.getHeaders().add("Access-Control-Allow-Origin", "*");
return Mono.just("Response with header using ServerHttpResponse");
}
@GetMapping("/response-entity")
public Mono<ResponseEntity<String>> usingResponseEntityBuilder() {
String responseBody = "Response with header using ResponseEntity (builder)";
// ruleid: permissive-cors
return Mono.just(ResponseEntity.ok()
.header("Access-Control-Allow-Origin", "*")
.body(responseBody));
}
public Mono<ServerResponse> useHandler(final ServerRequest request) {
// ruleid: permissive-cors
return ServerResponse.ok()
.header("Access-Control-Allow-Origin", "null")
.body(Mono.just("Response with header using Handler"),String.class);
}
// ruleid: permissive-cors
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
exchange.getResponse()
.getHeaders()
.add("Access-Control-Allow-Origin", "*.some.domain");
return chain.filter(exchange);
}
// ok: permissive-cors
public void setErrorsResponse1(Errors errors, HttpStatus responseHttpStatus, HttpServletRequest request, HttpServletResponse response) throws IOException {
response.addHeader("Foo", "Bar");
response.getWriter().write(responseData.getBody());
}
// ok: permissive-cors
@GetMapping("/ok-ok")
public Mono<String> usingServerHttpResponse1(ServerHttpResponse response) {
response.getHeaders().add("Foo", "Bar");
return Mono.just("Response with header using ServerHttpResponse");
}
@GetMapping("/ok-ok-ok")
public ResponseEntity<String> usingResponseEntityBuilderAndHttpHeaders1() {
// ok: permissive-cors
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("Foo", "Bar");
return ResponseEntity.ok()
.headers(responseHeaders)
.body("Response with header using ResponseEntity");
}
}
Short Link: https://sg.run/8y77