3. Global Configuration and core plugins
A handful of settings in System → Global Configuration and the System - HTTP Headers plugin carry most of the weight. All values below were applied and checked on the test site.
|
Setting |
Where |
Recommended |
Tested result |
|---|---|---|---|
|
Force HTTPS |
Global Config → Server |
Entire Site |
HTTP request → |
|
Debug System |
Global Config → System |
No |
With debug on, an error page exposed a call stack. Off: no stack or paths. |
|
Error Reporting |
Global Config → Server |
None (production) |
With Default, None and debug off, no server paths leaked on the error page tested. |
|
Behind Load Balancer |
Global Config → Server |
No, unless a real proxy is in front |
See warning below. |
|
Session Lifetime |
Global Config → System |
15 minutes (default) |
Keep short for admin sessions. |
|
HSTS |
System - HTTP Headers plugin |
On, max-age 31536000 |
|
|
X-Frame-Options, Referrer-Policy, COOP |
System - HTTP Headers plugin |
Defaults (on) |
|
|
Extra headers |
System - HTTP Headers → Additional headers |
|
Sent on site and admin when the client is set to Both. |
Warning on "Behind Load Balancer". This setting tells Joomla to trust the X-Forwarded-For header. In testing, with it switched on and no proxy present, a failed login sent with a forged X-Forwarded-For: 198.51.100.23 was logged under 198.51.100.23, not the real client IP. With it off, the real IP was logged regardless of the header. An attacker can use this to dodge IP-based blocking (see section 7) or get innocent IPs banned. Turn it on only when every request really arrives through your proxy.
Enable HSTS only after HTTPS works everywhere on the domain, including subdomains if you tick include subdomains. Browsers remember it for the full max-age.
A Content-Security-Policy is the strongest header but the most likely to break a site. CSP is off by default in the plugin; when you switch it on, it starts in report-only mode. Leave it there until reports show no legitimate violations, then enforce it.
