/ Security Audit Fixes / Plesk

How to Fix Security Headers in Plesk

Plesk Obsidian is one of the most common control panels for managed Linux servers. It also leaks the most fingerprint information by default — the X-Powered-By: PleskLin header is hardcoded into Plesk's nginx config generator. This guide walks through every fix our Security Audit raises on a Plesk-hosted site: removing X-Powered-By permanently, adding the six recommended HTTP security headers, configuring TLS protocols and publishing security.txt. Tested against Plesk Obsidian 18.0.77 on Ubuntu 24.04.

1. Remove the X-Powered-By: PleskLin header

This is the most common Plesk finding. Plesk auto-generates nginx.conf for every domain and injects add_header X-Powered-By PleskLin; at the server level. The fix is a one-line change to Plesk's global panel.ini followed by a config rebuild — fully supported by Plesk and survives all future regenerations.

Step 1
Edit panel.ini via SSH
SSH into your Plesk server as root and edit the panel.ini file. On modern Plesk installs the path is /usr/local/psa/admin/conf/panel.ini (with a symlink at /opt/psa/admin/conf/panel.ini). Open with your preferred editor:
nano /usr/local/psa/admin/conf/panel.ini
Add the following two lines at the end of the file:
[webserver]
xPoweredByHeader = off
Save and exit.
Step 2
Rebuild webserver configuration
Trigger Plesk to regenerate all nginx configs with the new setting applied:
plesk repair web -y
You should see lines confirming the repair, ending with Error messages: 0; Warnings: 0. If you prefer the UI, the same action is available at Tools & Settings → Diagnose & Repair → Repair Web.
Step 3
Verify the fix
Confirm the header is gone with curl:
curl -sI https://yourdomain.com/ | grep -iE "x-powered-by|server"
You should see only server: nginx — no x-powered-by line at all. Then re-run the Security Audit on your domain to confirm the check now passes.
💡 The panel.ini setting is server-wide — it removes X-Powered-By from every domain hosted on this Plesk server in one step. There is no per-domain version of this setting.

2. Add the six HTTP security headers

The six headers our audit checks (CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy) can all be added through Plesk's Additional nginx directives field, per-domain. This field is preserved across Plesk regenerations and panel updates.

Step 1
Open the Additional nginx directives field
In Plesk, navigate to: Domains → yourdomain.com → Hosting & DNS → Apache & nginx Settings. Scroll down to the "Additional nginx directives" text area.
Step 2
Paste the six directives
Paste the following block, then click OK:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" 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 "geolocation=(), microphone=(), camera=()" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; frame-ancestors 'self'" always;
Plesk validates the syntax. If you get a config error, the most common cause is unbalanced quotes — copy-paste exactly as above.
⚠️ The Content-Security-Policy above is a sensible default but may block legitimate third-party scripts (analytics, embedded video, advertising). Test thoroughly. Start with Google's CSP Evaluator if you need to loosen it.
⚠️ Only add preload to your HSTS header AFTER testing — submitting to the HSTS preload list is hard to undo. For a first deployment, omit preload and use just max-age=31536000; includeSubDomains.

3. Configure modern TLS protocols

Plesk uses sensible TLS defaults on modern installs (TLS 1.2 and 1.3 enabled, older protocols disabled) but on legacy upgraded servers you may still have TLS 1.0 or 1.1 enabled. Check and disable them.

UI path
Tools & Settings → Security → SSL/TLS
Find the "Enable support of the following protocols" section. Check only TLS 1.2 and TLS 1.3. Uncheck SSLv2, SSLv3, TLS 1.0 and TLS 1.1. Save.
Or via CLI
For nginx specifically
Add to your Additional nginx directives:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384";

4. Publish security.txt (RFC 9116)

security.txt tells researchers how to report vulnerabilities. Plesk does not have UI support for this — you create the file directly in your document root.

Step 1
Create the file
Via SSH (or via Plesk's File Manager), create httpdocs/.well-known/security.txt with this content (replace the email and date):
Contact: mailto:security@yourdomain.com
Expires: 2027-12-31T23:59:59.000Z
Preferred-Languages: en
Canonical: https://yourdomain.com/.well-known/security.txt
The Expires field must be no more than one year in the future per RFC 9116.
Step 2
Force text/plain Content-Type
By default nginx may serve security.txt with a default JSON content-type (because of the .well-known/ directory rules in Plesk's templates). Force the right type by adding to your Additional nginx directives:
location = /.well-known/security.txt {
    default_type "text/plain; charset=utf-8";
    add_header Content-Type "text/plain; charset=utf-8" always;
}

5. Cookie security flags

Cookie flags (Secure, HttpOnly, SameSite) must be set by whatever application sets the cookies — Plesk cannot add them on cookies it did not create. For most Plesk-hosted sites this means your CMS or application code.

6. Remove CMS version exposure

If your audit shows "CMS not exposing version: WARN", that finding is from your application not Plesk. Plesk itself does not add a <meta name="generator"> tag. For WordPress, follow the WordPress fix guide.

7. Mail security DNS (SPF, DMARC, DKIM)

Plesk has built-in support for managing SPF, DMARC and DKIM via the Mail tab on each domain, even if you do not use Plesk's mail server. Even if you delegate email to Google Workspace or Microsoft 365, publishing these records on your domain in Plesk's DNS settings prevents your domain from being spoofed.

UI path
Domains → yourdomain.com → Mail → Mail Settings
Enable SPF, DKIM and DMARC. Plesk will publish the relevant TXT records to your DNS zone. If you use external email, use the SPF and DKIM values your email provider gave you instead of Plesk's defaults.

Frequently Asked Questions

Will the panel.ini fix wipe out any other configuration?
No. The xPoweredByHeader = off setting only affects the X-Powered-By header injection. All your other Plesk settings, domain configurations, SSL certificates and email configurations are preserved. The plesk repair web step rebuilds webserver configs but does not touch panel-level settings.
Why does my Additional nginx directives field show a syntax error?
Plesk validates nginx syntax when you save. Common causes: missing semicolons, unbalanced quotes (especially in CSP directives that contain single quotes), or trying to use directives Plesk doesn't allow at the location level. If you get an error, paste smaller blocks at a time to narrow down which directive is the problem.
Do these changes affect Plesk's own admin panel security?
No. Per-domain Additional nginx directives apply only to that domain's public-facing site. Plesk's admin panel runs on a different port (8443) with its own nginx config. To harden the panel itself, use Tools & Settings → Web Server Settings, but those changes are separate from the per-domain hardening this guide covers.
My Plesk version is older — does this still work?
The panel.ini xPoweredByHeader = off setting has been available since Plesk Onyx (Plesk 17). Additional nginx directives have been available since Plesk 12. If you are on a much older Plesk version, your priority should be upgrading — older Plesk versions ship with older nginx and OpenSSL versions that have their own security issues.
I am on Plesk Web Host edition — do the steps differ?
No. The fixes in this guide work identically across Plesk Web Admin, Web Pro and Web Host editions. The panel.ini location, repair commands and Additional nginx directives field are present in all editions.

🛡 Re-run the audit when you're done

After applying these fixes, run the Security Audit again to confirm your score has improved. Each fix should move you closer to 100/100.

Run free security audit →
Related Guides: All Fix Guides  ·  Fix Headers in WordPress  ·  Security Audit Guide  ·  Expert Reference
💬 Got a problem?