programing

SpringRequestMapping 경로 매개 변수가 있는 인코딩 슬래시(%2F)는 HTTP 400을 제공합니다.

skycolor 2023. 7. 31. 21:15
반응형

SpringRequestMapping 경로 매개 변수가 있는 인코딩 슬래시(%2F)는 HTTP 400을 제공합니다.

이 질문은 봄마다 다르므로 중복 참조 질문이 아닙니다.누가 그것을 추가했든 간에 (사실로부터 3년 후에!) 진짜 답이 무엇인지 보기 위해 질문을 읽거나 댓글을 달지 않았습니다.인정된 답변이 정답은 아니지만, 답변 작성자는 제가 요청한 것처럼 다시 돌아오지 않고 편집했습니다.

3아래의 할 때, "이 보낸 으로 부정확했습니다합니다.token매개 변수에 URL 인코딩 슬래시(%2F)가 포함되어 있습니다(: "https://somewhere.com/ws/stuff/lookup/resourceId/287559/token/R4o6lI%2FbBx43/userName/jim "). %2F가 없으면 모든 것이 정상적으로 작동합니다.제3자가 이미 이 서비스를 호출하고 있기 때문에(물론!) 적어도 단기적으로는 그들이 보내는 것을 변경할 수 없습니다.서버 측에서 이 문제를 해결할 방법이 있습니까?

이 문제는 제가 사용하지 않는 UriTemplate와 관련이 있지만 https://jira.springsource.org/browse/SPR-8662 에 매우 잘 설명되어 있습니다.

@RequestMapping("/ws/stuff/**")
@Controller
public class StuffController {
  @RequestMapping(value = "/ws/stuff/lookup/resourceId/{resourceId}/token/{token}/userName/{userName}", method = RequestMethod.GET)
   public @ResponseBody
   String provisionResource(@PathVariable("resourceId") String resourceId, @PathVariable("token") String token, @PathVariable("userName") String userName, ModelMap modelMap,
         HttpServletRequest request, HttpServletResponse response) {
      return handle(resourceId, userName, request, token, modelMap);
   }
}

참고: 이것은 Glassfish 3.1.2에 있으며, 처음에는 Grizzly/Glassfish가 슬래시를 수락하지 않았지만,

-Dcom.sun.grizzly.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true

그것을 고쳤습니다.

asadmin set configs.config.server-config.network-config.protocols.protocol.http-listener-2.http.encoded-slash-enabled=true

도움이 되지 않는 것 같았습니다.

봄 부츠를 위해, 다음은 요령을 부렸습니다.

@SpringBootApplication
public class Application extends WebMvcConfigurerAdapter {

    public static void main(String[] args) throws Exception {
        System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        UrlPathHelper urlPathHelper = new UrlPathHelper();
        urlPathHelper.setUrlDecode(false);
        configurer.setUrlPathHelper(urlPathHelper);
    }

}

이것은 당신의 대답일 수 있습니다: urlencoded Forwardslash is break URL.

경로에 넣지 말고 요청 매개 변수로 이동하는 것이 좋습니다.

해결 방법:

요청 매핑을 다음으로 변경할 수 있습니다.

@RequestMapping(value = "/ws/stuff/lookup/resourceId/**", method = RequestMethod.GET) 

그런 다음 요청 개체에서 경로 변수를 수동으로 구문 분석합니다.

Spring Boot 2+ / Spring (보안) 5+ / Java 8+의 2019 업데이트:

amiddy의 답변에 대한 제 편집이 거부되었기 때문에, 저는 또한 Spring Boot 2+에 대한 완벽한 솔루션을 별도의 답변으로 제공하고 싶습니다.

WebMvcConfigurerAdapter/ 에서는 더 인터페이스 Spring5 / Java8로 할 수 있습니다.WebMvcConfigurer최종 결과:

@SpringBootApplication
public class Application implements WebMvcConfigurer {

    public static void main(String[] args) throws Exception {
        System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        UrlPathHelper urlPathHelper = new UrlPathHelper();
        urlPathHelper.setUrlDecode(false);
        configurer.setUrlPathHelper(urlPathHelper);
    }
}

의 Spring의 Spring을 구성해야 합니다.(Strict)HttpFirewall가 있는 된 슬래시의 " 오류메함께인슬않차하도려면록지되단가시래된딩코와"The request was rejected because the URL contained a potentially malicious String "%2F"

@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
    StrictHttpFirewall firewall = new StrictHttpFirewall();
    firewall.setAllowUrlEncodedSlash(true);    
    return firewall;
}

의 "Spring Boot"을 합니다.HttpFirewall가능한 경우 - " " - " " " " " " " " 을 해야 할 도 있습니다.WebSecurity여기에 언급된 바와 같이:

봄부츠 애플리케이션은 저에게 효과가 있었습니다.

버전 1 추가

org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true

application.properties 파일로 이동합니다.

버전 2는 스프링 부트 애플리케이션을 이렇게 실행합니다.

static void main(String[] args) {
    System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
    SpringApplication.run this, args
}

버전 3 또는 -Dorg.apache.tomcat.util.buf로 Java 응용 프로그램을 실행합니다.해독기.ALLOW_ENCODE_SLASH=true

%2F로 인코딩된 슬래시 경로 변수를 수정했습니다.

