반응형
1. 개요
- CORS는 Cross-Origin Resource Sharing(CORS) 의 약자이다.
- 웹 페이지가 웹 페이지를 제공한 도메인이 아닌 다른 도메인에 AJAX 요청을 할 수 있도록 하는 메커니즘입니다.
- CORS를 사용하면 브라우저는 요청 웹 페이지의 도메인을 식별하는 "Origin" 헤더와 함께 HTTP 요청을 보냅니다. 그런 다음 서버는 요청된 리소스에 액세스할 수 있는 도메인을 지정하는 "Access-Control-Allow-Origin" 헤더로 응답할 수 있습니다.
- CORS는 악의적인 공격으로부터 보호하면서 도메인 간 통신을 가능하게 하는 웹 개발의 중요한 보안 기능입니다.
2. [Nginx]
- Access-Control-Allow-Origin : 교차 출처 요청을 할 수 있는 도메인을 지정합니다.
- Access-Control-Allow-Methods : 요청에 허용되는 HTTP 메서드
- Access-Control-Max-Age : 실행 전 요청을 캐시할 수 있는 최대 시간(초)을 지정
- Access-Control-Expose-Headers : 원본 간 요청에서 클라이언트가 액세스할 수 있는 응답 헤더를 지정
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'PUT') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'DELETE') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
}
3. [Apache2]
- Access-Control-Allow-Methods : 허용된 HTTP 메서드를 나열합니다.
- Access-Control-Allow-Headers : 허용된 HTTP 요청 헤더를 설정합니다.
- Access-Control-Max-Age : 사전 검사 요청(preflight request)에 대한 캐시 시간을 설정합니다.
- Apache2에서 CORS(Cross-Origin Resource Sharing)를 처리하려면, mod_headers 모듈을 활성화하고 필요한 HTTP 응답 헤더를 설정해야 합니다.
#mod_headers 모듈 활성화
$ sudo a2enmod headers
- HTTP 응답 헤더 설정
- httpd.conf 파일의 <Directory>, <Location>, <Files>, <VirtualHost> 등에 적용한다.
# httpd.conf
<Directory /var/www/html>
...
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header set Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range"
Header set Access-Control-Max-Age "1728000"
...
</Directory>
# .htaccess 파일에설정
...
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header set Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range"
Header set Access-Control-Max-Age "1728000"
...
- 재기동
$ sudo service apache2 restart
4. [Nest.js or Node.js]
- 프로젝트 main.ts파일에서 enableCors 기능을 사용한다.
# main.ts
app.enableCors({
origin: '*',
methods: 'GET,PUT,PATCH,POST,DELETE,OPTIONS',
credentials: true,
allowedHeaders:
'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept, Observe, X-CSRF-TOKEN',
optionsSuccessStatus: 200,
});
5. [Spring-Boot]
- 시작점 Application.java 파일에 생성한다.
@SpringBootApplication
public class RestapiApplication extends WebMvcConfigurationSupport {
public static void main(String[] args) {
SpringApplication.run(RestapiApplication.class, args);
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET","POST","PUT","DELETE")
.allowedHeaders("Content-Type","X-Requested-With","accept","Origin","Access-Control-Request-Method","Access-Control-Request-Headers")
.exposedHeaders("Access-Control-Allow-Origin","Access-Control-Allow-Credentials")
.allowCredentials(true).maxAge(10);
}
}
6. [전자정부프레임워크]
- CorsFilter.java파일을 생성하고 xml이나 java파일에 필터를 등록하자.
// egovframework.com.cmm.config.EgovWebApplicationInitializer.java (아래내용추가)
FilterRegistration.Dynamic corsFilter = servletContext.addFilter("corsFilter", new CorsFilter());
corsFilter.addMappingForUrlPatterns(null, false, "/*");
// CorsFilter.java 생성
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CorsFilter implements Filter {
@SuppressWarnings("unused")
private FilterConfig config;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
res.setHeader("Access-Control-Max-Age", "3600");
res.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers");
chain.doFilter(req, res);
}
public void init(FilterConfig config) throws ServletException {
this.config = config;
}
public void destroy() {
}
}
7. [Apache-Tomcat8]
- tomcat/web.xml 파일에 필터추가
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,PUT,DELETE,OPTIONS</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>1800</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- catalina.properties 파일 수정
tomcat.util.http.parser.HttpParser.requestTargetAllow=|
반응형
'IT정보 > 보안' 카테고리의 다른 글
[Nginx] X-Frame-Options 웹취약점 예제, 명령어 (gs인증) (0) | 2023.08.08 |
---|---|
[보안] SameSite Cookie 적용 여러가지방법 (GS인증 보안성) (0) | 2023.04.19 |