PHPackages                             spaze/csp-config - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. spaze/csp-config

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

spaze/csp-config
================

Build Content Security Policy from a config file

v4.2.0(5mo ago)143.3k2MITPHPPHP ^8.3CI passing

Since Apr 2Pushed 5mo ago3 watchersCompare

[ Source](https://github.com/spaze/csp-config)[ Packagist](https://packagist.org/packages/spaze/csp-config)[ RSS](/packages/spaze-csp-config/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (10)Versions (20)Used By (0)

csp-config
==========

[](#csp-config)

Build Content Security Policy from a config file. Supports different policy per page or module, and snippets you can add dynamically, if needed.

[![PHP Tests](https://github.com/spaze/csp-config/workflows/PHP%20Tests/badge.svg)](https://github.com/spaze/csp-config/actions?query=workflow%3A%22PHP+Tests%22)

The library is designed to be usable with any framework (or without one) but comes with a bridge for [Nette Framework](https://nette.org/).

> Please note that this library will only build the header value and you still need to send the header yourself!

Installation
------------

[](#installation)

The best way to install the library is using [Composer](https://getcomposer.org/):

```
composer require spaze/csp-config
```

Nette Framework configuration
-----------------------------

[](#nette-framework-configuration)

If you're using Nette Framework you can add the extension to your config file:

```
extensions:
    contentSecurityPolicy: Spaze\ContentSecurityPolicy\Bridges\Nette\CspConfigExtension
```

### Example configuration

[](#example-configuration)

This is an example configuration, it's here to explain things and it's intentionally incomplete. You can also check [the configuration used for my site](https://github.com/spaze/michalspacek.cz/blob/master/site/app/config/contentsecuritypolicy.neon).

```
contentSecurityPolicy:
    snippets:
        slideshare:
            child-src:
                - https://www.slideshare.net
    policies:
        *.*:
            default-src: "'none'"
            form-action: "'none'"
            report-uri: https://report-uri.com.example.net
            report-to: default
        www.*.*:
            default-src: "'none'"
            script-src:
                - "'strict-dynamic'"
                - "'nonce'"
                - "'self'"
                - "'report-sample'"
            upgrade-insecure-requests:
        www.trainings.training:
            @extends: www.*.*
            connect-src: https://api.example.com
        admin.*.*:
            @extends: www.*.*
        admin.blog.add:
            @extends: admin.*.*
            connect-src: "'self'"
        admin.blog.edit:
            @extends: admin.blog.add
    policiesReportOnly:
      *.*:
        default-src: "'self'"
```

Let's explain:

- `snippets`This is where you define your snippets. A snippet consists of one or more Content Security Policy directives that can be added to the current Content Security Policy header with the `addSnippet(string $snippetName)` method like this: `$this->contentSecurityPolicy->addSnippet($type);` You can use it to add use it to extend your policy when there's a video on the page for example. There are sample snippets in [snippets.neon](https://github.com/spaze/csp-config/blob/master/snippets.neon) which you can directly include in your configuration if you want.
- `policies`Your CSP policies go here. The keys below mean `[module.]presenter.action`, wildcards are supported.

    - `*.*` means *use these for all presenters and actions*. As you can see in the example above, I've used quite restrictive policy and will allow more later on.
    - `www.*.*` applies to all presenters and actions in the "www" module.
    - `@extends: www.*.*` this configuration extends the `www.*.*` configuration, any values specified will be added, or merged. Use it to extend the default policy for some pages or actions. You can disable merging by prefixing the directive name with `!`, effectively overwriting the extended values, [see below](#overriding-values).
- `policiesReportOnly`Like `policies` but intended to be used with `Content-Security-Policy-Report-Only` header, see below.

Policies can contain a few special keys and values:

- keys with no values, like `upgrade-insecure-requests:` in the example above, will make the policy header contain just the key name and no values
- `'nonce'` will add a CSP nonce (`'nonce-somethingrandomandunique`') to the header. Nonces were defined in CSP2 and are used in a recommended policy using [CSP3 `'strict-dynamic'`](https://exploited.cz/xss/csp/strict.php). For this to work [spaze/nonce-generator](https://github.com/spaze/nonce-generator) is needed. It will also return the immutable nonce so you can add it to your `` tags. This can be nicely automated with [spaze/sri-macros](https://github.com/spaze/sri-macros).

#### Overriding values

[](#overriding-values)

If you don't want the extended values to be merged with the original values, prefix the directive name in the configuration with an exclamation mark (`!`). Consider the following simple example configuration:

```
contentSecurityPolicy:
    policies:
        *.*:
            default-src: "'none'"
        www.*:
            @extends: *.*
            default-src: "'self'"
```

Calling `getHeader('www:...')` would then return `default-src 'none' 'self'` which makes no sense and `'none'` would even be ignored.

Change the configuration to this (note the `!` prefix in `default-src`):

```
contentSecurityPolicy:
    policies:
        *.*:
            default-src: "'none'"
        www.*:
            @extends: *.*
            !default-src: "'self'"
```

Then calling `getHeader('www:...')` would return `default-src 'self'` which is probably what you'd want in this case.

### How to send the generated header in Nette Framework

[](#how-to-send-the-generated-header-in-nette-framework)

```
$header = $this->contentSecurityPolicy->getHeader($presenter->getAction(true));
if ($header) {
    $this->httpResponse->setHeader('Content-Security-Policy', $header);
}
```

You can get `$presenter` from `\Nette\Application\Application` like this for example:

```
/** @var \Nette\Application\UI\Presenter $presenter */
$presenter = $this->application->getPresenter();
$actionName = $presenter->getAction(true);
```

And get `$this->application` from dependency injection container:

```
public function __construct(private \Nette\Application\Application $application)
{
}
```

If you're in a presenter then you can use `$this->getAction(true)` instead.

### Report-only policy

[](#report-only-policy)

Use `policiesReportOnly` configuration key to define policies to use with `Content-Security-Policy-Report-Only` header:

```
contentSecurityPolicy:
    policies:
        *.*:
            default-src: "'none'"
    policiesReportOnly:
        *.*:
            default-src: "'self'"
```

Get the policy by calling `getHeaderReportOnly()` method:

```
$header = $this->contentSecurityPolicy->getHeaderReportOnly($presenter->getAction(true));
if ($header) {
    $this->httpResponse->setHeader('Content-Security-Policy-Report-Only', $header);
}
```

You can send both *enforce* and *report-only* policies which is useful for policy upgrades for example:

```
$header = $this->contentSecurityPolicy->getHeader($presenter->getAction(true));
if ($header) {
    $this->httpResponse->setHeader('Content-Security-Policy', $header);
}
$header = $this->contentSecurityPolicy->getHeaderReportOnly($presenter->getAction(true));
if ($header) {
    $this->httpResponse->setHeader('Content-Security-Policy-Report-Only', $header);
}
```

###  Health Score

54

—

FairBetter than 97% of packages

Maintenance70

Regular maintenance activity

Popularity28

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity87

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 97.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~155 days

Recently: every ~233 days

Total

19

Last Release

177d ago

Major Versions

v0.1.0 → v1.0.02019-03-09

v1.0.1 → v2.0.02019-04-13

v2.3.0 → v3.0.02023-05-04

v3.0.0 → v4.0.02023-06-12

PHP version history (6 changes)v0.1.0PHP ~7.0

v1.0.0PHP ~7.1

v2.0.7PHP ^7.1 || ^8.0

v2.2.0PHP ^7.2 || ^8.0

v3.0.0PHP ^8.2

v4.1.0PHP ^8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/6777bd445610e6e458e4d41bdefa3070d2ed4e068323362353b061b15e9ff81b?d=identicon)[spaze](/maintainers/spaze)

---

Top Contributors

[![spaze](https://avatars.githubusercontent.com/u/1966648?v=4)](https://github.com/spaze "spaze (139 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (3 commits)")

###  Code Quality

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/spaze-csp-config/health.svg)

```
[![Health](https://phpackages.com/badges/spaze-csp-config/health.svg)](https://phpackages.com/packages/spaze-csp-config)
```

###  Alternatives

[league/config

Define configuration arrays with strict schemas and access values with dot notation

564302.2M24](/packages/league-config)[contributte/di

Extra contrib to nette/di

465.8M18](/packages/contributte-di)[shipmonk/name-collision-detector

Simple tool to find ambiguous classes or any other name duplicates within your project.

362.1M35](/packages/shipmonk-name-collision-detector)[contributte/event-dispatcher

Best event dispatcher / event manager / event emitter for Nette Framework

292.4M19](/packages/contributte-event-dispatcher)[contributte/menu-control

Menu control for Nette framework

29108.6k1](/packages/contributte-menu-control)[radekdostal/nette-datetimepicker

DatePicker and DateTimePicker input controls for Nette Framework

13272.2k3](/packages/radekdostal-nette-datetimepicker)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
