Internal IP addresses and hostnames exposed
CWE-200CWE-204OWASP A05:2021Updated September 4, 20264 min read
Internal IP addresses, server names and domains ending up in HTTP headers, error messages, redirects or HTML comments give an attacker a picture of your network layout. That grants no direct access, but it is precisely the information needed to make a next step deliberate.
An attacker who gets in does not know what your network looks like. Mapping that takes time and generates traffic that can be noticed. Internal addresses your application gives away itself spare them that step. It happens along several routes, and it counts mainly in combination with other weaknesses.
What exactly leaks?
We speak of exposed internal addresses when an application gives away addresses or names that only have meaning within your own network. That means private IP addresses from the reserved ranges, server names, and internal domain names that are not public.
Those details are not secret in the sense that they open anything: an attacker on the internet cannot reach a private address. What they give away is structure: how many servers there are, what they are called, how the numbering is built, which roles exist. A name such as db-prod-02.internal.company.com states in one line that there is a production database, that a db-prod-01 probably exists, and that the internal domain is internal.company.com.
It is a floor plan blowing out of a building. There is no key attached, and it is still valuable to whoever intends to go inside.
Where do those internal addresses come from?
Vulnerable:
HTTP/1.1 500 Internal Server Error
X-Backend-Server: app-node-03.internal.company.com
Via: 1.1 proxy-dmz-01 (squid/5.2)
Cannot connect to 10.0.4.12:5432 (database-prod-02)
Three lines, three leaks. The header reveals the application server’s name and the internal domain. The proxy header names a system in the demilitarised zone. And the error message gives the IP address, the port and the name of the database server.
Other places are less conspicuous but equally productive. A redirect containing the internal address rather than the public one. An HTML comment referring to a test server. An email header showing the full internal route. A Location header carrying the backend server’s address after a misconfigured proxy.
Safe:
# The proxy cleans up what the backend adds
proxy_hide_header X-Backend-Server;
proxy_hide_header X-Powered-By;
proxy_hide_header Via;
# Rewrite redirects to the public address
proxy_redirect http://app-node-03.internal.company.com/ https://portal.example/;
// And error messages never contain addresses
app.use((error, req, res, next) => {
const reference = randomUUID();
logger.error({ reference, message: error.message, stack: error.stack });
res.status(500).json({ error: 'Something went wrong', reference });
});
The proxy is the right place here, because there you clean up in one go what every backend service adds, including services whose configuration is not in your hands. The error handling ensures no address ever ends up in the response; the details sit in your log file, tied to a reference number.
What is the impact of exposed internal addresses?
The severity is low, and it stays that way in virtually every situation. No attack becomes possible through this information; no access is gained and no user data leaks.
The value lies in reconnaissance. An attacker who has got in by another route, a compromised account, a workstation, a vulnerability in another service, has to work out where they are and what is worth reaching. That work takes time and generates network traffic detection systems can notice. If they already know the addresses, they can proceed deliberately and stay unnoticed longer.
There is a second consideration. The places where internal addresses leak are nearly always the same places where other information leaks: verbose error messages, headers that were not cleaned up, comments left behind. Cleaning them up therefore usually addresses more than this finding alone.
How do you detect exposed internal addresses?
A tester searches all responses for patterns indicating private addresses, and for hostnames with an internal-looking domain. That happens not only on the ordinary pages but precisely where things go wrong: error pages, redirects, responses to malformed requests and temporary failures.
They also compare the headers of different kinds of response, because a static file and an API response are handled by different components and therefore carry different headers. HTML comments get attention too, along with JavaScript files containing configured addresses, and the headers of email the application sends. Files published from an internal environment are examined as well, because paths to network locations can sit in those. AssistSec combines these findings into a picture of your internal structure, exactly as an attacker would, and that picture usually makes clearer than the individual lines why cleaning up is worthwhile.
How do you prevent exposed internal addresses?
- Clean up headers at your reverse proxy, so backend services do not send their names along.
- Rewrite redirects to the public address rather than passing the internal one through.
- Never include addresses or server names in error messages shown to the user.
- Remove HTML comments and configured internal addresses from your frontend files.
- Have your outbound mail server strip internal routing lines from email headers.
- Check that
Locationheaders carry the public address after a proxy. - Use neutral server names that do not reveal a role or numbering.
- Include this check in your acceptance process, because leaks usually arise from a configuration change.
Sources
Frequently asked questions
Is an internal IP address really usable to an attacker?
Not directly, because they cannot reach it from the internet. It becomes usable once they are inside somewhere, or when a vulnerability exists where your server makes requests on their behalf. It then spares them the work of mapping the network themselves.
Where does it usually leak?
In error messages naming a database server or an internal API, in redirects accidentally containing the internal address, in headers added by a proxy, and in HTML comments left over from development. Email headers often carry the internal route as well.
What about email headers?
An outgoing email carries the route the message travelled, including internal server names and addresses. That is default behaviour for most mail servers and yields a good picture of your internal infrastructure. Have your outbound server strip those lines.
Is this important enough to address?
On its own it is a low finding and rarely urgent. It is worth doing because it nearly always coincides with something else: the place where the address leaks is usually an error message or a header you wanted to clean up anyway.
Related articles
- VulnerabilitiesCWE-200A01:2021Information disclosureInformation disclosure explained: how stack traces, .git directories, source maps and over-sharing API responses leak data, and how to stop it.
- VulnerabilitiesCWE-200A05:2021Metadata in published filesDocuments and photos carry hidden data: names, internal paths, software and sometimes locations. Learn how to strip it before publishing.
- VulnerabilitiesCWE-918A10:2021Server-side request forgery (SSRF)Server-side request forgery (SSRF) explained: how attackers abuse your server to reach internal systems and cloud services, and how to prevent it.
- VulnerabilitiesCWE-209A05:2021Detailed error messagesStack traces and database errors reveal your technology, paths and queries. Learn what an attacker takes from them and how to handle errors.
- VulnerabilitiesCWE-200A05:2021Version information in HTTP headersHeaders such as Server and X-Powered-By state exactly which software you run. Learn why that eases targeted scanning and how to remove them.