How do I hide headers that reveal server information, such as Server and X-Powered-By?
Short answer
The shortest way is to check the Remove server fingerprints(Server, X-Powered-By etc.) option in the Response Headers list of the Manage HTTP Security Headers action; this option removes the Server, X-Powered-By, X-AspNet-Version and X-AspNetMvc-Version headers from all responses. For other headers or condition-based deletion, Delete HTTP Header is used at the On Response stage; to keep the header and hide its value, Set HTTP Header or Replace HTTP Header Content is used.
Problem: Responses Reveal the Server Software and Its Version
Web servers and application frameworks add headers such as Server: Apache/2.4.41 (Ubuntu) or X-Powered-By: PHP/7.4 to responses. This information makes the software and its version visible from outside; security audits also require these headers to be removed. Without touching the configuration of the Backend Services one by one, the headers are removed while the response passes through TR7.
Solution: Four Methods
All the methods are applied on the HTTP vService to the responses returning from the Backend Service; the action takes effect when it is added to the Actions field of the vService.
| Your situation | Suitable method |
|---|---|
| Removing the common fingerprint headers with a single selection | Method 1: Manage HTTP Security Headers |
| Other headers or condition-based deletion | Method 2: Delete HTTP Header |
| The header should stay, with a fixed value | Method 3: Set HTTP Header |
| Dropping only the version information | Method 4: Replace HTTP Header Content |
Method 1: Manage HTTP Security Headers Recommended
- How it works A single option removes four fingerprint headers from all responses; the action takes no condition. Security headers can also be selected in the same action.
- Where it is openedLoad Balancer → Actions → Manage HTTP Security Headers → Response Headers
- Requirement At least one selection
- vService type HTTP
Step-by-Step Configuration
Load Balancer → Actions → Add is clicked (how to add).
Action Name is entered, and Action Type = Manage HTTP Security Headers is selected.
Remove server fingerprints(Server, X-Powered-By etc.) is checked in the Response Headers list.
Add is clicked.
On the Load Balancer → Load Balancer vService List screen, the HTTP vService is selected and Edit is clicked.
Save is clicked. The change is applied without dropping open connections; in a cluster, it is also sent to the peer device with the default auto-sync (if Manual Sync Mode is on, with Synchronize).
Verification
curl -skI https://www.example.com/ | grep -iE '^(server|x-powered-by|x-aspnet)'
Empty outputWith Debug on in the vService, the Debug Mode Logs record is checked on its Response tab.
Server and X-Powered-By in red rows, trash can markMethod 2: Delete HTTP Header
- How it works The header whose name is written is deleted from the response; with a condition, it can be applied only to specific responses.
- Where it is openedLoad Balancer → Actions → Delete HTTP Header
- Requirement A separate action for each header
- vService type HTTP
Step-by-Step Configuration
Load Balancer → Actions → Add is clicked.
Action Type = Delete HTTP Header is selected.
Execution Level = On response (default On request; cannot be changed after saving), Header to Delete = X-Generator. To delete based on a condition, a condition is selected in the Conditions field (framework information on error pages).
Add is clicked; steps 1–4 are repeated for each header to be deleted.
The vService is opened with Edit.
The actions are selected in the Details → Actions field.
Save is clicked.
Verification
curl -skI https://www.example.com/ | grep -i '^x-generator'
Empty outputMethod 3: Set HTTP Header
- How it works The header stays, and its value is replaced with a fixed text; all repetitions of the header with the same name are reduced to a single value.
- Where it is openedLoad Balancer → Actions → Set HTTP Header
- Requirement None
- vService type HTTP
Step-by-Step Configuration
Load Balancer → Actions → Add is clicked.
Action Type = Set HTTP Header is selected.
Execution Level = On response, Header to Edit = Server, Header Content = web.
Add is clicked.
The vService is opened with Edit.
The action is selected in the Details → Actions field.
Save is clicked.
Verification
curl -skI https://www.example.com/
Server: webMethod 4: Replace HTTP Header Content
- How it works If the pattern matches, the header value is rewritten; the software name captured with the group is preserved, and the version is dropped.
- Where it is openedLoad Balancer → Actions → Replace HTTP Header Content
- Requirement The pattern is case-sensitive
- vService type HTTP
Step-by-Step Configuration
Load Balancer → Actions → Add is clicked.
Action Type = Replace HTTP Header Content is selected.
Execution Level = On response, Header to Replace = Server, Regex to Match = ^([^/]+)/.*$, Replacement Content = \1 (Can I change a header value with a regex?).
Add is clicked.
The vService is opened with Edit.
The action is selected in the Details → Actions field.
Save is clicked.
The result of the pattern on example values:
| Server value | Result |
|---|---|
Apache/2.4.41 (Ubuntu) | Apache |
nginx/1.18.0 | nginx |
Microsoft-IIS/10.0 | Microsoft-IIS |
cloudflare, Apache (without version) | Does not match; unchanged |
Verification
curl -skI https://www.example.com/
Server: ApacheCommon Mistakes
- Leaving the Execution level at On request in Delete HTTP header. The header is deleted from the request and stays in the response; since the Execution level cannot be changed after saving, the action is recreated with On response.
- Expecting bulk deletion with a wildcard. Delete HTTP Header matches the name exactly (case differences are ignored); patterns such as
X-*do not work. - Trying to add a condition to Manage HTTP security headers. This action has no Conditions field and is applied to all responses; Delete HTTP Header is used for condition-based deletion.
- Expecting an effect on the responses produced by TR7 itself. The headers are removed from the responses returning from the Backend Service; the blocking, redirect and error responses produced by TR7 do not carry these headers anyway.
How it is done in the documentation
