HttpServletRequest getRequestURI in SpringBoot

Viewed 367

I have a SpringBoot ap. with this method in the controller:

@GetMapping(value = "/")
public String home(Model model, HttpServletRequest request) {
    System.out.println("home ->" + request.getRequestURI() + "<-");
}

but when I do from the console:

curl localhost:7080
curl localhost:7080/./
curl localhost:7080/../
curl localhost:7080/..

I always get the same result: home ->/<-

and the same result with the browser. and I would like to return 404 for all the mapping that are not localhost:7080

I've tried:

MacBook-Pro-de-nunito:~ nunito$ curl --path--as-is localhost:7080/./
curl: option --path--as-is: is unknown
curl: try 'curl --help' or 'curl --manual' for more information


 curl --version
curl 7.64.1 (x86_64-apple-darwin20.0) libcurl/7.64.1 (SecureTransport) LibreSSL/2.8.3 zlib/1.2.11 nghttp2/1.41.0
Release-Date: 2019-03-27
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS GSS-API HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz MultiSSL NTLM NTLM_WB SPNEGO SSL UnixSockets
2 Answers

These should already be blocked as they contain path traversal. They are not valid request.

Curl is modifying them before sending to spring just like browser does. You could use --path-as-is flag to instruct curl to send the url as is.

Something like

curl --path-as-is localhost:7080/./

Once you do this you should get internal server error with the RequestedRejectedException.

There is open jira to change this to 400 by default - https://github.com/spring-projects/spring-security/issues/7568

I would suggest taking help from 3PP libraries. Example below

<dependency>
  <groupId>org.zalando</groupId>
  <artifactId>logbook-spring-boot-starter</artifactId>
  <version>2.4.1</version>
</dependency>

And add a class that will put proper complete URL into the request scope before the request reaches the actual controller

public class LogbookSink implements Sink {

    @Override
    public void write(final Precorrelation precorrelation, final HttpRequest request) throws IOException {
        request.setAttribute("complete_url", request.getRequestUri());
    }

    @Override
    public void write(final Correlation correlation, final HttpRequest request, final HttpResponse response) throws IOException {
        //do something else for response
    }
}

Now in the controller, you can simply get the exact "called" URI by saying

String calledUri = request.getAttribute("complete_url");
//your logic to throw 404
//if (!calledUri.matches("localhost:7080/")){
//    throw new ResponseStatusException(NOT_FOUND, "Unable to find resource");
//}
Related