xp-forge / frontend

Web frontends
1 stars 1 forks source link

Implement default security policies #31

Closed thekid closed 1 year ago

thekid commented 1 year ago

What this pull request does

Implements #30 and sets X-Content-Type-Options, X-Frame-Options, Referrer-Policy to sensible default values and allows specifying a Content-Security-Policy (including Report-Only mode).

use web\frontend\{Frontend, Security};

$frontend= (new Frontend($delegates, $templates))
  ->enacting((new Security())
    ->framing('SAMEORIGIN')       // X-Frame-Options, defaults to "DENY"
    ->referrers('strict-origin')  // Referrer-Policy, defaults to "no-referrer-when-downgrade"
    ->csp([                       // Content-Security-Policy, defaults to none
      'default-src' => "'none'",
      'script-src'  => "'self' 'nonce-{{nonce}}' https://example.com",
      // etcetera
    ])
  )
;

CSP

Content Security Policy is quite specific to what you are doing on your site, so no default value is supplied. However, using default-src 'self'; script-src 'self' 'nonce-{{nonce}}'; style-src 'self' 'nonce-{{nonce}}; img-src 'self' https: and then supplying nonce attributes on your <script> and <style> tags is maybe a good starting point as well as replacing on...-attributes with addEventListener().

If we introduce a default CSP, this would be done in a separate major release!

See also https://content-security-policy.com/, https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP and https://scotthelme.co.uk/content-security-policy-an-introduction/

Example

With no code changed (that is, just using the defaults), the rating from https://securityheaders.com/ changes as follows:

Before

Screenshot of rating before

After

Screenshot of rating after

If we were to define a content security policy, we could get an A rating.

BC break

This pull request doesn't break any code, but site's behavior will be different:

thekid commented 1 year ago

Released in https://github.com/xp-forge/frontend/releases/tag/v4.0.0

thekid commented 1 year ago

Hrm - Chromium devtools says this:

The 'X-Frame-Options' header should not be used. A similar effect, with more consistent support and stronger checks, can be achieved with the 'Content-Security-Policy' header and 'frame-ancestors' directive.

Would https://securityheaders.com/ recognize this as replacement too? Need to try this out...