Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<source>8</source>
<target>8</target>
</configuration>
</plugin>

Expand Down
29 changes: 29 additions & 0 deletions src/main/java/it/geosolutions/httpproxy/HTTPProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -847,12 +847,41 @@ private ProxyInfo setProxyRequestHeaders(URL url, HttpServletRequest httpServlet

Enumeration enumerationOfHeaderNames = httpServletRequest.getHeaderNames();

// ////////////////////////////////////////
// Load header whitelist/blacklist for
// filtering forwarded request headers.
// ////////////////////////////////////////

Set<String> headerWhitelist = proxyConfig.getRequestHeaderWhitelist();
Set<String> headerBlacklist = proxyConfig.getRequestHeaderBlacklist();

while (enumerationOfHeaderNames.hasMoreElements()) {
String stringHeaderName = (String) enumerationOfHeaderNames.nextElement();

if (stringHeaderName.equalsIgnoreCase(Utils.CONTENT_LENGTH_HEADER_NAME))
continue;

// ////////////////////////////////////////
// Apply header blacklist: always reject
// ////////////////////////////////////////

if (headerBlacklist != null && !headerBlacklist.isEmpty()) {
if (headerBlacklist.contains(stringHeaderName.toLowerCase())) {
continue;
}
}

// ////////////////////////////////////////
// Apply header whitelist: if set, only
// allow headers in the whitelist
// ////////////////////////////////////////

if (headerWhitelist != null && !headerWhitelist.isEmpty()) {
if (!headerWhitelist.contains(stringHeaderName.toLowerCase())) {
continue;
}
}

// ////////////////////////////////////////////////////////////////////////
// As per the Java Servlet API 2.5 documentation:
// Some headers, such as Accept-Language can be sent by clients
Expand Down
64 changes: 64 additions & 0 deletions src/main/java/it/geosolutions/httpproxy/ProxyConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ final class ProxyConfig {
*/
private Set<String> hostsWhitelist = new HashSet<String>();

/**
* A list of request header names (case-insensitive) that the proxy is permitted to forward.
* If non-empty, only headers in this set will be forwarded.
*/
private Set<String> requestHeaderWhitelist = new HashSet<String>();

/**
* A list of request header names (case-insensitive) that the proxy must NOT forward.
* Headers in this set will always be removed, even if they appear in the whitelist.
*/
private Set<String> requestHeaderBlacklist = new HashSet<String>();

/**
* The servlet context
*/
Expand Down Expand Up @@ -137,6 +149,14 @@ private void configProxy() {
if (p != null)
this.setHostsWhitelist(p);

p = Utils.parseWhiteList(props.getProperty("requestHeaderWhitelist"));
if (p != null)
this.setRequestHeaderWhitelist(Utils.toLowerCaseSet(p));

p = Utils.parseWhiteList(props.getProperty("requestHeaderBlacklist"));
if (p != null)
this.setRequestHeaderBlacklist(Utils.toLowerCaseSet(p));

// ////////////////////////////////////////
// Read various request type properties
// ////////////////////////////////////////
Expand Down Expand Up @@ -436,6 +456,50 @@ public void setHostsWhitelist(Set<String> hostsWhitelist) {
this.hostsWhitelist = hostsWhitelist;
}

/**
* @return the requestHeaderWhitelist
*/
public Set<String> getRequestHeaderWhitelist() {
Properties props = propertiesLoader();

if (props != null) {
Set<String> set = Utils.parseWhiteList(props.getProperty("requestHeaderWhitelist"));
if (set != null)
this.setRequestHeaderWhitelist(Utils.toLowerCaseSet(set));
}

return requestHeaderWhitelist;
}

/**
* @param requestHeaderWhitelist the requestHeaderWhitelist to set
*/
public void setRequestHeaderWhitelist(Set<String> requestHeaderWhitelist) {
this.requestHeaderWhitelist = requestHeaderWhitelist;
}

/**
* @return the requestHeaderBlacklist
*/
public Set<String> getRequestHeaderBlacklist() {
Properties props = propertiesLoader();

if (props != null) {
Set<String> set = Utils.parseWhiteList(props.getProperty("requestHeaderBlacklist"));
if (set != null)
this.setRequestHeaderBlacklist(Utils.toLowerCaseSet(set));
}

return requestHeaderBlacklist;
}

/**
* @param requestHeaderBlacklist the requestHeaderBlacklist to set
*/
public void setRequestHeaderBlacklist(Set<String> requestHeaderBlacklist) {
this.requestHeaderBlacklist = requestHeaderBlacklist;
}

/**
* @return the context
*/
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/it/geosolutions/httpproxy/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
* Utility methods.
Expand Down Expand Up @@ -150,6 +152,21 @@ static final Set<String> parseWhiteList(String property) {
}
}

/**
* Converts all strings in the given set to lower case.
*
* @param set the input set
* @return a new set with all strings converted to lower case
*/
static Set<String> toLowerCaseSet(Set<String> set) {
if (set == null) {
return null;
}
return set.stream().filter(Objects::nonNull)
.map(String::trim).map(String::toLowerCase)
.collect(Collectors.toSet());
}

static URL buildURL(String value) throws MalformedURLException {
URL url = new URL(value);

Expand Down
8 changes: 8 additions & 0 deletions src/main/resources/proxy.properties
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ methodsWhitelist = GET,POST,PUT

#hostsWhitelist = 127.0.0.1

# Optional: only forward these request headers (comma-separated, case-insensitive).
# If empty or commented out, all headers are forwarded (except those in the blacklist).
#requestHeaderWhitelist = Accept,Accept-Language,Content-Type,Authorization,Host

# Optional: never forward these request headers (comma-separated, case-insensitive).
# Blacklist takes precedence over whitelist.
#requestHeaderBlacklist = Cookie,X-Custom-Secret

#reqtypeWhitelist.capabilities = (([&]?([Rr][Ee][Qq][Uu][Ee][Ss][Tt]=[Gg]et[Cc]apabilities))|([&]?(version=1\\.1\\.1)))+
reqtypeWhitelist.capabilities = .*[Gg]et[Cc]apabilities.*
reqtypeWhitelist.featureinfo = .*[Gg]et[Ff]eature[Ii]nfo.*
Expand Down
Loading
Loading