XSS(Cross-Site Scripting)

·2024년 7월 19일

Web

목록 보기
3/6
post-thumbnail

XSS(Cross-Site Scripting) 공격은 신뢰할 수 있는 웹사이트에 악성 스크립트를 주입하는 유형의 공격이다.

공격자는 웹 애플리케이션을 이용해서 악성 코드를 다른 사용자의 브라우저로 보내고, 브라우저는 이를 신뢰할 수 있는 소스로 간주하고 실행한다.

쿠키, 세션 토큰 등 민감한 정보에 접근할 수 있다.

XSS 공격 유형

XSS 공격은 크게 두 가지로 나뉜다. 반사형 XSS(Reflected XSS), 저장형 XSS(Stored XSS)가 있다.

반사형 XSS(Reflected XSS)는 악성 스크립트가 서버로부터 반사되어 사용자의 브라우저로 전달된다. 보통 이메일 링크나 악성 웹사이트로 유도된다. 반사라는 것은 데이터가 서버에 저장되지 않고 즉시 응답에 포함되어 브라우저로 전달되는 것을 말한다.

저장형 XSS(Stored XSS)는 악성 스크립트가 서버에 저장된 후, 다른 사용자가 스크립트를 실행하게 된다. 주로 DB나 게시판 등을 통해 발생한다.

XSS 공격 방어 방법

Spring Security는 기본적으로 X-XSS-Protection 헤더를 설정하여 브라우저의 XSS Auditor를 비활성화한다. 비활성화하는 이유는 일부 브라우저는 XSS 보호 기능을 사용할 때 정상적인 콘텐츠를 오탐지하여 차단할 수 있다. 이런 오탐지는 사용자 경험을 저해할 수 있고, 더 강력하고 신뢰할 수 있는 Content Security Policy(CSP)를 사용할 것을 권장한다.

  • 헤더 비활성화 (기본)
    @Bean
    SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http
            // ...
            .headers(headers -> headers
                .xssProtection(xssProtection -> xssProtection.disable())
            );
        return http.build();
    }
  • 헤더 값 설정 X-XSS-Protection 헤더 값을 명시적으로 설정하여 브라우저의 XSS 필터링 동작을 제어할 수 있다.
    @Bean
    SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http
            // ...
            .headers(headers -> headers
                .xssProtection(xssProtection -> xssProtection.headerValue(XXssProtectionServerHttpHeadersWriter.HeaderValue.ENABLED_MODE_BLOCK))
            );
        return http.build();
    }

그렇다면 위에서 언급한 Content Security Policy(CSP)에 대해 알아보자. CSP는 웹 애플리케이션 작성자가 클라이언트에게 리소스를 로드할 출처를 선언하고 알리는 선언적 정책이다.

Content Security Policy는 모든 콘텐츠 삽입 취약점을 해결하기 위한 것이 아니지만, CSP는 콘텐츠 삽입 공격으로 인한 피해를 줄이는 데 도움이 될 수 있다.

스프링 시큐리티는 기본적으로 CSP를 추가하지는 않는다. 애플리케이션의 맥락 없이 합리적인 기본값을 설정하는 것이 불가능하기 때문이다. 애플리케이션 작성자가 보호할 리소스에 대해 보안 정책을 선언하고 모니터링해야 한다.

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
        // ...
        .headers(headers -> headers
            .contentSecurityPolicy(policy -> policy
                .policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
            )
        );
    return http.build();
}

위 코드는 스크립트는 현재 도메인('self')과 https://trustedscripts.example.com에서만 로드될 수 있도록 하고, 플러그인 콘텐츠는 https://trustedplugins.example.com에서만 로드되도록 제한한다.

브라우저가 CSP 위반 사항을 감지하면 /csp-report-endpoint/ URL로 보고서를 전송하도록 한다.

XSS 방지를 위해서는 다층적인 접근이 필요하다. 서버 측에서는 위에서 언급한 설정들 이외에도 사용자 입력값을 철저히 검증하고 적절히 이스케이프 처리해야 한다. 동시에 프론트엔드에서도 React나 Vue.js 같은 현대적인 프레임워크가 제공하는 기본 XSS 방지 기능을 활용하는 등 애플리케이션의 여러 층위에서 보안 조치를 취해야 한다.

참고

Cross Site Scripting (XSS) | OWASP Foundation

Security HTTP Response Headers :: Spring Security

profile
개발블로그👩🏻‍💻

0개의 댓글