HTTPS Is Not Enough: The Other Security Layers Your Hosting Stack Needs

Written by:

·

Last Updated on:

·

HostingGuider uses affiliate links. We may earn a commission if you purchase through them, at no extra cost to you.

Having HTTPS on your site is good. It is also the most misunderstood security measure in web hosting.

HTTPS encrypts the connection between a visitor’s browser and your server. Traffic on the network cannot be read by a third party watching the connection. The padlock appears. Visitors feel safe.

That encryption does nothing to protect the server itself. A site running HTTPS with no firewall, no rate limiting, no security headers, and a publicly exposed database is not a secure site. It is a site where the attack traffic arrives encrypted.

This article covers the specific security layers that HTTPS does not provide and how to add each one.

Key Takeaways

  • HTTPS protects data in transit between browser and server, nothing more
  • SQL injection, XSS, brute force, and DDoS all work exactly the same over HTTPS as they do over HTTP
  • Security headers sent alongside HTTPS responses protect against attack classes that TLS cannot address
  • Correct TLS configuration matters separately from simply having a certificate
  • Database, email, and server-side security each require independent configuration
  • A free tool like Mozilla Observatory scores all your security headers in under 30 seconds

What HTTPS Actually Does

HTTPS establishes an encrypted channel between the browser and the server using TLS. When a visitor requests your site over HTTPS, the exchange works like this:

  1. The browser and server negotiate which TLS version and cipher suite to use
  2. The server presents its SSL certificate for the browser to verify
  3. Both sides establish a shared encryption key
  4. All subsequent traffic for this session is encrypted

HTTPS protects against eavesdropping on the network and against a man-in-the-middle substituting content while traffic is in transit. These are real and important protections.

What HTTPS does not touch:

The content being served. A server can serve malware-infected pages over HTTPS with a valid certificate. The malware is just delivered more privately.

Server-side attacks. A SQL injection attack carried in a POST request arrives at the database as a properly formatted query whether the transport was HTTP or HTTPS.

Brute force attempts. An attacker trying 10,000 password combinations at your login page sends each request over an encrypted connection. The encryption does not limit how many attempts can be made.

What happens after the request reaches your server. HTTPS terminates at the server. Beyond that point, security depends entirely on server configuration, application code, and the other layers below.

Layer 1: HTTP Security Headers

Security headers are instructions the server sends alongside page responses. They tell browsers how to handle the page content, which resources to trust, and what protections to enforce. HTTPS enables the transport. Security headers define the security rules the browser must follow after receiving the content.

The headers most sites are missing:

Content-Security-Policy (CSP)

CSP tells the browser exactly which sources are allowed to load scripts, stylesheets, images, and frames on your page. A tight CSP eliminates most cross-site scripting attacks because even if an attacker injects a script tag, the browser will refuse to execute it if the source is not in the approved list.

A basic CSP for a WordPress site:

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-RANDOM_NONCE'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; frame-ancestors 'self';

WordPress with inline scripts and multiple external plugins often requires a more permissive starting point. Begin with Report-Only mode to collect violations before enforcing:

Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report;

This logs violations without blocking anything. Review the reports for a week before switching to enforcement mode.

X-Frame-Options

This header prevents your site from being embedded in an iframe on another domain. Clickjacking attacks embed your login page in a transparent iframe over a different page and trick users into clicking your buttons without knowing.

X-Frame-Options: SAMEORIGIN

SAMEORIGIN allows iframes from your own domain but blocks them from external sites.

X-Content-Type-Options

This header prevents browsers from guessing the MIME type of a response differently from what the server declared. Without this header, a browser might execute a file that the server sent as text/plain if the browser decides it looks like JavaScript.

X-Content-Type-Options: nosniff

Referrer-Policy

This controls how much referrer information is sent when a visitor follows a link from your site to another. Without it, the full URL including any session tokens in the query string is sent to external sites.

Referrer-Policy: strict-origin-when-cross-origin

