본문 바로가기
IT정보/보안

[보안] CORS 처리활성화 여러가지방법(GS인증 보안성)

by 아크투어 2023. 4. 20.
반응형

1. 개요

  • CORS는 Cross-Origin Resource Sharing(CORS) 의 약자이다.
  • 웹 페이지가 웹 페이지를 제공한 도메인이 아닌 다른 도메인에 AJAX 요청을 할 수 있도록 하는 메커니즘입니다.
  • CORS를 사용하면 브라우저는 요청 웹 페이지의 도메인을 식별하는 "Origin" 헤더와 함께 HTTP 요청을 보냅니다. 그런 다음 서버는 요청된 리소스에 액세스할 수 있는 도메인을 지정하는 "Access-Control-Allow-Origin" 헤더로 응답할 수 있습니다.
  • CORS는 악의적인 공격으로부터 보호하면서 도메인 간 통신을 가능하게 하는 웹 개발의 중요한 보안 기능입니다.

cors browser

 

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=|
반응형