IT이야기

사람들이 Spring MVC에서 XSS를 수행하는 것 방지 방법

cyworld 2021. 10. 22. 21:25
반응형

사람들이 Spring MVC에서 XSS를 수행하는 것을 어떻게 방지합니까?


Spring MVC에서 XSS를 방지하려면 어떻게 해야 하나요? 지금은 사용자 텍스트를 JSTL <c:out>태그 또는 fn:escapeXml()함수에 출력하는 모든 위치를 넣고 있지만 장소를 놓칠 수 있으므로 오류가 발생하기 쉽습니다.

이를 예방할 수 있는 쉽고 체계적인 방법이 있습니까? 필터같은거 아닐까요? @RequestParam컨트롤러 메서드에 매개변수를 지정하여 입력을 수집하고 있습니다.


Spring에서는 <form>태그에 의해 생성된 JSP 페이지에서 html을 이스케이프할 수 있습니다 . 이것은 XSS 공격에 대한 많은 경로를 차단하며 세 가지 방법으로 자동으로 수행될 수 있습니다.

web.xml파일 의 전체 애플리케이션 :

<context-param>
    <param-name>defaultHtmlEscape</param-name>
    <param-value>true</param-value>
</context-param>

파일 자체의 지정된 페이지에 있는 모든 양식에 대해:

<spring:htmlEscape defaultHtmlEscape="true" /> 

각 양식에 대해:

<form:input path="someFormField" htmlEscape="true" /> 

XSSFilter를 사용해보십시오 .


