# Is it possible to trace a backend through a reverse proxy?

I'm creating a reference network topology for a WebSocket chat application at work, and I'd like to have something clarified for my own understanding.

The current topology involves a reverse proxy between the customer and backend where the customer connects directly to the proxy. The backend has firewalls that only allow connections from the proxy.

The customer can see the address of the proxy in the page source or browser console. Would it be possible for a malicious customer to trace the address of the backend, and if so, would adding a second proxy be any use in mitigating this?

EDIT: Melin asked about my proxy and backend. I'm using WAMP for the proxy, mainly because it's based on Apache and out of previous familiarity with WAMP before I graduated (which was just about 8 months ago). Inside the Apache module for WAMP, I've defined Virtual Hosts which do the actual proxying, and Apache has been configured to listen only on the ports for these Virtual Hosts. I've add the configuration at the bottom of the post, minus the actual addresses and paths used.

This is all running on an internal network in the lab, so there's a few holes that won't be added in production code - such as self-signed certificates to test secure connections, or disabling verification of the backend certificate.

## I've stripped this down to remove the comments, and just include the stuff that's enabled
## The Virtual Hosts are down at the bottom

Listen myServer:8080
Listen myServer:8443

# modules that are enabled

ServerName myServer

#
# <Directory> blocks below.
#
<Directory />
AllowOverride none
Require all denied
</Directory>

DocumentRoot "c:/wamp/www/"
<Directory "c:/wamp/www/">
#
# Possible values for the Options directive are "None", "All",
# or any combination of:
#
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
#
# The Options directive is both complicated and important.  Please see
# http://httpd.apache.org/docs/2.4/mod/core.html#options
#

#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
#   AllowOverride FileInfo AuthConfig Limit
#
AllowOverride None

#
# Controls who can get stuff from this server.
#
Require all granted
</Directory>

#
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#
<IfModule dir_module>
DirectoryIndex index.php index.php3 index.html index.htm
</IfModule>

#
# The following lines prevent .htaccess and .htpasswd files from being
# viewed by Web clients.
#
<Files ".ht*">
Require all denied
</Files>

#
# Customizable error responses come in three flavors:
# 1) plain text 2) local redirects 3) external redirects
#
# Some examples:
ErrorDocument 500 "The server made a boo boo."
#ErrorDocument 404 /missing.html
#ErrorDocument 404 "/cgi-bin/missing_handler.pl"
#ErrorDocument 402 http://www.example.com/subscription_info.html
#

# Secure (SSL/TLS) connections
#Include conf/extra/httpd-ssl.conf
#
# Note: The following must must be present to support
#       starting without SSL on platforms with no /dev/random equivalent
#       but a statically compiled-in mod_ssl.
#
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>
#
# uncomment out the below to deal with user agents that deliberately
# violate open standards by misusing DNT (DNT *must* be a specific
# end-user choice)
#
#<IfModule setenvif_module>
#</IfModule>

# set up a reverse proxy here inside a virtual host on port 8080
<VirtualHost *:8080>
ServerName proxyserver

# turning off ProxyRequests turns this into a closed server - recommended for security reasons
# ProxyPreserveHost passes the Host: line from the incoming request to the proxied host
# ProxyVia controls the use of the Via: HTTP header. If turned on, each request and reply has a Via: header added for this host
ProxyRequests Off
ProxyPreserveHost On
ProxyVia On

# Anything inside this applies only to matching proxied content
# in this case, it allows connections from everything that connects to this server - could be changed later
<Proxy *>
Order deny,allow
Allow from all
</Proxy>

# turn on full logging - not strictly needed, but useful
LogLevel debug

#SSLProxyEngine On

# this is the actual redirection: anything coming in on port 8080 which ends in /chat
# will be redirected to the backend servlet at the following address
<Location /chat>
ProxyPass           ws://<Backend:Normal_Port>/path/to/chat
ProxyPassReverse    ws://<Backend:Normal_Port>/path/to/chat
</Location>

</VirtualHost>

<VirtualHost *:8443>
ServerName SSLProxyServer

# turning off ProxyRequests turns this into a closed server - recommended for security reasons
# ProxyPreserveHost passes the Host: line from the incoming request to the proxied host
# ProxyVia controls the use of the Via: HTTP header. If turned on, each request and reply has a Via: header added for this host
ProxyRequests Off
ProxyPreserveHost On
ProxyVia On

# give the proxy a 10-minute timeout for development
ProxyTimeout 600

# Anything inside this applies only to matching proxied content
# in this case, it allows connections from everything that connects to this server - could be changed later
# e.g. Deny from all, followed by Allow from frontend.example.com would permit connections only from frontend.example.com
<Proxy *>
Order deny,allow
Allow from all
</Proxy>

# turn on full logging - not strictly needed, but useful
LogLevel debug

# to actually use SSL, turn on the SSL engine!
SSLEngine On
SSLProxyEngine On

# disable cert verification for backend *for development*
# this is due to the backend cert being self-signed during testing
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off

# link to the certificate and key for this server
SSLCertificateFile      "path\to\certificate"
SSLCertificateKeyFile   "path\to\key"

# this is the actual redirection: anything coming in on port 8443 which ends in /chat
# will be redirected to the backend servlet at the following address
<Location /chat>
ProxyPass               wss://<Backend:Secure_Port>/path/to/chat
ProxyPassReverse        wss://<Backend:Secure_Port>/path/to/chat
</Location>

</VirtualHost>

• The Apache documentation specifies that mod_proxy automatically forwards three headers (X-Forwarded-For, X-Forwarded-Host, and X-Forwarded-Server). You may want to turn these off. I'd also recommend looking into using mod_security as an IPS for eliminating general badness. – Milen Jul 27 '15 at 19:42
• One more thing I forgot to mention - I recommend that turn off Indexes options if you're using this as a reverse proxy. Tones down the exposure. Also, you do not need ProxyVia, turn that off - it would make sense if you're cascading proxies, but I do not think it's relevant in your case. – Milen Jul 27 '15 at 20:04

Revealing the internal IP address is not always down to the proxy, sometimes the back-end is not properly configured, and its web server would "leak" system details, such as application paths and configuration details.

One area that is particularly "vulnerable" to data leakage are error pages - default IIS and Apache error pages may reveal the internal IP address. Always disable these default pages, and have your own custom error pages that do not leak any internal information.

Also, it depends on the type of reverse proxy used, and its configuration. What you need to check for is the frequently "automatically added" X-Forwareded-for and X-Forwarded-IP HTTP headers by using Apache's mod_headers:

Header unset X-Forwarded-For