TL;DR
To enhance the security of your web applications on Debian 13, implement the following HTTP security headers. These headers help mitigate various attacks, such as cross-site scripting (XSS), clickjacking, and content type sniffing.
Content Security Policy (CSP): Define which resources can be loaded by your application. Start with a restrictive policy and gradually allow necessary sources.
echo "add_header Content-Security-Policy \"default-src 'self'; img-src 'self' data:;\";" >> /etc/nginx/conf.d/security.confCaution: Test your CSP thoroughly to avoid breaking functionality.
X-Content-Type-Options: Prevent browsers from MIME-sniffing a response away from the declared content type.
echo "add_header X-Content-Type-Options nosniff;" >> /etc/nginx/conf.d/security.confX-Frame-Options: Protect against clickjacking by controlling whether your site can be displayed in a frame.
echo "add_header X-Frame-Options DENY;" >> /etc/nginx/conf.d/security.confX-XSS-Protection (Legacy/Deprecated): This header was intended to enable the browser’s built-in XSS auditor.
Deprecated:
X-XSS-Protectionhas been removed from all modern browsers. Chrome removed the XSS auditor in version 78 (2019); Firefox never implemented it; Edge removed it in 2020. Sending this header provides no protection in current browsers and can introduce vulnerabilities in older browsers. UseContent-Security-Policyinstead — a properly configured CSP is the correct and current replacement for XSS mitigation.The header is shown here for legacy reference only. Do not add it to new configurations:
# DEPRECATED - do not use in new configurations # echo "add_header X-XSS-Protection \"1; mode=block\";" >> /etc/nginx/conf.d/security.confStrict-Transport-Security (HSTS): Enforce secure connections to your server.
echo "add_header Strict-Transport-Security \"max-age=31536000; includeSubDomains;\";" >> /etc/nginx/conf.d/security.confCaution: Once HSTS is enabled, it can be difficult to disable. Ensure your site is fully HTTPS before applying.
After adding these headers, restart your web server to apply the changes:
## Restart Nginx
sudo systemctl restart nginx
Regularly review and update your security headers as your application evolves. Use tools like security scanners to verify header implementation and effectiveness.
Understanding Security Headers
Security headers are HTTP response headers that help protect web applications from various attacks by controlling how browsers handle content. Implementing these headers can significantly enhance the security posture of your web applications on a Debian 13 server.
Content Security Policy (CSP): This header helps prevent cross-site scripting (XSS) and data injection attacks by specifying which sources of content are trusted. A basic CSP can be set as follows:
echo "Content-Security-Policy: default-src 'self';" | sudo tee /etc/nginx/conf.d/security-headers.confCaution: Be careful when defining sources; overly permissive policies can expose your application to risks.
X-Content-Type-Options: This header prevents browsers from MIME-sniffing a response away from the declared content type. To set it, use:
echo "X-Content-Type-Options: nosniff" | sudo tee -a /etc/nginx/conf.d/security-headers.confSafe Default: Always set this header to nosniff.
X-Frame-Options: This header protects against clickjacking by controlling whether your site can be embedded in an iframe. Use the following command to set it:
echo "X-Frame-Options: DENY" | sudo tee -a /etc/nginx/conf.d/security-headers.confCaution: Setting it to SAMEORIGIN allows your site to be framed by pages on the same origin, which may be acceptable in some cases.
Strict-Transport-Security (HSTS): This header enforces the use of HTTPS, preventing man-in-the-middle attacks. To enable HSTS, use:
echo "Strict-Transport-Security: max-age=31536000; includeSubDomains" | sudo tee -a /etc/nginx/conf.d/security-headers.confCaution: Once HSTS is enabled, it cannot be easily undone. Ensure your site is fully HTTPS before applying this header.
Referrer-Policy: This header controls how much referrer information is passed when navigating from your site. A safe default is:
echo "Referrer-Policy: no-referrer" | sudo tee -a /etc/nginx/conf.d/security-headers.conf
By implementing these security headers, you can significantly reduce the attack surface of your web applications on Debian 13. Always test your configuration to ensure that legitimate functionality is not inadvertently broken.
Installing Required Packages
To implement security headers effectively, you will need to install a web server and a few additional packages that facilitate the configuration of security headers. Below are the steps to install the required packages on a Debian 13 server.
First, ensure your package list is up to date:
sudo apt update # Update the package list
Next, install the Apache web server, which is a popular choice for serving web applications:
sudo apt install apache2 # Install Apache web server
If you are using Nginx instead, you can install it with the following command:
sudo apt install nginx # Install Nginx web server
For both web servers, you may also want to install the libapache2-mod-security2 module for Apache or the nginx-extras package for Nginx, which provides additional security features:
For Apache:
sudo apt install libapache2-mod-security2 # Install ModSecurity for Apache
For Nginx:
sudo apt install nginx-extras # Install Nginx with extra modules
Additionally, consider installing curl for testing your headers later:
sudo apt install curl # Install curl for testing
Caution: Ensure that you only install packages from trusted sources. Always verify the integrity of the packages if you are downloading them from third-party repositories.
After installation, it is advisable to enable the necessary modules for Apache or configure the server blocks for Nginx to apply security headers effectively.
By following these steps, you will have the essential tools required to implement security headers for your web applications on Debian 13.
Configuring Security Headers in Apache
To enhance the security of your web applications hosted on an Apache server, configuring security headers is essential. These headers help protect against various attacks, such as cross-site scripting (XSS), clickjacking, and other vulnerabilities. Below are the steps to configure common security headers in Apache on a Debian 13 server.
Edit the Apache Configuration File: Open your Apache configuration file or the specific virtual host file for your site. This is typically located in /etc/apache2/sites-available/. Use a text editor like nano or vim.
sudo nano /etc/apache2/sites-available/000-default.confAdd Security Headers: Within the VirtualHost block, add the following directives to set the security headers:
<VirtualHost *:80> # Content Security Policy Header set Content-Security-Policy "default-src 'self';" # X-Content-Type-Options Header set X-Content-Type-Options "nosniff" # X-Frame-Options Header set X-Frame-Options "DENY" # X-XSS-Protection (DEPRECATED - removed from modern browsers, do not use) # Header set X-XSS-Protection "1; mode=block" # Referrer-Policy Header set Referrer-Policy "no-referrer" # Permissions-Policy Header set Permissions-Policy "geolocation=(self), microphone=()" # Ensure headers are only added if mod_headers is enabled Header always set X-Permitted-Cross-Domain-Policies "none" </VirtualHost>Caution: Adjust the Content-Security-Policy to suit your application needs. A restrictive policy can break functionality if not configured correctly.
Enable Required Modules: Ensure that the headers module is enabled in Apache. You can enable it using the following command:
sudo a2enmod headers # Enable the headers moduleRestart Apache: After making changes, restart the Apache service to apply the new configuration.
sudo systemctl restart apache2 # Restart ApacheTest Your Configuration: Use tools like curl or browser developer tools to verify that the headers are being sent correctly. For example:
curl -I http://yourdomain.com # Check response headers
By implementing these security headers, you significantly enhance the security posture of your web applications on Debian 13.
Configuring Security Headers in Nginx
For Nginx servers, security headers are configured in server blocks. Here’s how to implement them:
Edit Nginx Configuration: Open your Nginx configuration file:
sudo nano /etc/nginx/sites-available/defaultAdd Security Headers: Add the following directives within your server block:
server { listen 80; server_name yourdomain.com; # Content Security Policy add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';" always; # X-Content-Type-Options add_header X-Content-Type-Options "nosniff" always; # X-Frame-Options add_header X-Frame-Options "DENY" always; # X-XSS-Protection (DEPRECATED - removed from modern browsers, do not use) # add_header X-XSS-Protection "1; mode=block" always; # HSTS add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; # Referrer-Policy add_header Referrer-Policy "strict-origin-when-cross-origin" always; # Permissions-Policy add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always; location / { root /var/www/html; index index.html; } }Test Configuration: Always test your Nginx configuration before reloading:
sudo nginx -t # Test configurationReload Nginx: Apply the changes:
sudo systemctl reload nginx # Reload Nginx
Testing Security Headers
To test the security headers implemented in your web application, you can use command-line tools such as curl and wget, or web-based services that analyze HTTP headers. Below are methods to verify your security headers directly from your Debian 13 server.
The curl command is a versatile tool for making HTTP requests and can be used to inspect the headers returned by your web server. Use the following command to fetch the headers:
curl -I https://yourdomain.com # Fetch headers for your domain
The -I option tells curl to fetch only the HTTP headers. Look for the security headers in the output, such as Content-Security-Policy, X-Content-Type-Options, and Strict-Transport-Security.
Using wget
Another option is to use wget, which can also display headers. Run the following command:
wget --server-response --spider https://yourdomain.com # Check headers with wget
Using Online Tools
Several online tools can analyze your security headers:
- securityheaders.com: Enter your domain to get a detailed report
- Mozilla Observatory: Provides comprehensive security analysis
- SSL Labs: Tests HTTPS configuration and headers
Automated Testing Script
Create a script to automatically test headers:
#!/bin/bash
# test-headers.sh
DOMAIN="yourdomain.com"
echo "Testing security headers for $DOMAIN"
echo "========================================"
curl -sI "https://$DOMAIN" | grep -E "(Content-Security-Policy|X-Frame-Options|X-Content-Type-Options|Strict-Transport-Security|X-XSS-Protection|Referrer-Policy)"
echo "========================================"
echo "Test complete"
Make it executable:
chmod +x test-headers.sh
./test-headers.sh
Troubleshooting Common Issues
Headers Not Appearing
If headers are not showing in responses, check:
Module is Enabled (Apache):
apache2ctl -M | grep headers # Verify headers module is loadedConfiguration Syntax (Nginx):
sudo nginx -t # Test configurationVirtual Host Configuration: Ensure headers are in the correct server block or virtual host.
CSP Breaking Functionality
If Content Security Policy blocks legitimate resources:
Check Browser Console: Look for CSP violation reports
Use Report-Only Mode:
add_header Content-Security-Policy-Report-Only "default-src 'self';" always;Gradually Tighten Policy: Start permissive and restrict incrementally
HSTS Preventing HTTP Access
If HSTS causes issues:
Clear Browser HSTS Cache: In Chrome, visit chrome://net-internals/#hsts
Reduce max-age: Start with shorter durations during testing:
add_header Strict-Transport-Security "max-age=300" always; # 5 minutes for testing
Headers Not Applied to Subdirectories
Ensure the always parameter is used in Nginx:
add_header X-Frame-Options "DENY" always; # 'always' ensures header is sent even on error pages
Conflicting Headers
Multiple configuration files may cause conflicts. Check:
## For Nginx
sudo nginx -T | grep "add_header" # Show all header directives
## For Apache
sudo apache2ctl -S # Show virtual host configuration
Best Practices
1. Implement Defense in Depth
Use multiple security headers together for layered protection. No single header provides complete protection.
2. Start Restrictive, Then Relax
Begin with strict policies and loosen them as needed based on application requirements.
3. Use HTTPS Everywhere
Many security headers (like HSTS) require HTTPS to be effective. Always use TLS/SSL certificates.
4. Regular Security Audits
Periodically scan your site with tools like:
curl -I https://yourdomain.com | grep -i "security\|frame\|content"
5. Monitor CSP Violations
Implement CSP reporting to track policy violations:
add_header Content-Security-Policy "default-src 'self'; report-uri /csp-report" always;
6. Document Your Policies
Maintain documentation explaining why each header is configured the way it is.
7. Test Across Browsers
Different browsers implement security headers differently. Test on Chrome, Firefox, Safari, and Edge.
8. Keep Headers Updated
Security standards evolve. Regularly review and update your header configurations.
9. Use Subresource Integrity
For external scripts and styles, use SRI hashes:
<script src="https://cdn.example.com/script.js"
integrity="sha384-hash"
crossorigin="anonymous"></script>
Verification
Check Service Status
Verify your web server is running:
sudo systemctl status nginx # For Nginx
## OR
sudo systemctl status apache2 # For Apache
Expected: active (running)
Verify Headers with curl
Test that all security headers are present:
curl -I https://yourdomain.com
Expected headers to see:
- Content-Security-Policy
- X-Content-Type-Options: nosniff
- X-Frame-Options: DENY
- Strict-Transport-Security
- Referrer-Policy
Note: X-XSS-Protection is deprecated and should not be present. Modern XSS protection is handled by Content-Security-Policy.
Test Functionality
Verify your application works correctly with the headers:
## Test main page loads
curl -s https://yourdomain.com | head -n 5
## Test specific endpoints
curl -s https://yourdomain.com/api/health
Security Score Check
Use online tools to verify implementation:
## Use securityheaders.com API
curl -s "https://securityheaders.com/?q=yourdomain.com&followRedirects=on"
Validate CSP
Check CSP syntax and coverage:
## Extract and examine CSP header
curl -I https://yourdomain.com 2>&1 | grep -i "content-security-policy"
Related Guides
Deploying Content Security Policy (CSP) Correctly Learn how to effectively deploy Content Security Policy on Debian 13
Learn to enhance your Nginx server
Blocking Bad Bots with Nginx Map Learn how to effectively block unwanted bots on your Debian 13 server
Implement TLS 1.3 security best practices with Nginx on Debian 13, including
Protecting Against DoS with Nginx Limit Conn + Limit Req Learn to configure Nginx on Debian 13 to effectively mitigate DoS attacks
Rollback Procedure
If you need to revert these changes:
1. Stop the Web Server
sudo systemctl stop nginx # For Nginx
## OR
sudo systemctl stop apache2 # For Apache
2. Restore Configuration
## Restore from backup (create backups before making changes)
sudo cp /etc/nginx/nginx.conf.backup /etc/nginx/nginx.conf # For Nginx
## OR
sudo cp /etc/apache2/apache2.conf.backup /etc/apache2/apache2.conf # For Apache
3. Remove Security Headers Configuration
For Nginx:
sudo rm /etc/nginx/conf.d/security.conf
For Apache:
## Edit virtual host and remove Header directives
sudo nano /etc/apache2/sites-available/000-default.conf
4. Test Configuration
sudo nginx -t # For Nginx
## OR
sudo apache2ctl configtest # For Apache
5. Restart Web Server
sudo systemctl start nginx # For Nginx
sudo systemctl status nginx
## OR
sudo systemctl start apache2 # For Apache
sudo systemctl status apache2
6. Verify Rollback
Check that headers are removed:
curl -I http://yourdomain.com | grep -i "security\|frame\|content-security"
Expected: Headers should not be present in the response.
