SkillAgentSearch skills...

SecureHeaders

A PHP library aiming to make the use of browser security features more accessible.

Install / Use

/learn @aidantwoods/SecureHeaders
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

SecureHeaders Build Status Build Status

A PHP class aiming to make the use of browser security features more accessible.

For full documentation, please see the Wiki.

A demonstration with a sample configuration is also available.

What is a 'secure header'?

Secure headers, are a set of headers that configure browser security features. All of these headers can be used in any web application, and most can be deployed without any, or very minor code changes. However some of the most effective ones do require code changes – especially to implement well.

Features

  • Add/remove and manage headers easily
  • Build a Content Security Policy, or combine multiple together
  • Content Security Policy analysis
  • Easy integeration with arbitrary frameworks (take a look at the HttpAdapter)
  • Protect incorrectly set cookies
  • Strict mode
  • Safe mode prevents accidental long-term self-DOS when using HSTS, or HPKP
  • Receive warnings about missing, or misconfigured security headers

Methodology and Philosophy

Error messages are often a great way for a program to tell the programmer that something is wrong. Whether it's calling a variable that's not yet been assigned, or causing a fatal error by exhausting the memory allocation limit.

Both of these situations can usually be rectified very quickly by the programmer. The effort required to do so is greatly reduced because the program communicated exactly what the problem was, as soon as the programmer introduced the bug. SecureHeaders aims to apply this concept to browser security features.

Utilising the error reporting level set within PHP configuration, SecureHeaders will generate E_USER_WARNING and E_USER_NOTICE level error messages to inform the programmer about either misconfigurations or lack of configuration.

In addition to error reporting, SecureHeaders will make some safe proactive changes to certain headers, or even add new ones if they're missing.

Installation

Via Composer

composer require aidantwoods/secureheaders

Other

Download SecureHeaders.phar, then

require_once('SecureHeaders.phar');

Sounds good, but let's see some of the code...

Here is a good implementation example

$headers = new SecureHeaders();
$headers->hsts();
$headers->csp('default', 'self');
$headers->csp('script', 'https://my.cdn.org');
$headers->apply();

These few lines of code will take an application from a grade F, to a grade A on Scott Helme's https://securityheaders.io/

Woah, that was easy! Tell me what it did...

Let's break down the example above.

'Out of the box', SecureHeaders will already do quite a lot (by running the following code)

$headers = new SecureHeaders();
$headers->apply();

Automatic Headers and Errors

With such code, the following will occur:

  • Warnings will be issued (E_USER_WARNING)

    Warning: Missing security header: 'Strict-Transport-Security'

    Warning: Missing security header: 'Content-Security-Policy'

  • The following headers will be automatically added

    Expect-CT: max-age=0
    Referrer-Policy: no-referrer
    Referrer-Policy: strict-origin-when-cross-origin
    X-Content-Type-Options:nosniff
    X-Frame-Options:Deny
    X-Permitted-Cross-Domain-Policies: none
    X-XSS-Protection:1; mode=block
    
  • The following header will also be removed (SecureHeaders will also attempt to remove the Server header, though it is unlikely this header will be under PHP jurisdiction)

    X-Powered-By
    

Cookies

Additionally, if any cookies have been set (at any time before ->apply() is called) e.g.

setcookie('auth', 'supersecretauthenticationstring');

$headers = new SecureHeaders();
$headers->apply();

Even though in the current PHP configuration, cookie flags Secure and HTTPOnly do not default to on, and despite the fact that PHP does not support the SameSite cookie attribute, the end result of the Set-Cookie header will be

Set-Cookie:auth=supersecretauthenticationstring; Secure; HttpOnly; SameSite=Lax

These flags were inserted by SecureHeaders because the cookie name contained the substring auth. Of course if that was a bad assumption, you can correct SecureHeaders' behaviour, or conversely you can tell SecureHeaders about some of your cookies that have less obvious names – but may need protecting in case of accidental missing flags.