다음은 Spring 3.2.4에 대한 수정 사항입니다(다른 버전에서도 작동해야 함).기본 UrlPathHelper를 덮어써야 합니다.

    public class UrlPathHelperFixed extends UrlPathHelper {

        public UrlPathHelperFixed() {
            super.setUrlDecode(false);
        }

        @Override
        public void setUrlDecode(boolean urlDecode) {
            if (urlDecode) {
                throw new IllegalArgumentException("Handler [" + UrlPathHelperFixed.class.getName() + "] does not support URL decoding.");
            }
        }

        @Override
        public String getServletPath(HttpServletRequest request) {
            return getOriginatingServletPath(request);
        }

        @Override
        public String getOriginatingServletPath(HttpServletRequest request) {
            return request.getRequestURI().substring(request.getContextPath().length());
        }
    }

매핑 핸들러에 주입합니다.

    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
        <property name="order" value="-1"></property>
        <property name="urlPathHelper">
            <bean class="com.yoochoose.frontend.spring.UrlPathHelperFixed"/>
        </property>
    </bean>

하루 동안 열심히 일한 후에 지금은 저에게 효과가 있습니다 :-)

Spring 팀에 https://jira.springsource.org/browse/SPR-11101 로 제안되었습니다.

나는 나에게 효과가 있는 이 해결책을 찾았습니다.

System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");

스프링 직전 Application.run(args);

응용프로그램 클래스에 아래 코드를 추가합니다.

 @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        UrlPathHelper urlPathHelper = new UrlPathHelper();
        urlPathHelper.setUrlDecode(false);
        configurer.setUrlPathHelper(urlPathHelper);
    }

Spring Boot 3.x / Tomcat 10.x 솔루션

@leonid 및 @Edu의 의견 덕분에 Tomcat 10.x에 대한 지원이 제거되었습니다.UDecoder.ALLOW_ENCODED_SLASH릴리스 노트에는 다음과 같이 언급되어 있습니다.

시스템 속성 org.apache.tomcat.util.buf를 바꿉니다.해독기.커넥터 특성이 인코딩된 ALLOW_ENCODE_SLASH는 이러한 시퀀스를 거부하고 이러한 시퀀스를 디코딩하는 것 외에도 %2f 시퀀스를 디코딩하지 않고 응용 프로그램에 전달하는 추가 옵션을 추가합니다.(마크트)

이것의 봄에 해당하는 것이 바로 레오니드와 에듀가 지적한 것입니다.

    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() {
        log.info("Configuring Tomcat to allow encoded slashes.");
        return factory -> factory.addConnectorCustomizers(connector -> connector.setEncodedSolidusHandling(
                EncodedSolidusHandling.DECODE.getValue()));
    }

우리는 방금 제 사무실에서 이 문제에 부딪혔고, 우리는 당신이 쿼리 매개변수에 넣었던 Solubris의 말에서 위의 제안을 했습니다.유일한 추가 요구 사항은 데이터에 '&'도 포함되어 쿼리 매개 변수가 엉망이 될 수 있다는 것입니다.우리가 해야 할 일은 URL로 보내기 전에 텍스트를 인코딩하고 심지어 '&'을 걸러내는 것입니다.

은 또다대암입다니호화답은른다니를 인코딩하는 것입니다."/"두 번, 그것은 생산할 것입니다."%252F".
매된끝점스이다시디다니합코딩링핑으로 ."%2F"은 다음과 것을 하여 한 번 더 입니다.

URLDecoder.decode(encoded_URL, "UTF-8");

다음은 BACK_SLASH 문제를 해결한 내용입니다.

public static void main(String[] args) throws Exception {
  System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
  SpringApplication.run(Application.class, args);
}

그러나 application.yml을 통해 동일한 기능을 수행할 수 있습니다.

org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH: true

이 설정은 작동하지 않습니다.저는 그것을 위한 방법을 찾지 못했고, 여전히 그것을 보고 있습니다.

변수를 수동으로 구문 분석하지 않기 위해 다음을 수행했습니다.

  1. 다른 코드를 실행하기 전에 다음을 추가합니다.
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
  1. 그리고 컨트롤러에서 변수 하나 대신 변수 2개를 추가합니다. 예:
    @RequestMapping(value = "/api/devices-by-name/device={deviceId}/restconf/data/ietf-interfaces:interfaces-state/interface={dpuIdPrefix}/{dpuIdSuffix}",
            method = RequestMethod.GET,
            produces = "application/json")
    public ResponseEntity<String> getInterfaceState(@PathVariable(value = "deviceId") String deviceId,
                                                    @PathVariable(value = "dpuIdPrefix") String dpuIdPrefix,
                                                    @PathVariable(value = "dpuIdSuffix") String dpuIdSuffix) {
        String dpuId = dpuIdPrefix + "/" + dpuIdSuffix;

그러면 다음 항목을 검색할 수 있습니다.

curl -s -X GET http://localhost:9090/api/devices-by-name/device=ZNSDX16DPU03/restconf/data/ietf-interfaces:interfaces-state/interface=gfast%200%2F14

슬래시가 선택 사항인 경우 두 개의 서로 다른 요청 매핑을 구성해야 할 수 있습니다.

언급URL : https://stackoverflow.com/questions/13482020/encoded-slash-2f-with-spring-requestmapping-path-param-gives-http-400

반응형