{"id":13519170,"url":"https://github.com/paragonie/csp-builder","last_synced_at":"2025-05-14T04:07:59.513Z","repository":{"id":33847773,"uuid":"37551453","full_name":"paragonie/csp-builder","owner":"paragonie","description":"Build Content-Security-Policy headers from a JSON file (or build them programmatically)","archived":false,"fork":false,"pushed_at":"2025-01-03T21:04:08.000Z","size":175,"stargazers_count":543,"open_issues_count":7,"forks_count":39,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-04-14T22:04:36.888Z","etag":null,"topics":["content-security-policy","cross-site-scripting","csp","csp-builder","csp-header","easy-to-use","http","http-header","json-configuration","php","secure-by-default","security","xss"],"latest_commit_sha":null,"homepage":"https://paragonie.com/projects","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/paragonie.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-06-16T19:30:39.000Z","updated_at":"2025-03-15T20:57:58.000Z","dependencies_parsed_at":"2024-01-14T17:03:02.199Z","dependency_job_id":"eca59c97-610a-4d0c-99de-40ef2038fde0","html_url":"https://github.com/paragonie/csp-builder","commit_stats":{"total_commits":154,"total_committers":20,"mean_commits":7.7,"dds":0.6428571428571428,"last_synced_commit":"fa924ebdeec1c81f89c93f145ef56b0941df1618"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paragonie%2Fcsp-builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paragonie%2Fcsp-builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paragonie%2Fcsp-builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paragonie%2Fcsp-builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/paragonie","download_url":"https://codeload.github.com/paragonie/csp-builder/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254069557,"owners_count":22009558,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["content-security-policy","cross-site-scripting","csp","csp-builder","csp-header","easy-to-use","http","http-header","json-configuration","php","secure-by-default","security","xss"],"created_at":"2024-08-01T05:01:54.958Z","updated_at":"2025-05-14T04:07:59.345Z","avatar_url":"https://github.com/paragonie.png","language":"PHP","funding_links":[],"categories":["PHP","http"],"sub_categories":[],"readme":"# Content Security Policy Builder\n\n[![Build Status](https://github.com/paragonie/csp-builder/actions/workflows/ci.yml/badge.svg)](https://github.com/paragonie/csp-builder/actions)\n[![Psalm Status](https://github.com/paragonie/csp-builder/actions/workflows/psalm.yml/badge.svg)](https://github.com/paragonie/csp-builder/actions)\n[![Latest Stable Version](https://poser.pugx.org/paragonie/csp-builder/v/stable)](https://packagist.org/packages/paragonie/csp-builder)\n[![Latest Unstable Version](https://poser.pugx.org/paragonie/csp-builder/v/unstable)](https://packagist.org/packages/paragonie/csp-builder)\n[![License](https://poser.pugx.org/paragonie/csp-builder/license)](https://packagist.org/packages/paragonie/csp-builder)\n[![Downloads](https://img.shields.io/packagist/dt/paragonie/csp-builder.svg)](https://packagist.org/packages/paragonie/csp-builder)\n\nEasily integrate Content-Security-Policy headers into your web application, either\nfrom a JSON configuration file, or programatically.\n\nCSP Builder was created by [Paragon Initiative Enterprises](https://paragonie.com)\nas part of our effort to encourage better [application security](https://paragonie.com/service/appsec) practices.\n\nCheck out our other [open source projects](https://paragonie.com/projects) too.\n\nThere's also a [CSP middleware](https://github.com/geggleto/geggleto-csp-middleware) available that uses this library.\n\n## Installing\n\nFirst, get [Composer](https://getcomposer.org/download), then run:\n\n```sh\ncomposer require paragonie/csp-builder\n```\n\n## Build a Content Security Policy header from a JSON configuration file\n\n```php\n\u003c?php\n\nuse ParagonIE\\CSPBuilder\\CSPBuilder;\n\n$csp = CSPBuilder::fromFile('/path/to/source.json');\n$csp-\u003esendCSPHeader();\n\n```\n\nYou can also load the configuration from a JSON string, like so:\n\n```php\n\u003c?php\n\nuse ParagonIE\\CSPBuilder\\CSPBuilder;\n\n$configuration = file_get_contents('/path/to/source.json');\nif (!is_string($configuration)) {\n    throw new Error('Could not read configuration file!');\n}\n$csp = CSPBuilder::fromData($configuration);\n$csp-\u003esendCSPHeader();\n\n```\n\nFinally, you can just pass an array to the first argument of the constructor:\n\n```php\n\u003c?php\n\nuse ParagonIE\\CSPBuilder\\CSPBuilder;\n\n$configuration = file_get_contents('/path/to/source.json');\nif (!is_string($configuration)) {\n    throw new Error('Could not read configuration file!');\n}\n$decoded = json_decode($configuration, true);\nif (!is_array($decoded)) {\n  throw new Error('Could not parse configuration!');\n}\n$csp = new CSPBuilder($decoded);\n$csp-\u003esendCSPHeader();\n\n```\n\n\n### Example\n\n```json\n{\n    \"report-only\": false,\n    \"report-to\": \"PolicyName\",\n    \"report-uri\": \"/csp_violation_reporting_endpoint\",\n    \"base-uri\": [],\n    \"default-src\": [],    \n    \"child-src\": {\n        \"allow\": [\n            \"https://www.youtube.com\",\n            \"https://www.youtube-nocookie.com\"\n        ],\n        \"self\": false\n    },\n    \"connect-src\": [],\n    \"font-src\": {\n        \"self\": true\n    },\n    \"form-action\": {\n        \"allow\": [\n            \"https://example.com\"\n        ],\n        \"self\": true\n    },\n    \"frame-ancestors\": [],\n    \"img-src\": {\n        \"blob\": true,\n        \"self\": true,\n        \"data\": true\n    },\n    \"media-src\": [],\n    \"object-src\": [],\n    \"plugin-types\": [],\n    \"script-src\": {\n        \"allow\": [\n            \"https://www.google-analytics.com\"\n        ],\n        \"self\": true,\n        \"unsafe-inline\": false,\n        \"unsafe-eval\": false\n    },\n    \"style-src\": {\n        \"self\": true\n    },\n    \"upgrade-insecure-requests\": true\n}\n```\n\n## Build a Content Security Policy, programmatically\n\n```php\n\u003c?php\n\nuse ParagonIE\\CSPBuilder\\CSPBuilder;\n\n$csp = CSPBuilder::fromFile('/path/to/source.json');\n\n// Let's add a nonce for inline JS\n$nonce = $csp-\u003enonce('script-src');\n$body .= \"\u003cscript nonce={$nonce}\u003e\";\n    $body .= $desiredJavascriptCode;\n$body .= \"\u003c/script\u003e\";\n\n// Let's add a hash to the CSP header for $someScript\n$hash = $csp-\u003ehash('script-src', $someScript, 'sha256');\n\n// Add a new source domain to the whitelist\n$csp-\u003eaddSource('image', 'https://ytimg.com');\n\n// Set the Report URI\n$csp-\u003esetReportUri('https://example.com/csp_report.php');\n\n// Let's turn on HTTPS enforcement\n$csp-\u003eaddDirective('upgrade-insecure-requests', true);\n\n$csp-\u003esendCSPHeader();\n```\n\nNote that many of these methods can be chained together:\n\n```php\n$csp = CSPBuilder::fromFile('/path/to/source.json');\n$csp-\u003eaddSource('image', 'https://ytimg.com')\n    -\u003eaddSource('frame', 'https://youtube.com')\n    -\u003eaddDirective('upgrade-insecure-requests', true)\n    -\u003esendCSPHeader();\n```\n\n* `addSource()`\n* `addDirective()`\n* `disableOldBrowserSupport()`\n* `enableOldBrowserSupport()`\n* `hash()`\n* `preHash()`\n* `setDirective()`\n* `setBlobAllowed()`\n* `setDataAllowed()`\n* `setFileSystemAllowed()`\n* `setMediaStreamAllowed()`\n* `setReportUri()`\n* `setSelfAllowed()`\n* `setAllowUnsafeEval()`\n* `setAllowUnsafeInline()`\n\n## Inject a CSP header into a PSR-7 message\n\nInstead of invoking `sendCSPHeader()`, you can instead inject the headers into\nyour PSR-7 message object by calling it like so:\n\n```php\n/**\n * $yourMessageHere is an instance of an object that implements \n * \\Psr\\Http\\Message\\MessageInterface\n *\n * Typically, this will be a Response object that implements \n * \\Psr\\Http\\Message\\ResponseInterface\n *\n * @ref https://github.com/guzzle/psr7/blob/master/src/Response.php\n */\n$csp-\u003einjectCSPHeader($yourMessageHere);\n```\n\n## Save a CSP header for configuring Apache/nginx\n\nInstead of calling `sendCSPHeader()` on every request, you can build the CSP once\nand save it to a snippet for including in your server configuration:\n\n```php\n$policy = CSPBuilder::fromFile('/path/to/source.json');\n$policy-\u003esaveSnippet(\n    '/etc/nginx/snippets/my-csp.conf',\n    CSPBuilder::FORMAT_NGINX\n);\n```\n\nMake sure you reload your webserver afterwards.\n\n## Processing output before save to disk through hook\n\n```php\n$policy = CSPBuilder::fromFile('/path/to/source.json');\n$policy-\u003esaveSnippet(\n    '/etc/nginx/snippets/my-csp.conf',\n    CSPBuilder::FORMAT_NGINX\n    fn ($output) =\u003e  \\str_replace('bar','foo',$output)\n);\n```\n\nThe output will change before save to file\n\n## Support Contracts\n\nIf your company uses this library in their products or services, you may be\ninterested in [purchasing a support contract from Paragon Initiative Enterprises](https://paragonie.com/enterprise).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparagonie%2Fcsp-builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fparagonie%2Fcsp-builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparagonie%2Fcsp-builder/lists"}