Clickjacking loads a trusted page inside a misleading or hidden frame so an ordinary click performs an unintended action. Sending an anti-framing policy from Apache stops the browser from rendering that embedded page in the first place, which protects admin panels, checkout flows, and any page that should not accept framed clicks from another site.
Apache adds anti-framing policies as HTTP response headers through mod_headers. Content-Security-Policy with frame-ancestors is the modern control for deciding which origins may embed a page, while X-Frame-Options still covers the simpler DENY and SAMEORIGIN cases for browsers that do not rely on frame-ancestors.
Examples below use the Debian and Ubuntu layout with /etc/apache2/, a2enmod, and the apache2 service name. If an application already sends its own Content-Security-Policy header, merge frame-ancestors into that existing policy instead of emitting a second conflicting header, and use Header always set so the policy is still present on redirects, error pages, and internal rewrites.
$ sudo a2enmod headers Enabling module headers. To activate the new configuration, you need to run: systemctl restart apache2
If the command reports that the module is already enabled, continue with the next step. RHEL-style packages usually ship mod_headers loaded by default instead of using a2enmod.
$ sudoedit /etc/apache2/sites-available/000-default.conf
Use a VirtualHost for site-wide coverage, or a narrower Directory or Location block when only part of the application needs the policy.
<VirtualHost *:80> ServerName host.example.net DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
<VirtualHost *:80> ServerName host.example.net DocumentRoot /var/www/html Header always set Content-Security-Policy "frame-ancestors 'self'" Header always set X-Frame-Options "SAMEORIGIN" ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
Use frame-ancestors 'none' plus X-Frame-Options “DENY” when the site should never appear inside any frame. Use frame-ancestors 'self' plus SAMEORIGIN when same-origin framing is still legitimate, and declare frame-ancestors explicitly because it does not inherit from default-src.
Header always set Content-Security-Policy "frame-ancestors 'self' https://portal.example.net https://admin.example.net"
X-Frame-Options ALLOW-FROM is obsolete and modern browsers ignore it. When third-party origins must frame the page, keep frame-ancestors as the authoritative control and remove any X-Frame-Options value that would contradict that requirement.
$ sudo apache2ctl -t Syntax OK
Debian and Ubuntu expose apache2ctl, while many other distributions use apachectl -t or httpd -t for the same check.
Related: How to test Apache configuration
$ sudo systemctl reload apache2
Use sudo systemctl reload httpd on many RHEL-family systems, or sudo apache2ctl graceful when systemd is not managing the service.
$ curl -I -sS -H 'Host: host.example.net' http://127.0.0.1/ HTTP/1.1 200 OK Date: Thu, 09 Apr 2026 04:39:48 GMT Server: Apache/2.4.58 (Ubuntu) X-Frame-Options: SAMEORIGIN Content-Security-Policy: frame-ancestors 'self' ##### snipped ##### Content-Type: text/html
If a reverse proxy, CDN, or application layer also emits Content-Security-Policy, confirm the final response still contains the intended frame-ancestors rule and does not send a contradictory policy.
$ curl -I -sS -H 'Host: host.example.net' http://127.0.0.1/definitely-not-a-page HTTP/1.1 404 Not Found Date: Thu, 09 Apr 2026 04:39:48 GMT Server: Apache/2.4.58 (Ubuntu) X-Frame-Options: SAMEORIGIN Content-Security-Policy: frame-ancestors 'self' Content-Type: text/html; charset=iso-8859-1
If the 404 or redirect response drops the header, recheck that the configuration uses Header always set instead of Header set.