If you enable ->strictMode() then the SameSite setting will be set to strict (you can also upgrade this without using strict mode).

Strict Mode

Strict mode will enable settings that you should be using. It is highly advisable to adjust your application to work with strict mode enabled.

When enabled, strict mode will:

  • Auto-enable HSTS with a 1 year duration, and the includeSubDomains and preload flags set. Note that this HSTS policy is made as a header proposal, and can thus be removed or modified.

  • The source keyword 'strict-dynamic' will also be added to the first of the following directives that exist: script-src, default-src; only if that directive also contains a nonce or hash source value, and not otherwise.

    This will disable the source whitelist in script-src in CSP3 compliant browsers. The use of whitelists in script-src is considered not to be an ideal practice, because they are often trivial to bypass.

    Don't forget to manually submit your domain to the HSTS preload list if you are using this option.

  • The default SameSite value injected into ->protectedCookie will be changed from SameSite=Lax to SameSite=Strict. See documentation on ->auto to enable/disable injection of SameSite and documentation on ->sameSiteCookies for more on specific behaviour and to explicitly define this value manually, to override the default.

  • Auto-enable Expect-CT with a 1 year duration, and the enforce flag set. Note that this Expect-CT policy is made as a header proposal, and can thus be removed or modified.

Back to the example

Let's take a look at those other three lines, the first of which was

$headers->hsts();

This enabled HSTS (Strict-Transport-Security) on the application for a duration of 1 year.

That sounds like something that might break things – I wouldn't want to accidentally enable that.

Safe Mode

Okay, SecureHeaders has got you covered – use $headers->safeMode(); to prevent headers being sent that will cause lasting effects.

So for example, if the following code was run (safe mode can be called at any point before ->apply() to be effective)

$headers->hsts();
$headers->safeMode();

HSTS would still be enabled (as asked), but would be limited to lasting 24 hours.

SecureHeaders would also generate the following notice

Notice: HSTS settings were overridden because Safe-Mode is enabled. Read about some common mistakes when setting HSTS via copy/paste, and ensure you understand the details and possible side effects of this security feature before using it.

What if I set it via a method not related to SecureHeaders? Can SecureHeaders still enforce safe mode?

Yup! SecureHeaders will look at the names and values of headers independently of its own built in functions that can be used to generate them.

For example, if I use PHPs built in header function to set HSTS for 1 year, for all subdomains, and indicate consent to preload that rule into major browsers, and then (before or after setting that header) enable safe-mode...

header('Strict-Transport-Security: max-age=31536000; includeSubDomains; preload');
$headers->safeMode();

The same above notice will be generated, max-age will be modified to 1 day, and the preload and includesubdomains flags will be removed.

Content Security Policy

The final two lines to cover from the initial example are as follows

$headers->csp('default', 'self');
$headers->csp('script', 'https://my.cdn.org');

These tell SecureHeaders that it should build a CSP (Content Security Policy) that allows default assets to be loaded from the current domain (self), and that scripts should be allowed from https://my.cdn.org.

Note that if we had said http://my.cdn.org instead, then the following would have been generated

Warning: Content Security Policy contains the insecure protocol HTTP in a source value http://my.cdn.org; this can allow anyone to insert elements covered by the script-src directive into the page.

Similarly, if wildcards such as 'unsafe-inline', https:, or * are included – SecureHeaders will generate warnings to highlight these CSP bypasses.

Note that the ->csp function is very diverse in what it will accept, to see some more on that take a look at Using CSP

Sending the headers

In order to apply anything added through SecureHeaders, you'll need to call ->apply(). By design, SecureHeaders doesn't have a construct function – so everything up until ->apply() is called is just configuration. However, if you don't want to have to remember to call this function, you can call ->applyOnOutput() instead, at any time. Thi

View on GitHub
GitHub Stars433
CategoryContent
Updated12d ago
Forks21

Languages

PHP

Security Score

100/100

Audited on Mar 17, 2026

No findings