Permissions-Policy

This header controls which browser features the page can use. Blocking camera, microphone, and geolocation for pages that do not need them reduces what a compromised script can do.

Permissions-Policy: camera=(), microphone=(), geolocation=()

Strict-Transport-Security (HSTS)

HSTS tells browsers to always use HTTPS for your domain, even if a link or redirect uses HTTP. This prevents protocol downgrade attacks.

Strict-Transport-Security: max-age=31536000; includeSubDomains

Only enable HSTS after confirming HTTPS works correctly across all subdomains. Once set, browsers enforce it strictly for the duration of the max-age.

Adding headers in Nginx:

add_header Content-Security-Policy "default-src 'self'" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

The always directive ensures these headers are sent even on error responses, not just successful ones.

Test your current headers:

Visit Mozilla Observatory and enter your domain. The scan grades your security headers and shows exactly which ones are missing or incorrectly configured. A site with only HTTPS and no security headers typically scores an F.

Layer 2: Correct TLS Configuration

Having a certificate is not the same as having a secure TLS configuration. The default settings on many servers allow protocol versions and cipher suites that have known vulnerabilities.

What to disable:

TLS 1.0 and TLS 1.1 are outdated protocol versions with known weaknesses. They should not be offered by any production server.

ssl_protocols TLSv1.2 TLSv1.3;

Weak cipher suites like RC4, 3DES, and export-grade ciphers should be removed from the allowed list.

ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

Session tickets and forward secrecy:

ssl_session_tickets off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;

Disabling session tickets prevents an attacker who later obtains the server key from decrypting previously captured sessions.

Test your TLS configuration:

Run your domain through SSL Labs. An A rating requires TLS 1.2 or higher only, strong ciphers, and no known vulnerabilities. The test also flags certificate chain issues, HSTS status, and HTTP/2 support.

The relationship between TLS versions and protocol improvements like HTTP/3 is covered in more detail in the QUIC and HTTP/3 guide, which also explains why TLS 1.3 improves both security and connection speed simultaneously.

Layer 3: Web Application Firewall

HTTPS carries attack payloads just as efficiently as HTTP. SQL injection strings, cross-site scripting payloads, and remote code execution attempts arrive at the application layer regardless of transport encryption.

A WAF inspects the content of requests and blocks those matching known attack patterns. It runs before the application processes the request.

A server without a WAF passes everything to the application and trusts the application to handle malicious input safely. This is a high-trust assumption that plugin-heavy WordPress installations rarely justify.

Configure a WAF at the Cloudflare level (handled before the request reaches the server) or at the web server level with ModSecurity. The web application firewall layers involved and how they work together determine what gets blocked and at what cost in server resources.

At minimum, add these Nginx rules to block common attack patterns without a full WAF:

# Block common injection attempts in query strings
if ($query_string ~* "union.*select|insert.*into|drop.*table") {
    return 403;
}

# Block script injection attempts in query strings
if ($query_string ~* "<script|javascript:|vbscript:") {
    return 403;
}

# Block requests with suspicious user agents
if ($http_user_agent ~* "sqlmap|nikto|nmap|w3af|havij") {
    return 403;
}

These are not a substitute for a proper WAF but they block automated scanning tools that run common attack patterns.

Layer 4: Brute Force and Rate Limiting

A login page accessible over HTTPS is still accessible to automated tools making thousands of attempts per minute. The encryption protects the credentials being transmitted. It does not limit how many times the transmission can occur.

Nginx rate limiting at the server level:

# Define a rate limit zone
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

# Apply to the login endpoint
location = /wp-login.php {
    limit_req zone=login burst=3 nodelay;
    limit_req_status 429;
    # rest of config
}

This allows five requests per minute to the login page per IP address. An automated tool making 1,000 attempts per minute gets a 429 response for 999 of them.

Also apply rate limiting to the WordPress REST API if you do not use it heavily:

limit_req_zone $binary_remote_addr zone=api:10m rate=30r/m;

