허용적인 CORS 정책을 가지는것은 보안에 민감할 수 있습니다.

 

허용적인 CORS 정책을 갖는 것은 보안에 민감합니다. 과거에는 다음과 같은 취약점이 있었습니다.

브라우저의 동일 출처 정책 은 기본적으로, 또 보안상의 이유로 자바스크립트 프론트엔드가 출처가 다른(도메인, 프로토콜, 포트) 리소스에 대한 교차 출처 HTTP 요청을 수행하는 것을 방지합니다. 요청된 대상은 CORS 라고 불리는 추가적인 HTTP 헤더를 Response 에 추가할 수 있고, 이 헤더는 브라우저의 접근 제어 정책을 변경하거나 동일 출처 정책을 완화하는 지시어 역할을 합니다.

스스로에게 자문하세요

  • 지정된 원본을 신뢰하지 않음(예시: Access-Control-Allow-Origin: untrustedwebsite.com).
  • 접근 제어 정책이 완전히 비활성화됨: Access-Control-Allow-Origin: *
  • 접근 제어 정책이 오리진 헤더와 같은 사용자 제어 입력에 의해 동적으로 정의됨.

이러한 질문에 예라고 답하는 경우 문제가 발생할 수 있습니다.

추천되는 안전한 코딩 관습

  • Access-Control-Allow-Origin 헤더는 신뢰할 수 있는 원본 및 특정 리소스에 대해서만 설정해야 합니다.
  • Access-Control-Allow-Origin 헤더에서 선택되고 신뢰할 수 있는 도메인만 허용합니다. 블랙리스트에 추가하거나 모든 도메인을 허용하는 것보다 도메인을 화이트리스트에 추가하는 것이 선호됩니다. (* 와일드카드를 사용하거나 확인하지 않고 맹목적으로 Origin 헤더 콘텐츠를 반환하지 마십시오).

보안에 민감한 코드의 예

자바 서블릿 프레임워크 :

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.setHeader("Content-Type", "text/plain; charset=utf-8");
    resp.setHeader("Access-Control-Allow-Origin", "*"); // Sensitive
    resp.setHeader("Access-Control-Allow-Credentials", "true");
    resp.setHeader("Access-Control-Allow-Methods", "GET");
    resp.getWriter().write("response");
}

스프링 MVC 프레임워크 :

@CrossOrigin // 민감한 코드
@RequestMapping("")
public class TestController {
    public String home(ModelMap model) {
        model.addAttribute("message", "ok ");
        return "view";
    }
}
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*"); // 민감한 코드
config.applyPermitDefaultValues(); // 민감한 코드
class Insecure implements WebMvcConfigurer {
  @Override
  public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**")
      .allowedOrigins("*"); // 민감한 코드
  }
}
  • 사용자 제어 오리진 :
public ResponseEntity<String> userControlledOrigin(@RequestHeader("Origin") String origin) {
  HttpHeaders responseHeaders = new HttpHeaders();
  responseHeaders.add("Access-Control-Allow-Origin", origin); // 민감한 코드

  return new ResponseEntity<>("content", responseHeaders, HttpStatus.CREATED);
}

규칙을 준수한 해결책

자바 서블릿 프레임워크 :

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.setHeader("Content-Type", "text/plain; charset=utf-8");
    resp.setHeader("Access-Control-Allow-Origin", "trustedwebsite.com"); // 규칙을 준수한 코드
    resp.setHeader("Access-Control-Allow-Credentials", "true");
    resp.setHeader("Access-Control-Allow-Methods", "GET");
    resp.getWriter().write("response");
}

스프링 MVC 프레임워크 :

@CrossOrigin("trustedwebsite.com") // 규칙을 준수한 코드
@RequestMapping("")
public class TestController {
    public String home(ModelMap model) {
        model.addAttribute("message", "ok ");
        return "view";
    }
}

CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("http://domain2.com"); // 규칙을 준수한 코드
class Safe implements WebMvcConfigurer {
  @Override
  public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**")
      .allowedOrigins("safe.com"); // 규칙을 준수한 코드
  }
}
  • 허용된 리스트를 통해 검증된 사용자 제어 오리진 :
public ResponseEntity<String> userControlledOrigin(@RequestHeader("Origin") String origin) {
  HttpHeaders responseHeaders = new HttpHeaders();
  if (trustedOrigins.contains(origin)) {
    responseHeaders.add("Access-Control-Allow-Origin", origin);
  }

  return new ResponseEntity<>("content", responseHeaders, HttpStatus.CREATED);
}

참고


If you like SONARKUBE, don’t forget to give me a star. :star2:

원문으로 바로가기

Star This Project