To block all URIs containing a tilde character in Nginx, use the regular expression location directive location ~ /~ combined with a return statement. This configuration matches any request path that includes a tilde anywhere after the domain name and immediately returns a 403 Forbidden or 404 Not Found status code, effectively rejecting the request before it reaches your application server.
Understanding the Tilde Character Risk
The tilde character (~) is historically associated with user home directories in Unix-like systems. While modern web applications rarely use this convention for public URLs, its presence in a URI often indicates a security misconfiguration, an automated attack, or a leftover from legacy file system structures. Attackers frequently probe for these characters to access sensitive files, attempt directory traversal, or exploit vulnerabilities in older software stacks that interpret tildes as special path delimiters.
By explicitly declining these requests at the reverse proxy level, you reduce the load on your backend application servers. This simple filter prevents unnecessary processing of malformed or malicious traffic, enhancing both the performance and security posture of your Nginx deployment. It is a proactive measure that aligns with the principle of least privilege by denying access to resources that should never be publicly accessible via standard HTTP methods.
For more insights on managing URL patterns in Nginx, see Creating List of URLs from Nginx Location Directive.
Configuring the Regex Location Block
Nginx processes location blocks in a specific order: exact matches first, then prefix matches, and finally regular expressions. To ensure that your tilde-blocking rule takes precedence over other generic rules, you must place it strategically within your server block. The most effective approach uses a regular expression location directive that matches the tilde character anywhere in the URI path. Open your Nginx configuration file, typically located at/etc/nginx/sites-available/default or within the /etc/nginx/conf.d/ directory. Inside the relevant server block, add a new location directive. The syntax requires the ~ modifier to indicate a case-sensitive regular expression match. The pattern itself should target the tilde character. A common misconception is that the regex must start with a slash, but since Nginx strips the leading slash from the URI before matching against location patterns, you can simply target the character directly or include the preceding slash depending on your specific needs.
However, to catch /~file and /path/~to/file, the regex ~ /~ works because the URI passed to the regex context usually retains the leading slash in some contexts or the pattern is interpreted relative to the path. Actually, Nginx's regex locations match against the full URI including the leading slash. Therefore, the pattern ~ /~ will match any URI that contains a tilde preceded by a slash. If you want to be absolutely certain to catch any tilde, you might consider ~ .*~.*, but ~ /~ is sufficient for standard web paths where the tilde appears after the root.
Here is the correct configuration snippet:
server {
listen 80;
server_name example.com;
# Block any URI containing a tilde
location ~ /~ {
return 403 "Forbidden";
}
# Your other location blocks here
location / {
proxy_pass http://backend;
}
}
This block instructs Nginx to evaluate the incoming URI against the regular expression. If the pattern matches, Nginx immediately executes the return directive, sending a 403 Forbidden response to the client. The request does not proceed to any further location matching or upstream proxying.
Case Sensitivity Considerations
By default, the~ modifier performs a case-sensitive match. Since the tilde character is a single ASCII symbol, case sensitivity is generally not a concern for this specific character. However, if you were blocking other alphabetic characters, you would need to use ~* for case-insensitive matching. For the tilde, ~ is perfectly adequate and slightly more efficient.
If you are dealing with internationalized domain names or complex encoding issues, ensure that your Nginx version supports UTF-8 properly. Modern versions of Nginx handle Unicode correctly, so a tilde encoded in UTF-8 will still be matched by the ASCII-based regex pattern.
Testing and Validating the Configuration
Before applying the changes to your production environment, always test the configuration syntax. Run the following command in your terminal:sudo nginx -t
If the output indicates that the test is successful, reload Nginx to apply the new rules without dropping existing connections:
sudo systemctl reload nginx
To verify that the rule is working, use curl to send a test request to a URI containing a tilde. For example:
curl -I http://example.com/~test
You should receive a 403 Forbidden status code in the response headers. Additionally, test a normal URI like http://example.com/about to ensure that legitimate traffic is not being blocked. This validation step confirms that your regex is precise and does not have unintended side effects on other parts of your site.
For more information on rewriting arguments and handling complex URL structures, refer to How to use NGINX rewrite of arguments: A Comprehensive Guide.
Optimizing Performance and Security
Blocking these requests at the Nginx level is significantly more efficient than handling them in your application code. Nginx operates at the connection layer, allowing it to reject invalid requests before they consume CPU cycles or memory on your backend servers. This is particularly important for high-traffic sites that may be subjected to automated scanning tools looking for vulnerable paths. Furthermore, returning a 403 Forbidden provides clear feedback to clients that the resource is unavailable due to policy restrictions, rather than a generic 404 which might encourage further probing. From a security perspective, this reduces the attack surface by hiding the existence of potential legacy paths or misconfigurations that could otherwise be exploited.Frequently Asked Questions
What happens if I use a 404 instead of 403?
A 404 Not Found hides the fact that the path exists but is forbidden, which can sometimes deter attackers who are looking for specific error responses. However, a 403 Forbidden is more accurate for policy violations and clearly signals that the request was rejected by the server's configuration rather than the resource being missing.Does this regex block tildes in query strings?
No, the location directive matches only the URI path, not the query string parameters. If you need to block tildes in query strings, you would need to use a separateif directive checking the $query_string variable, though this is less common and can impact performance.
Can I use this method to block other special characters?
Yes, you can modify the regex pattern to match other characters such as backslashes or null bytes. For example,location ~ /\\ would block URIs containing a backslash. Always ensure your regex is anchored correctly to avoid false positives.
Why is my config not taking effect after editing?
Ensure you have runnginx -t to validate the syntax and then reloaded the service with systemctl reload nginx. Simply restarting the service with restart can cause brief downtime, while reload applies changes gracefully. Also check that the block is inside the correct server context.
Should I block tildes in subdomains too?
The configuration applies to the entire server block, affecting all hostnames served by that virtual host. If you have different requirements for different subdomains, you should create separateserver blocks for each and apply the tilde-blocking rule only where necessary.