location /wp-json/ {
    limit_req zone=api burst=10 nodelay;
}

Combine server-level rate limiting with Cloudflare’s rate limiting rules for protection at the edge before traffic reaches the server.

Layer 5: Database Security

HTTPS encrypts the connection between browser and server. The connection between your server and its database is a completely separate channel that HTTPS does not touch.

Common database security failures that HTTPS cannot prevent:

Database listening on a public IP. If MySQL binds to 0.0.0.0 instead of 127.0.0.1, it accepts connections from the internet. HTTPS has no visibility into this.

Verify MySQL is listening only on localhost:

mysql -e "SHOW VARIABLES LIKE 'bind_address';"

The result should show 127.0.0.1 or localhost. If it shows 0.0.0.0, update /etc/mysql/mysql.conf.d/mysqld.cnf:

bind-address = 127.0.0.1

Overprivileged database users. The WordPress database user should have only the privileges it needs. It does not need SUPER, FILE, or DROP privileges for normal WordPress operation.

Review current privileges:

mysql -e "SHOW GRANTS FOR 'wp_user'@'localhost';"

Revoke unnecessary privileges:

REVOKE SUPER, FILE ON *.* FROM 'wp_user'@'localhost';
FLUSH PRIVILEGES;

Weak database credentials. The database password should be as strong as any other password. A 32-character random password costs nothing extra and dramatically raises the cost of credential-based attacks.

HTTPS enables the Secure flag on cookies, which tells the browser to only transmit the cookie over HTTPS connections. But simply having HTTPS does not automatically set this flag. The application must explicitly set it.

WordPress session cookies should have both Secure and HttpOnly flags. The HttpOnly flag prevents JavaScript from reading the cookie, which stops a class of cross-site scripting attacks from stealing session tokens.

Add to wp-config.php:

define('COOKIEPATH', '/');
define('SITECOOKIEPATH', '/');

In php.ini or .user.ini, configure session cookie security:

session.cookie_secure = On
session.cookie_httponly = On
session.cookie_samesite = Strict

The SameSite=Strict attribute prevents the cookie from being sent on cross-site requests, blocking a category of cross-site request forgery attacks at the cookie level.

Layer 7: Email Authentication

HTTPS protects web traffic. Email is a completely separate system with its own trust model that HTTPS does not address.

Without email authentication records in DNS, anyone can send email that appears to come from your domain. Attackers spoof your domain to send phishing emails to your customers. Email providers increasingly reject or spam-filter email from domains without authentication records.

Three DNS records secure your email:

SPF (Sender Policy Framework) declares which mail servers are authorised to send email from your domain.

v=spf1 include:mail.yourhost.com ~all

Add as a TXT record in your DNS with the IP addresses or mail server names authorised to send on behalf of your domain.

DKIM (DomainKeys Identified Mail) adds a cryptographic signature to outgoing email that receiving servers can verify.

Your email service provider gives you a DKIM public key to add as a DNS TXT record. The private key signs outgoing messages. Receivers verify the signature against the DNS record.

DMARC (Domain-based Message Authentication, Reporting and Conformance) specifies what to do with messages that fail SPF or DKIM checks and where to send reports.

v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com; pct=100;

Start with p=none to receive reports without rejecting any email, then move to p=quarantine or p=reject after reviewing the reports to confirm legitimate email is passing.

Check your current email authentication at MXToolbox by entering your domain and running the DMARC, SPF, and DKIM lookups.

Layer 8: Server-Level Hardening

HTTPS says nothing about how the underlying server is configured. Several server-level settings affect security independent of what the application does.

Hide server version information:

# Nginx
server_tokens off;

# Apache
ServerTokens Prod
ServerSignature Off

Exposing the server and version number helps attackers identify which CVEs apply to your specific setup.

Restrict HTTP methods:

Most web applications only need GET, POST, and occasionally PUT. Methods like TRACE, DELETE, and CONNECT can expose information or enable request smuggling attacks.

