Security headers are instructions sent from Apache web server to a web browser during communication. They act like additional security settings, telling the browser how to handle certain aspects of the website’s content and resources. This can help mitigate various attack vectors and improve the overall security posture of your web application.
How Security Headers Work in Apache
Security headers operate at the HTTP level, but they’re not part of the main content being transmitted (HTML, images, etc.). They are metadata that guides the browser’s security-related actions.
A user’s browser initiates a request to a web server using the HTTP protocol. The web server responds with the requested content (e.g., web page, images, data), along with various HTTP headers.
During the Request-Response exchange between the user’s browser and the web server, security headers are included within these HTTP response headers. The user’s browser receives and interprets these security headers. The browser adjusts its behavior according to the instructions specified in the security headers, enhancing security measures.
Because security headers work at the HTTP level, they can influence browser behavior and protect against a wide range of web-based attacks. Their effectiveness depends on both the server sending them correctly and the browser’s ability to interpret and implement them.
How to Implement Security Headers in Apache
This involves loading the necessary modules and configuring them in your Apache server. Here’s a step-by-step guide to help you set it up:
Load the Headers Module
First, ensure that the headers
the module is loaded in your Apache configuration. This module is responsible for adding and modifying HTTP headers. Open your Apache configuration file (usually located at:
/etc/apache2/apache2.conf
or /etc/httpd/conf/httpd.conf
), and add or uncomment the following line:
LoadModule headers_module modules/mod_headers.so
If the line is already present but commented out (with a #
at the beginning), remove the #
to enable it.
Restart Apache
After making changes to the configuration, restart Apache to apply the new settings:
sudo service apache2 restart
or
sudo systemctl restart httpd
Add Security Headers
In Apache, the Header
directive is used to set HTTP response headers, including those related to security headers. The Header
directive is very versatile and allows you to control various aspects of HTTP headers.
Here’s a basic syntax for using the Header
directive in Apache to set security headers:
Header always set Header-Name "Header-Value"
Let’s break down the above parameters:
always
: This keyword ensures that the header is set for all responses, regardless of the status code.set
: Indicates that you are setting the value of the specified header.Header-Name
: Replace this with the name of the security header you want to set (e.g.,X-Content-Type-Options
,X-Frame-Options
,X-XSS-Protection
, etc.)."Header-Value"
: Replace this with the desired value for the header.
It’s also possible to add multiple headers in the Apache configuration file as seen below:
<VirtualHost *:80>
# ... other configuration settings ...
# Enable security headers
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-XSS-Protection "1; mode=block"
Header always set Content-Security-Policy "your CSP rules here"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# ... other configuration settings ...
</VirtualHost>
You can replace "your CSP rules here"
with your specific Content Security Policy rules like the following example:
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' https://trusted-scripts.com; img-src 'self' data: https://trusted-images.com;"
In this example:
- default-src ‘self
'
allows resources to be loaded only from the same origin. - script-src ‘self’ https://trusted-scripts.com allows scripts to be loaded from the same origin and from https://trusted-scripts.com.
- img-src ‘self’ data: https://trusted-images.com allows images to be loaded from the same origin,
data
URIs, and https://trusted-images.com.
RECOMMENDED READING: A Beginner’s Guide to Cross-origin Resource Sharing (CORS)
Restart Apache Again
After adding the headers, restart Apache one more time to apply the new configurations.
sudo service apache2 restart
And that’s it! Your Apache server should now be serving your website with the added security headers. Make sure to test your website to confirm that the headers are being applied as expected. You can use online tools like securityheaders.com to analyze your site’s security headers and get recommendations for improvements.
Security headers are crucial for enhancing the security of web applications by preventing common vulnerabilities and attacks. Here are some commonly used security headers:
Content Security Policy (CSP)
Content Security Policy helps prevent Cross-Site Scripting (XSS) attacks by specifying which sources are allowed to load content on a web page.
Cross-site scripting is a type of security vulnerability that occurs when an attacker injects malicious scripts into a web page that is viewed by other users. This can happen when a web application does not properly validate or sanitize user input before rendering it on the page. The injected script then executes within the context of the victim’s browser, allowing the attacker to steal sensitive information, manipulate the appearance of the page, or perform other malicious actions.
To simplify it for you, suppose a website allows users to input comments, and the comments are then displayed on a page. If the website doesn’t properly validate or sanitize the input, an attacker could insert a script in a comment. When other users view the comments, the malicious script runs in their browsers.
Now, Content-Security Policy (CSP) allows developers to define and declare policies that control which resources can be loaded and executed on a page.
Using Content Security Policy in Apache Server
In Apache, you can implement Content Security Policy (CSP) using the Header
directive. The Header
directive allows you to set HTTP headers in the server’s responses, and it can be used to specify the Content Security Policy.
Here’s an example of how you can set a Content Security Policy header using the Header
directive in an Apache configuration file:
Header always set Content-Security-Policy "directive1 value1; directive2 value2; ..."
Replace “directive1 value1; directive2 value2; …” with your desired Content Security Policy directives and their values. For example:
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline';"
This example sets a Content Security Policy that allows content to be loaded only from the same origin ('self'
), and allows inline scripts ('unsafe-inline'
). Please customize the directives based on your specific security requirements.
Remember to restart or reload the Apache server after making changes to the configuration file for the changes to take effect.
Defining Customized Content Security Policies
CSP can be customized based on the specific needs and features of your web application. Regular testing and refinement are crucial to ensure that the policy effectively enhances security without breaking the functionality of your site. Adjustments might be necessary depending on the external resources, libraries, or APIs used by your application.
Here are the examples of the CSP policies to implement:
- Allow content to be loaded only from the same origin (‘self’).
The directive “self” is used to specify that content on a web page should only be loaded from the same origin. The “same origin” refers to the combination of the scheme (http/https), domain, and port of a web page.
Content-Security-Policy: script-src 'self';
With the “self” directive, you are telling the browser to only execute scripts that originate from the same domain, scheme, and port as the web page itself.
If an attacker tries to inject a script from an external domain, the browser will block the execution of that script, as it violates the Content Security Policy.
- Mitigate script injection
When an attacker attempts to inject a script into a vulnerable part of your web application, the CSP policy prevents the injected script from being executed if it does not originate from the same origin. This significantly reduces the risk of attackers injecting malicious scripts that could manipulate the DOM or steal sensitive information.
Here is an example of a CSP policy that restricts script sources and includes additional directives for various types of content:
Content-Security-Policy:
default-src 'self'; // Default source for general content
script-src 'self'; // Allow scripts from the same origin only
style-src 'self' 'unsafe-inline'; // Allow inline styles from the same origin
img-src 'self'; // Allow images from the same origin
font-src 'self'; // Allow fonts from the same origin
object-src 'none'; // Disallow plugins and embedded objects
frame-src 'none'; // Disallow loading content in frames
connect-src 'self'; // Allow AJAX, WebSocket, and other connections from the same origin
form-action 'self'; // Allow form submissions to the same origin
base-uri 'self'; // Restrict the document base URL to the same origin
This example CSP policy includes the following directives:
default-src
: Sets the default source for general content. In this case, it’s restricted to the same origin (‘self’).script-src
: Specifies that scripts should only be allowed from the same origin (‘self’).style-src
: Allows inline styles from the same origin, but also note the use of'unsafe-inline'
. While allowing inline styles may pose a security risk, it’s included here for cases where inline styles are necessary. It’s generally recommended to avoid inline styles if possible.img-src
,font-src
: Specifies that images and fonts should be loaded only from the same origin.object-src
,frame-src
: Disallows plugins, embedded objects, and loading content in frames to enhance security.connect-src
: Controls which URLs the page is allowed to make requests to. In this case, it’s restricted to the same origin.form-action
: Specifies the URLs that can be used as the action of HTML forms. Restricted to the same origin in this example.base-uri
: Restricts the document base URL to the same origin.
- Client-Side Protection
Even if an attacker manages to inject malicious scripts into the web page, the browser will block their execution, protecting users from the harmful effects of the injected scripts.
To implement client-side protection using Content Security Policy (CSP), you can create a policy that restricts the sources from which content, scripts, and other resources can be loaded. The following example CSP policy focuses on enhancing client-side security:
Content-Security-Policy:
default-src 'self'; // Default source for general content
script-src 'self'; // Allow scripts from the same origin only
style-src 'self' 'unsafe-inline'; // Allow inline styles from the same origin
img-src 'self'; // Allow images from the same origin
font-src 'self'; // Allow fonts from the same origin
object-src 'none'; // Disallow plugins and embedded objects
frame-src 'none'; // Disallow loading content in frames
media-src 'self'; // Allow audio and video from the same origin
connect-src 'self'; // Allow AJAX, WebSocket, and other connections from the same origin
form-action 'self'; // Allow form submissions to the same origin
base-uri 'self'; // Restrict the document base URL to the same origin
Strict-Transport-Security (HSTS)
HTTP Strict Transport Security helps protect against man-in-the-middle attacks by enforcing secure (HTTPS) connections.
A Man-in-the-Middle (MitM) attack is a type of cyberattack where an attacker intercepts and possibly alters the communication between two parties without their knowledge. In the context of HTTP (Hypertext Transfer Protocol), which is the foundation of data communication on the World Wide Web, a Man-in-the-Middle attack can occur when an attacker positions themselves between the client (e.g., a web browser) and the server, allowing them to eavesdrop on or manipulate the communication.
The attacker intercepts the communication between the client and the server. This can be achieved through various means, such as sniffing the network traffic or using techniques like DNS spoofing.
The attacker may impersonate either the client or the server, making it appear as though the communication is secure when, in fact, it is being intercepted and manipulated.
The attacker can alter the data being exchanged between the client and the server. This could include injecting malicious code, stealing sensitive information, or modifying the content of the communication.
How Strict-Transport-Security protects against man-in-the-middle attacks
Strict-Transport-Security (HSTS) helps to enforce a security policy mechanism that helps protect websites against man-in-the-middle attacks such as protocol downgrade attacks and cookie hijacking. HSTS allows a web server to declare that it should only be accessed using secure, encrypted connections, and helps to ensure that browsers interact with it over HTTPS (HTTP Secure).
For example, a web server sends an HTTP header with the response, declaring the use of HSTS. This header includes the maximum time the browser should enforce the use of HTTPS for future visits as shown the code below:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
max-age
: Specifies the time, in seconds, that the browser should remember to enforce HTTPS.includeSubDomains
: Indicates that the policy should also be applied to all subdomains.
once the browser receives the HSTS header, it will remember to access the site only over HTTPS for the specified duration. Even if the user manually types “http://” or clicks on an HTTP link, the browser will automatically convert it to “https://” before making the request.
How to implement Strict-Transport-Security (HSTS) in Apache
To implement Strict-Transport-Security (HSTS) in an Apache web server, you can use the Header
directive to send the Strict-Transport-Security
HTTP header. This directive can be added to the Apache configuration file or to an individual virtual host configuration. Here’s how you can do it:
- Edit the Apache Configuration File
Open the Apache configuration file in a text editor. The location of the configuration file depends on your operating system and Apache version. Common locations include /etc/apache2/apache2.conf
or /etc/httpd/conf/httpd.conf
.
.
- Add the HSTS Header
Add the following lines to enable HSTS. This example sets a maximum age of 365 days (31536000
seconds) and includes subdomains:
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</IfModule>
max-age
: Specifies the time, in seconds, that the browser should remember to enforce HTTPS.includeSubDomains
: Indicates that the policy should also be applied to all subdomains. Make sure to wrap theHeader
directive with<IfModule mod_headers.c>
to ensure that it is only processed if themod_headers
module is enabled.
After making changes to the configuration file, restart the Apache web server to apply the changes:
sudo service apache2 restart
or
sudo systemctl restart httpd
Now, your Apache server is configured to send the HSTS header, instructing browsers to enforce HTTPS for a specified duration. Before implementing HSTS in a production environment, it’s crucial to test it thoroughly and ensure that your website and all its subdomains support HTTPS properly.
Keep in mind that once a user visits your site and receives the HSTS header, their browser will remember to access your site via HTTPS for the specified duration. Therefore, be cautious when initially implementing HSTS, especially if your site does not currently support HTTPS or if there are potential issues that need to be addressed.
X-Content-Type-Options
This HTTP header helps to mitigate a type of security vulnerability known as MIME type sniffing or content sniffing. It prevents browsers from interpreting files as a different MIME type than what is declared by the server. MIME type sniffing is a process where browsers attempt to determine the type of content in a file based on its content, rather than relying solely on the MIME type specified by the server.
When a server sends a response, it includes a MIME type declaration in the Content-Type
HTTP header. This declaration specifies the type of content the server intends for the browser to interpret.
In the absence of the X-Content-Type-Options
header or when it is not set to a specific value, some browsers might engage in MIME type sniffing. They analyze the content of the file and may override the declared MIME type if they believe the declared type is incorrect.
So, the X-Content-Type-Options
header allows web servers to explicitly instruct browsers to not perform MIME type sniffing. When the server sets this header with the value nosniff
, it signals to the browser that it should trust the declared MIME type and not try to infer the type based on the file’s content.
X-Content-Type-Options: nosniff
The above directive helps web developers reduce the risk of certain types of attacks, such as those that involve serving a file with a misleading MIME type to exploit browser vulnerabilities.
How to implement X-Content-Type-Options in Apache
To implement the X-Content-Type-Options
header in Apache, you can use the Header
directive, and you can achieve this using any of the following methods:
- Using
.htaccess
file (if allowed)
If you don’t have access to the main Apache configuration files, or if you want to apply this header only to a specific directory, you can use an .htaccess
file. Create a file named .htaccess
in the directory where you want to apply the header, or add the following lines if the file already exists:
<FilesMatch "\.(html|htm|js|json|xml|css)$">
Header set X-Content-Type-Options "nosniff"
</FilesMatch>
This example sets the X-Content-Type-Options
header to nosniff
for files with extensions commonly associated with web content. You can adjust the file extensions in the <FilesMatch>
directive to match the types of files you want to protect.
- Using Apache Configuration File
If you have access to the main Apache configuration files (e.g., httpd.conf
), you can directly add the Header
directive. Open the configuration file and add the following lines:
<FilesMatch "\.(html|htm|js|json|xml|css)$">
Header set X-Content-Type-Options "nosniff"
</FilesMatch>
Make sure to restart or reload Apache after making changes to the configuration files to apply the new settings.
- Using
mod_headers
module
Ensure that the mod_headers
module is enabled. You can enable it by running the following command:
a2enmod headers
Then, you can use the Header
directive in your configuration files:
<FilesMatch "\.(html|htm|js|json|xml|css)$">
Header always set X-Content-Type-Options "nosniff"
</FilesMatch>
The always
keyword ensures that the header is set in all circumstances.
After making these changes, Apache will include the X-Content-Type-Options: nosniff
header in the responses for the specified file types, helping to prevent MIME type sniffing vulnerabilities in supported browsers.
X-Frame-Options
X-Frame-Options
is a security header that can be sent by a web server to instruct the browser on how to handle the embedding of a page in an iframe. It helps prevent clickjacking attacks by controlling whether a browser should be allowed to render a page in a frame.
Clickjacking is a type of attack where a malicious website embeds another website within an iframe, tricking the user into interacting with the embedded content without their knowledge. This can lead to unintended actions being taken on the victim’s behalf.
To prevent clickjacking in an Apache server, you need to add the X-Frame-Options
header to your Apache server configuration.
add_header X-Frame-Options "SAMEORIGIN" always;
The above configuration allows the page to be displayed in a frame or iframe, but only if the request is coming from the same origin (i.e., the same domain).
If a different domain attempts to embed your page using an iframe, the browser will block it.
On the other hand, if you want to deny framing completely, you can use the following line:
Header always append X-Frame-Options DENY
When you set the X-Frame-Options
header to DENY
, you are essentially denying framing completely for your web page. This means that your web page cannot be displayed within a frame or iframe, regardless of the origin (domain) attempting to embed it.
In other words, if a malicious website or any other third-party site tries to embed your web page in a frame or iframe using HTML <iframe>
tags, the browser will refuse to load it. This is a security measure designed to prevent clickjacking attacks, where an attacker tries to trick users into interacting with your web page unknowingly by embedding it within a frame on a malicious site.
After making changes to the configuration file, restart the Apache server to apply the change:
sudo service apache2 restart
X-XSS-Protection
is an HTTP header designed to enable the Cross-Site Scripting (XSS) filter in web browsers. Its purpose is to protect users from malicious script injection attacks like:
X-XSS-Protection
- Stored XSS
Malicious scripts are permanently stored on the target server, and when a user accesses a particular page, the script is executed.
Protection with X-XSS-Protection
: The header helps prevent the execution of stored XSS scripts by blocking the rendering of the entire page when a potential XSS attack is detected.
- Reflected XSS
The attacker tricks a user into clicking on a specially crafted link, and the malicious script is reflected off the server and executed in the victim’s browser.
The header can block the rendering of the page if it detects a reflected XSS attack, protecting the user from executing the malicious script.
- DOM-based XSS
The attack occurs on the client side, manipulating the Document Object Model (DOM) of a web page to execute malicious scripts.
While the header is not specifically designed for DOM-based XSS, it might provide some protection by blocking the rendering of the page when a potential attack is detected.
- Script-Injection Attacks
Injection of malicious scripts into user inputs, such as form fields or URL parameters, leading to the execution of scripts in the context of a web page.
The X-XSS-Protection header helps mitigate script-injection attacks by blocking the rendering of the page when it detects potential XSS attempts.
- Malicious Content in HTML Attributes
Injecting malicious scripts into HTML attributes, such as onclick
or onmouseover
, leading to script execution when the attribute is triggered.
The x-xss-protection header can help prevent the execution of scripts embedded in HTML attributes, thereby protecting against this type of attack.
- Data Theft via Script Injection
Injecting scripts to steal sensitive information, such as login credentials or session tokens, from users.
The X-XSS-Protection header helps in blocking the execution of scripts that attempt to steal sensitive data, providing an additional layer of defense.
How to enforce x-xss-protection at the server server level
To enforce the X-XSS-Protection header in Apache server, you can use the mod_headers
module. This module allows you to manipulate HTTP headers in both the request and response.
Run the following command to enable the mod_headers
module in apache:
sudo a2enmod headers
After enabling the module, restart Apache:
sudo service apache2 restart
You can now edit your Apache configuration file or the virtual host configuration file where you want to enable X-XSS-Protection. This file is often located in the /etc/apache2/sites-available/
directory and has a .conf
extension. Add the following lines to set the X-XSS-Protection header:
<IfModule mod_headers.c>
Header set X-XSS-Protection "1; mode=block"
</IfModule>
This configuration will enable XSS protection in the browser by setting the X-XSS-Protection header to “1; mode=block”.
After making changes to the configuration, restart Apache to apply the new settings:
sudo service apache2 restart
This configuration will instruct the browser to activate its XSS filter to block malicious scripts. The “1; mode=block” parameter tells the browser to enable the XSS filter and block the rendering of the page if a potential XSS attack is detected.
Conclusion
If you want to use all the applicable security headers in apache server, you can simply copy the following configuration that has everything uou need:
<IfModule mod_headers.c>
# Strict-Transport-Security
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
# Content-Security-Policy
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';"
# X-Content-Type-Options
Header always set X-Content-Type-Options "nosniff"
# X-Frame-Options
Header always set X-Frame-Options "DENY"
# X-XSS-Protection
Header always set X-XSS-Protection "1; mode=block"
# Referrer-Policy
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# Feature-Policy
Header always set Feature-Policy "geolocation 'self'; microphone 'none'; camera 'none'"
</IfModule>
Copy and paste the above configuration into your Apache server configuration file. Ensure that the mod_headers
module is enabled in your Apache server. After making these changes, restart or reload your Apache server for the new configurations to take effect.