— This post is part of a series of monthly blog posts about all kinds of Security topics for Developers —
Security experts, penetration testers, developers, administrators, and anyone else who creates or deploys software will often ask the question “Just how closely should I guard the version numbers of software and libraries that I use?”
Today, we are going to look at some answers to that question, and why we might choose one approach over another.
What version information are we talking about?
Any of the packages used in these layers can have security holes specific to certain versions, which means that knowing which exact version you are using can be valuable information to an attacker trying to find ways to breach the security of your whole system.
There are many ways for this information to become available to an attacker. It is often willingly included right into the response delivered to clients—for example, some Content Management Systems (CMS) include the generator HTML meta tag into their HTML headers, e.g.. <meta name=”generator” content=”WordPress 3.0.1” /> Other well-known examples are the auto-generated error pages of web servers. Sometimes the information might also be hidden in the metadata of generated documents, such as the “Application” field that can be seen in the properties of an Adobe PDF file.
Two extreme positions
Preventing version disclosure is often considered best practice as it slows down hackers, but there are many discussions about this, and there seems to be little middle ground. Conventional wisdom holds that you should prevent any information from getting out at all, or on the other end of the scale, that the disclosing the versions of software you are using doesn’t make any difference.
Both positions aren’t very useful in practice, though. If your software offers a public API, it can be necessary to give some pointers to the version of the API so that clients can interface with it properly. This is true for the popular OpenSSH server and client, which require some version information so they can select the correct protocol version.
On the other hand, not caring at all about leaking the versions of software you use is not wise either. When a zero-day exploit is discovered, attackers have plenty of tools at their disposal for discovering vulnerable targets. Search engines like Shodan, which specialize on gathering information on web hosts (including which software versions and operating systems) are easily available. Likewise, cleverly constructed Google queries can also yield useful information.
Simply hiding the version information of software packages you are using is not the kind of silver bullet that some proclaim it to be. It is a prime example of security through obscurity.
Covering up a problem doesn’t solve the underlying issue
Hiding this version information might prevent you from becoming a target in these broad attacks from hackers simply looking to bolster their botnet or harvest general user data, but it does almost nothing to protect you against a dedicated attacker.
A text string containing the information is not the only way to find out which version of a server or application you are running. Response headers might change between versions, different API endpoints might be available or unavailable, or some recognizable changes might have been introduced in the CSS on the login screen; there are countless ways to deduct the version information via fingerprinting. Some differences can even be down to aspects that are almost impossible to change, like response timings or buffer sizes.
Even if the attacker remains blind, they may try out any known exploit in the software you are using. To be fair, this might trigger some intrusion detection system that you could have set up and produce very suspicious log entries. Still, if there is no one detecting the attack fast enough, any vulnerability can be exploited. Instead of hiding the software versions you are using, the only way to protect your system is to always apply the latest security updates.
These can arguably be called false alerts, as these files are publicly available anyways, and can be downloaded and analyzed. Therefore, you have little to gain by stripping that version information at the cost of complicating your build process and possibly, in modifying the files’ headers, even violating some licenses. A better solution might be to block access to these seemingly public files from unauthenticated users, though again this does not solve the root security problem. It only reduces the attack surface.
The benefits of keeping version information available
As mentioned earlier, there are benefits to making the version information of libraries or other parts of your software available. For example, what if you don’t have the luxury of offering your software as a solution in the cloud, but must support multiple versions installed on your customers’ machines? Troubleshooting may be a lot easier if the customer can supply that kind of information along with the support ticket. It might help the developers looking up known issues and pinpointing the problem more quickly.
So, what is the best advice to follow in practice? The solution lies in-between the two extremes. It cannot be said often enough that security is always a trade-off. If you can easily hide the version of the Java container or web server you are using, such as Jetty, then go ahead and do so. If it’s easy to hide a few revealing headers with your reverse proxy, that certainly won’t hurt; making yourself a smaller target is never wrong. This is even a great defense against untargeted attacks that might just aim at compromising as many servers as possible for spamming, denial of service attacks, or more fashionably nowadays, crypto mining.
But at the same time, remember that only applying security fixes will truly keep you safe—specially if you have valuable data to protect that might incentivize an attacker to spend extensive time on research and planning. A truly dedicated attacker will fail only if a security hole can no longer be exploited.