if ($request_method !~ ^(GET|HEAD|POST)$ ) {
    return 405;
}

Block access to sensitive files:

location ~* \.(htaccess|htpasswd|env|git|log|sql|bak|config)$ {
    deny all;
    return 404;
}

Firewall incoming traffic:

HTTPS does not restrict which ports are open. A firewall at the OS level should allow only port 22 (SSH), 80 (HTTP for redirect), and 443 (HTTPS) for incoming public traffic. Everything else should be blocked.

sudo ufw default deny incoming
sudo ufw allow 22
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable

DDoS protection at the hosting level adds another dimension: even a correctly configured server can be taken offline by volume attacks that bypass application-layer controls entirely.

Checking Your Current Security Posture

Three tools give you a comprehensive picture of what is missing:

Mozilla Observatory at observatory.mozilla.org grades HTTP security headers and TLS configuration in one scan. Run it first because it catches the most common missing layers.

SSL Labs at ssllabs.com/ssltest grades your TLS configuration specifically. An A rating requires TLS 1.2 or higher only, strong ciphers, and no protocol-level vulnerabilities.

SecurityHeaders.com at securityheaders.com provides a separate header grading focused on the browser-enforced security policies.

Run all three before making changes. Note what each flags. Work through the findings in order of severity. The majority of sites score well below their potential on all three tools with changes that take under an hour to implement.

Frequently Asked Questions

Does having an SSL certificate from a CA guarantee my site is secure?

An SSL certificate from a Certificate Authority confirms that the server presenting the certificate legitimately controls the domain. It does not confirm anything about the security of the application running on that server, the server configuration, or the data practices of the site owner. A phishing site can have a valid SSL certificate. The padlock confirms the connection is encrypted, not that the destination is trustworthy.

What is the fastest security improvement after adding HTTPS?

Adding the five core security headers takes about 15 minutes in Nginx and immediately improves protection against clickjacking (X-Frame-Options), MIME sniffing (X-Content-Type-Options), and protocol downgrade attacks (HSTS). These headers require no changes to the application and have no compatibility risk for visitors. The Mozilla Observatory score typically jumps from F to B or A with these headers added.

Do managed WordPress hosts handle these layers automatically?

The better managed hosts configure several of these layers by default. Kinsta includes Cloudflare Enterprise WAF, security headers, and hardened Nginx configurations as part of the platform. Cloudways includes server-level firewall configuration and security monitoring. However, layers that depend on application code (CSP with proper nonces, email authentication records, WordPress-level cookie settings) require action by the site owner regardless of the hosting platform. Always verify with your provider which layers they configure and which remain your responsibility.

Why do security headers sometimes break site functionality?

Content-Security-Policy is the most common cause. A strict CSP that blocks all inline scripts will break WordPress admin functionality, page builders, and many plugins that rely on inline JavaScript. The fix is not to abandon CSP but to implement it incrementally using the Report-Only header first, collect violations for a week, then build a policy that allows legitimate sources while blocking unknown ones. X-Frame-Options can break intentional embeds. Adding exceptions or using ALLOW-FROM uri where needed resolves this.

How does rate limiting interact with legitimate high-traffic events?

A rate limit of five login attempts per minute per IP is appropriate for humans and will never affect legitimate traffic. Legitimate users attempting to log in do not make hundreds of requests per minute. The limit frustrates automated tools and is invisible to real visitors. For general page traffic, set rate limits well above your typical per-IP request rate. A visitor browsing your site might make 20-30 requests per minute across images, scripts, and pages. A rate limit of 100 requests per minute per IP blocks volumetric attacks while being invisible to any real visitor.

About The Author

Hostinger

4.7/5 (62k)
Claim 88% OFF Now

Liquid Web

4.3/5 (2.6k)
Claim 50% OFF Now

WP Engine

4.3/5 (1.6k)
Claim 33% OFF Now