swagger-api / swagger-parser

Swagger Spec to Java POJOs
http://swagger.io
Apache License 2.0
778 stars 525 forks source link

Initial commit of safe url resolver #1910

Closed CalemRoelofsSB closed 1 year ago

CalemRoelofsSB commented 1 year ago

This PR adds a new module to the swagger parser repo: swagger-parser-safe-url-resolver

What is it?

The main class of the package is the PermittedUrlsChecker which has one method: verify(String url). This method takes in a string URL and performs the following steps:

  1. Gets the hostname portion from the URL
  2. Resolves the hostname to an IP address
  3. Checks if that IP address is in a private/restricted IP address range (and throws an exception if it is)
  4. Returns a ResolvedUrl object which contains 4.1. A String url where the original URL has the hostname replaced with the IP address
    4.2. A String hostHeader which contains the hostname from the original URL to be added as a host header

This behavior can also be customized with the allowlist and denylist in the constructor, whereby:

Why is it needed?

This lib can be used in services that deal with user-submitted URLs that get fetched (like in swagger-parser resolving external URL $refs) to protect against Server-Side Request Forgery and DNS rebinding attacks

Example usage

List<String> allowlist = List.of("mysite.local");
List<String> denylist = List.of("*.example.com:443");
var checker = new PermittedUrlsChecker(allowlist, denylist);

// Will throw a HostDeniedException as `localhost` resolves to local IP and is not in allowlist
checker.verify("http://localhost/example");

// Will return a ResolvedUrl if `github.com` resolves to a public IP
checker.verify("https://github.com/swagger-api/swagger-parser");

// Will throw a HostDeniedException as `*.example.com` is explicitly deny listed, even if it resolves to public IP
checker.verify("https://subdomain.example.com/somepage");

// Will return a `ResolvedUrl` as `mysite.local` is explicity allowlisted
checker.verify("http://mysite.local/example");
bcoughlan commented 1 year ago

Great stuff. LGTM at least. Will there be another PR to enable swagger-parser to be configured to use it?

CalemRoelofsSB commented 1 year ago

Great stuff. LGTM at least. Will there be another PR to enable swagger-parser to be configured to use it?

@bcoughlan Yes indeed, separate tickets created for parser and codegen implementations that will pull this lib in