Security headers

Every web response carries a few headers that cost nothing and close common holes:

header default what it does
X-Content-Type-Options nosniff the browser takes the content type as sent, and does not guess one
Referrer-Policy strict-origin-when-cross-origin other sites see where a visitor came from, not the full address
Content-Security-Policy frame-ancestors 'self' no other site can show your pages in a frame

$padSecurityHeaders in _config/config.php lists the first two, name => value - an empty value leaves one out, [] sends none - and $padCsp is the policy, '' for none. A header the page's own PHP sent stands over the default.

A strict policy and the {nonce} tag

A strict policy refuses inline scripts - which is the point: a script someone smuggled into the page does not run. Your own inline script runs when it carries the request's nonce. Write 'nonce', with the quotes, in the policy, and {nonce} in the script tag; the engine puts the same random value in both, new for every request:

$padCsp = "default-src 'self'; script-src 'self' 'nonce'; frame-ancestors 'self'";
PHP
HTML
fragments/security_headers_1.pad
Result
<script nonce="{nonce}">{ignore}
document.title = 'Hello';
{/ignore}</script>