Please Enable JavaScript!
Mohon Aktifkan Javascript![ Enable JavaScript ]

[SPRING BOOT] AJP CONNECTOR CVE-2020-1938 (2.2.5.RELEASE)

2020. 12. 10. 09:37programming/spring-boot

728x90

The Tomcat connector configured to listen on port 8001 failed to start. The port may already be in use or the connector may be misconfigured.

위와 같은 오류가 발생하는 이유는 포트가 겹치거나 커넥터 설정이 부족하기 때문에 나오는 오류입니다.

 

spring-boot-starter-parent 버전 2.2.5.RELEASE를 사용할 경우 AJP Connector를 사용하려고 할때 위와 같은 오류메시지가 나올 수 있습니다.

Ghostcat : Tomcat-Ajp 프로토콜 취약점 (cve-2020-1938) 주의!

Apache Tomcat 의 기본보트 8009로 활성화되는 AJP 커넥터에 있는 파일 읽기 취약성이 있습니다. 인증되지 않은 원격 공격자는 이 취약성을 이용하여 취약한 서버에서 웹 응용프로그램 파일(이하 webapp 목록 하위의 있는 모든 임의의 파일)을 읽을 수 있습니다. 취약한 서버에서 파일 업로드를 허용하는 경우, 공격자는 다양한 파일 형식 내에서 악의적인 JSP 파일을 업로드하여 원격코드실행도 가능하다고 합니다.

Tomcat은 기본적으로 2개의 connector가 설정되어 있습니다.
외부로 HTTP 프로토콜을 전송하는 8080포트와 AJP 프로토콜의 8009, 이 두 포트는 디폴트로 외부망 IP를 수신합니다.

Tomcat이 AJP Request를 받았을 경우 아무런 검증을 수행하지 않기 때문에 AJP Connector에 request 객체의 Attribute 속성으로 설정하면서 문제가 발생하였습니다.

request 객체 설정하는 속성은 아래와 같습니다.

  • javax.servlet.include.request_uri
  • javax.servlet.include.path_info
  • javax.servlet.include.servlet_path

 

이에 따라 보안 강화된 톰캣 버전으로 업그레이드 할 것을 강력히 권장합니다.

AJP 커넥터가 기본적으로 활성화 되어 있기 때문에

 


만약 AJP를 사용하고 있지 않다면 주석처리를 하는게 좋습니다.

하지만 AJP Connector를 사용하는 경우 AJP Connector에 암호와 유사한 필수 Secret 속성이 포함되어 있는지 확인해야 하고 강력한 암호를 사용할 것을 권장합니다.

네트워크가 신뢰할 수 있는 상태에서만 속성 값을 false로 해야 합니다.

 

package com.forge.oauth;
 
import org.apache.catalina.connector.Connector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.ApplicationPidFileWriter;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
 
/**
 * @author 박준영
 */
 
@SpringBootApplication
@ConfigurationPropertiesScan
public class WebApplication extends SpringBootServletInitializer {
    @Value(“${server.http.port}”)
    private int HTTP_PORT;
 
    @Value(“${server.ajp.port}”)
    private int AJP_PORT;
 
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(WebApplication.class);
    }
 
    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(WebApplication.class);
        springApplication.addListeners(new ApplicationPidFileWriter(“../pid/application.pid”));
        springApplication.run(args).registerShutdownHook();
    }
 
    @Bean
    public ServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        factory.setPort(HTTP_PORT);
        Connector ajpConnector = new Connector(“AJP/1.3”);
        ajpConnector.setPort(AJP_PORT);
        ((AbstractAjpProtocol<?>) ajpConnector.getProtocolHandler()).setSecretRequired(false);
        ajpConnector.setParseBodyMethods(“POST,PUT,DELETE”);
        factory.addAdditionalTomcatConnectors(ajpConnector);
        factory.addConnectorCustomizers(connector –> connector.setParseBodyMethods(“POST,PUT,DELETE”));
 
        return factory;
    }
 
}
 
728x90

'programming > spring-boot' 카테고리의 다른 글

Spring boot ajax 를 이용하여 리스트 VO 받기  (0) 2021.07.15
Spring boot Version upgrade!  (0) 2021.01.26