@Valid모든 입력 객체(바인딩 및 @RequestBodyjson, https://dzone.com/articles/spring-31-valid-requestbody 참조 )에 대해 Hibernate Validator를 사용 합니다. 그래서 @org.hibernate.validator.constraints.SafeHtml나에게 좋은 솔루션입니다.

Hibernate SafeHtmlValidator는 에 의존 org.jsoup하므로 프로젝트 종속성을 하나 더 추가해야 합니다.

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.10.1</version>
</dependency>

콩의 경우 User필드

@NotEmpty
@SafeHtml
protected String name;

<script>alert(123)</script>컨트롤러의 으로 업데이트 시도

@PutMapping(value = "/{id}", consumes = MediaType.APPLICATION_JSON_VALUE)
public void update(@Valid @RequestBody User user, @PathVariable("id") int id) 

또는

@PostMapping
public void createOrUpdate(@Valid User user) {

BindException바인딩 및 기본 메시지에 MethodArgumentNotValidException대해 throw 됩니다 @RequestBody.

name may have unsafe html content

Validator는 지속하기 전과 마찬가지로 바인딩에도 작동합니다. 앱은 http://topjava.herokuapp.com/ 에서 테스트할 수 있습니다.


XSS를 방지하려고 할 때 컨텍스트를 생각하는 것이 중요합니다. 예를 들어 HTML 태그나 HTML 속성으로 데이터를 출력하는 것과 대조적으로 자바스크립트 스니펫에서 변수 내부에 데이터를 출력하는 경우 이스케이프 방법과 대상은 매우 다릅니다.

여기에 대한 예가 있습니다. http://erlend.oftedal.no/blog/?blogid=91

OWASP XSS 예방 치트 시트도 확인하십시오. http://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet

따라서 짧은 대답은 Tendayi Mawush가 제안한 것처럼 출력을 이스케이프 처리해야 하지만 HTML 속성이나 자바스크립트로 데이터를 출력할 때는 특별한 주의를 기울이는 것입니다.


처음에 사용자 입력을 어떻게 수집하고 있습니까? 다음을 사용하는 경우 이 질문/답변이 도움이 될 수 있습니다 FormController.

Spring: 명령에 바인딩할 때 입력 이스케이프


사용하는 메서드, 태그를 항상 수동으로 확인하고 마지막에 항상 이스케이프(한 번)하는지 확인하십시오. 프레임워크에는 이 측면에서 많은 버그와 차이점이 있습니다.

개요: http://www.gablog.eu/online/node/91


에만 의존하는 대신 <c:out />antixss 라이브러리도 사용해야 합니다. 이 라이브러리는 입력에서 악성 스크립트를 인코딩할 뿐만 아니라 삭제합니다. 사용 가능한 최고의 라이브러리 중 하나는 OWASP Antisamy 이며 매우 유연하며 요구 사항에 따라 구성(xml 정책 파일 사용)할 수 있습니다.

예를 들어 응용 프로그램이 텍스트 입력만 지원하는 경우 대부분의 html 태그를 삭제하고 삭제하는 OWASP에서 제공하는 대부분의 일반 정책 파일을 사용할 수 있습니다. 마찬가지로 응용 프로그램이 모든 종류의 html 태그가 필요한 html 편집기(예: tinymce)를 지원하는 경우 ebay 정책 파일 과 같은 보다 유연한 정책을 사용할 수 있습니다.


**To avoid XSS security threat in spring application**

XSS 문제에 대한 해결책은 양식을 제출할 때 양식의 모든 텍스트 필드를 필터링하는 것입니다.

    It needs XML entry in the web.xml file & two simple classes.

        java code :-
        The code for the  first class named CrossScriptingFilter.java is :

        package com.filter;

        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 org.apache.log4j.Logger;

        public class CrossScriptingFilter implements Filter {
            private static Logger logger = Logger.getLogger(CrossScriptingFilter.class);
            private FilterConfig filterConfig;

            public void init(FilterConfig filterConfig) throws ServletException {
                this.filterConfig = filterConfig;
            }

            public void destroy() {
                this.filterConfig = null;
            }

            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
                logger.info("Inlter CrossScriptingFilter  ...............");
                chain.doFilter(new RequestWrapper((HttpServletRequest) request), response);
                logger.info("Outlter CrossScriptingFilter ...............");
            }

        }

RequestWrapper.java라는 코드 두 번째 클래스는 다음과 같습니다.

패키지 com.filter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import org.apache.log4j.Logger;

public final class RequestWrapper extends HttpServletRequestWrapper {
    private static Logger logger = Logger.getLogger(RequestWrapper.class);
    public RequestWrapper(HttpServletRequest servletRequest) {
        super(servletRequest);
    }

    public String[] getParameterValues(String parameter) {
        logger.info("InarameterValues .. parameter .......");
        String[] values = super.getParameterValues(parameter);
        if (values == null) {
            return null;
        }
        int count = values.length;
        String[] encodedValues = new String[count];
        for (int i = 0; i < count; i++) {
            encodedValues[i] = cleanXSS(values[i]);
        }
        return encodedValues;
    }

    public String getParameter(String parameter) {
        logger.info("Inarameter .. parameter .......");
        String value = super.getParameter(parameter);
        if (value == null) {
            return null;
        }
        logger.info("Inarameter RequestWrapper ........ value .......");
        return cleanXSS(value);
    }

    public String getHeader(String name) {
        logger.info("Ineader .. parameter .......");
        String value = super.getHeader(name);
        if (value == null)
            return null;
        logger.info("Ineader RequestWrapper ........... value ....");
        return cleanXSS(value);
    }

    private String cleanXSS(String value) {
        // You'll need to remove the spaces from the html entities below
        logger.info("InnXSS RequestWrapper ..............." + value);
        //value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
        //value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
        //value = value.replaceAll("'", "& #39;");
        value = value.replaceAll("eval\\((.*)\\)", "");
        value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");

        value = value.replaceAll("(?i)<script.*?>.*?<script.*?>", "");
        value = value.replaceAll("(?i)<script.*?>.*?</script.*?>", "");
        value = value.replaceAll("(?i)<.*?javascript:.*?>.*?</.*?>", "");
        value = value.replaceAll("(?i)<.*?\\s+on.*?>.*?</.*?>", "");
        //value = value.replaceAll("<script>", "");
        //value = value.replaceAll("</script>", "");
        logger.info("OutnXSS RequestWrapper ........ value ......." + value);
        return value;
    }

남은 것은 web.xml 파일의 XML 항목뿐입니다.

        <filter>
        <filter-name>XSS</filter-name>
        <display-name>XSS</display-name>
        <description></description>
        <filter-class>com.filter.CrossScriptingFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>XSS</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

/*는 브라우저에서 만들어진 모든 요청에 ​​대해 CrossScriptingFilter 클래스를 호출함을 나타냅니다. 요청에서 가져온 모든 구성 요소/요소를 구문 분석하고 해커가 넣은 모든 자바 스크립트 태그를 빈 문자열로 대체합니다.

ReferenceURL : https://stackoverflow.com/questions/2147958/how-do-i-prevent-people-from-doing-xss-in-spring-mvc

반응형