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.

  1. 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.conf
    

    Caution: Test your CSP thoroughly to avoid breaking functionality.

  2. 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.conf
    
  3. X-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.conf
    
  4. X-XSS-Protection (Legacy/Deprecated): This header was intended to enable the browser’s built-in XSS auditor.

    Deprecated: X-XSS-Protection has 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. Use Content-Security-Policy instead — 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.conf
    
  5. Strict-Transport-Security (HSTS): Enforce secure connections to your server.

    echo "add_header Strict-Transport-Security \"max-age=31536000; includeSubDomains;\";" >> /etc/nginx/conf.d/security.conf
    

    Caution: 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.

  1. 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.conf
    

    Caution: Be careful when defining sources; overly permissive policies can expose your application to risks.

  2. 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.conf
    

    Safe Default: Always set this header to nosniff.

  3. 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.conf
    

    Caution: Setting it to SAMEORIGIN allows your site to be framed by pages on the same origin, which may be acceptable in some cases.

  4. 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.conf
    

    Caution: Once HSTS is enabled, it cannot be easily undone. Ensure your site is fully HTTPS before applying this header.

  5. 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.

  1. 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.conf
    
  2. Add 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.

  3. 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 module
    
  4. Restart Apache: After making changes, restart the Apache service to apply the new configuration.

    sudo systemctl restart apache2  # Restart Apache
    
  5. Test 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:

  1. Edit Nginx Configuration: Open your Nginx configuration file:

    sudo nano /etc/nginx/sites-available/default
    
  2. Add 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;
        }
    }
    
  3. Test Configuration: Always test your Nginx configuration before reloading:

    sudo nginx -t  # Test configuration
    
  4. Reload 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:

  1. securityheaders.com: Enter your domain to get a detailed report
  2. Mozilla Observatory: Provides comprehensive security analysis
  3. 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:

  1. Module is Enabled (Apache):

    apache2ctl -M | grep headers  # Verify headers module is loaded
    
  2. Configuration Syntax (Nginx):

    sudo nginx -t  # Test configuration
    
  3. Virtual Host Configuration: Ensure headers are in the correct server block or virtual host.

CSP Breaking Functionality

If Content Security Policy blocks legitimate resources:

  1. Check Browser Console: Look for CSP violation reports

  2. Use Report-Only Mode:

    add_header Content-Security-Policy-Report-Only "default-src 'self';" always;
    
  3. Gradually Tighten Policy: Start permissive and restrict incrementally

HSTS Preventing HTTP Access

If HSTS causes issues:

  1. Clear Browser HSTS Cache: In Chrome, visit chrome://net-internals/#hsts

  2. 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"
  • 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.