{"id":13828353,"url":"https://github.com/spatie/laravel-csp","last_synced_at":"2026-01-24T20:50:47.965Z","repository":{"id":28998873,"uuid":"119958264","full_name":"spatie/laravel-csp","owner":"spatie","description":"Set content security policy headers in a Laravel app","archived":false,"fork":false,"pushed_at":"2025-11-25T13:46:03.000Z","size":453,"stargazers_count":837,"open_issues_count":0,"forks_count":96,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-11-27T16:34:55.104Z","etag":null,"topics":["csp","http","laravel","request","security"],"latest_commit_sha":null,"homepage":"https://freek.dev/982-using-content-security-policy-headers-in-a-laravel-app","language":"PHP","has_issues":false,"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/spatie.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"custom":"https://spatie.be/open-source/support-us"}},"created_at":"2018-02-02T09:01:58.000Z","updated_at":"2025-11-27T04:13:21.000Z","dependencies_parsed_at":"2024-01-16T20:27:58.817Z","dependency_job_id":"75c06764-7f48-48fd-912f-1be34b2807e0","html_url":"https://github.com/spatie/laravel-csp","commit_stats":{"total_commits":199,"total_committers":48,"mean_commits":4.145833333333333,"dds":0.5175879396984925,"last_synced_commit":"5e59492201bf7f882bf3549b068cd9d50fb813af"},"previous_names":[],"tags_count":76,"template":false,"template_full_name":null,"purl":"pkg:github/spatie/laravel-csp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spatie%2Flaravel-csp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spatie%2Flaravel-csp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spatie%2Flaravel-csp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spatie%2Flaravel-csp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spatie","download_url":"https://codeload.github.com/spatie/laravel-csp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spatie%2Flaravel-csp/sbom","scorecard":{"id":359683,"data":{"date":"2025-08-11","repo":{"name":"github.com/spatie/laravel-csp","commit":"de6c41f5b7dc476d8637ca36ab507376ec815e5d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.6,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":6,"reason":"Found 15/25 approved changesets -- score normalized to 6","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":6,"reason":"8 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 6","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.md:0","Info: FSF or OSI recognized license: MIT License: LICENSE.md:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 20 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T10:29:51.108Z","repository_id":28998873,"created_at":"2025-08-18T10:29:51.108Z","updated_at":"2025-08-18T10:29:51.108Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28736747,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T19:23:36.361Z","status":"ssl_error","status_checked_at":"2026-01-24T19:23:28.966Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["csp","http","laravel","request","security"],"created_at":"2024-08-04T09:02:42.722Z","updated_at":"2026-01-24T20:50:47.958Z","avatar_url":"https://github.com/spatie.png","language":"PHP","funding_links":["https://spatie.be/open-source/support-us"],"categories":["PHP"],"sub_categories":[],"readme":"\u003cdiv align=\"left\"\u003e\n    \u003ca href=\"https://spatie.be/open-source?utm_source=github\u0026utm_medium=banner\u0026utm_campaign=laravel-csp\" target=\"_blank\"\u003e\n      \u003cpicture\u003e\n        \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://spatie.be/packages/header/laravel-csp/html/dark.webp\"\u003e\n        \u003cimg alt=\"Logo for Laravel CSP\" src=\"https://spatie.be/packages/header/laravel-csp/html/light.webp\"\u003e\n      \u003c/picture\u003e\n    \u003c/a\u003e\n\n\u003ch1\u003eSet content security policy headers in a Laravel app\u003c/h1\u003e\n    \n[![Latest Version on Packagist](https://img.shields.io/packagist/v/spatie/laravel-csp.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-csp)\n![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/spatie/laravel-csp/run-tests.yml?branch=main\u0026label=tests\u0026style=flat-square)\n![Check \u0026 fix styling](https://github.com/spatie/laravel-csp/workflows/Check%20\u0026%20fix%20styling/badge.svg)\n[![Total Downloads](https://img.shields.io/packagist/dt/spatie/laravel-csp.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-csp)\n    \n\u003c/div\u003e\n\nBy default, all scripts on a webpage are allowed to send and fetch data to any site they want. This can be a security problem. Imagine one of your JavaScript dependencies sends all keystrokes, including passwords, to a third party website.\n\nIt's very easy for someone to hide this malicious behaviour, making it nearly impossible for you to detect it (unless you manually read all the JavaScript code on your site). For a better idea of why you really need to set content security policy headers, read [this excellent blog post](https://medium.com/hackernoon/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5) by [David Gilbertson](https://twitter.com/D__Gilbertson).\n\nSetting Content Security Policy headers helps solve this problem. These headers dictate which sites your site is allowed to contact. This package makes it easy for you to set the right headers.\n\nThis readme does not aim to fully explain all the possible usages of CSP and its directives. We highly recommend that you read [Mozilla's documentation on the Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) before using this package. Another good resource to learn about CSP, is [this edition of the Larasec newsletter](https://larasec.substack.com/p/in-depth-content-security-policy) by Stephen Rees-Carter.\n\n\n## Support us\n\n[\u003cimg src=\"https://github-ads.s3.eu-central-1.amazonaws.com/laravel-csp.jpg?t=1\" width=\"419px\" /\u003e](https://spatie.be/github-ad-click/laravel-csp)\n\nWe invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).\n\nWe highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).\n\n## Installation\n\nYou can install the package via composer:\n\n```bash\ncomposer require spatie/laravel-csp\n```\n\nYou can publish the config-file with:\n\n```bash\nphp artisan vendor:publish --tag=csp-config\n```\n\nThis is the contents of the file which will be published at `config/csp.php`:\n\n```php\nreturn [\n\n    /*\n     * Presets will determine which CSP headers will be set. A valid CSP preset is\n     * any class that implements `Spatie\\Csp\\Preset`\n     */\n    'presets' =\u003e [\n        Spatie\\Csp\\Presets\\Basic::class,\n    ],\n\n    /**\n     * Register additional global CSP directives here.\n     */\n    'directives' =\u003e [\n        // [Directive::SCRIPT, [Keyword::UNSAFE_EVAL, Keyword::UNSAFE_INLINE]],\n    ],\n\n    /*\n     * These presets which will be put in a report-only policy. This is great for testing out\n     * a new policy or changes to existing CSP policy without breaking anything.\n     */\n    'report_only_presets' =\u003e [\n        //\n    ],\n\n    /**\n     * Register additional global report-only CSP directives here.\n     */\n    'report_only_directives' =\u003e [\n        // [Directive::SCRIPT, [Keyword::UNSAFE_EVAL, Keyword::UNSAFE_INLINE]],\n    ],\n\n    /*\n     * All violations against a policy will be reported to this url.\n     * A great service you could use for this is https://report-uri.com/\n     */\n    'report_uri' =\u003e env('CSP_REPORT_URI', ''),\n\n    /*\n     * Headers will only be added if this setting is set to true.\n     */\n    'enabled' =\u003e env('CSP_ENABLED', true),\n\n    /**\n     * Headers will be added when Vite is hot reloading.\n     */\n    'enabled_while_hot_reloading' =\u003e env('CSP_ENABLED_WHILE_HOT_RELOADING', false),\n\n    /*\n     * The class responsible for generating the nonces used in inline tags and headers.\n     */\n    'nonce_generator' =\u003e Spatie\\Csp\\Nonce\\RandomString::class,\n\n    /*\n     * Set false to disable automatic nonce generation and handling.\n     * This is useful when you want to use 'unsafe-inline' for scripts/styles\n     * and cannot add inline nonces.\n     * Note that this will make your CSP policy less secure.\n     */\n    'nonce_enabled' =\u003e env('CSP_NONCE_ENABLED', true),\n];\n```\n\nYou can add CSP headers to all responses of your app by registering `Spatie\\Csp\\AddCspHeaders::class` as global middleware in `bootstrap/app.php`.\n\n```php\nuse Spatie\\Csp\\AddCspHeaders;\n\n-\u003ewithMiddleware(function (Middleware $middleware) {\n     $middleware-\u003eappend(AddCspHeaders::class);\n})\n```\n \nAlternatively you can apply the middleware on the route or route group level.\n\n```php\n// In your routes file\nRoute::get('my-page', 'MyController')\n    -\u003emiddleware(AddCspHeaders::class);\n```\n\nYou can also pass a preset class as a parameter to the middleware:\n \n```php\n// In your routes file\nRoute::get('my-page', 'MyController')\n    -\u003emiddleware(AddCspHeaders::class . ':' . MyPreset::class);\n``` \n\nThe given preset will override the ones configured in the `config/csp.php` config file for that specific route or group of routes.\n\nAlternatively, you can register your CSP policies as a meta tag using our Blade directives.\n\n```blade\n{{-- app/layout.blade.php --}}\n\u003chead\u003e\n    @cspMetaTag\n\u003c/head\u003e\n```\n\n## Usage\n\nThis package ships with a few commonly used presets to get your started. *We're happy to receive PRs for more services!*\n\n| Policy                     | Services                                                                                       |\n|----------------------------|------------------------------------------------------------------------------------------------|\n| `Basic`                    | Allow requests to scripts, images… within the application                                      |\n| `AdobeFonts`               | [fonts.adobe.com](https://fonts.adobe.com) (previously typekit.com)                            |\n| `Alchemer Survey`          | [alchemer.com](https://www.alchemer.com)                                                       |\n| `Algolia`                  | [algolia.com](https://www.algolia.com)                                                         |\n| `Bootstrap`                | [getbootstrap.com](https://getbootstrap.com)                                                   |       \n| `Bunny Fonts`              | [fonts.bunny.net](https://fonts.bunny.net/)                                                    |       \n| `Chargebee`                | [chargebee.com](https://www.chargebee.com/)                                                    |\n| `Cloudflare Cdn`           | [cloudflare.com](https://www.cloudflare.com/en-in/application-services/products/cdn/)          |\n| `Cloudflare Turnstile`     | [cloudflare.com](https://www.cloudflare.com/application-services/products/turnstile/)          |\n| `Cloudflare Web Analytics` | [cloudflare.com](https://developers.cloudflare.com/web-analytics/)                             |\n| `Fathom`                   | [usefathom.com](https://usefathom.com)                                                         |\n| `Google TLD's`             | Allow all Google Top Level Domains for 'connect' and 'image'                                   |       \n| `Google`                   | Google Analytics \u0026 Tag Manager                                                                 |       \n| `GoogleFonts`              | [fonts.google.com](https://fonts.google.com)                                                   | \n| `GoogleLookerStudio`       | [lookerstudio.google.com](https://lookerstudio.google.com)                                     | \n| `GoogleMaps`               | [maps.google.com](https://maps.google.com)                                                     | \n| `GoogleRecaptcha`          | [developers.google.com](https://developers.google.com/recaptcha)                               | \n| `Hcaptcha`                 | [hcaptcha.com](https://docs.hcaptcha.com)                                                      |\n| `Heap Analytics`           | [heap.io](https://www.heap.io/)                                                                |\n| `Hireroad`                 | [hireroad.com](https://hireroad.com)                                                           |\n| `Hotjar`                   | [hotjar.com](https://help.hotjar.com/hc/en-us/articles/115011640307-Content-Security-Policies) | \n| `HubSpot`                  | [hubspot.com](https://hubspot.com) (full suite)                                                |       \n| `Intercom`                 | [intercom.com](https://intercom.com/)                                                          |       \n| `JsDelivr`                 | [jsdelivr.com](https://jsdelivr.com)                                                           |  \n| `JQuery`                   | [jquery.com](https://jquery.com)                                                               |  \n| `Maze`                     | [maze.co](https://maze.co)                                                                     |       \n| `Meta Pixel`               | [facebook.com](https://en-gb.facebook.com/business/tools/meta-pixel)                           |       \n| `Microsoft Clarity`        | [clarity.microsoft.com](https://clarity.microsoft.com)                                         |\n| `Plain`                    | [plain.com](https://plain.com)                                                                 |\n| `Plausible Analytics`      | [plausible.io](http://plausible.io/)                                                           |\n| `Posthog`                  | [posthog.com](https://posthog.com/)                                                            |       \n| `Rollbar`                  | [posthog.com](https://docs.rollbar.com/docs/javascript)                                        |       \n| `Sentry`                   | [sentry.io](https://sentry.io/)                                                                |\n| `Stripe`                   | [stripe.com](https://stripe.com/)                                                              |\n| `SurveyMonkey`             | [surveymonkey.com](https://www.surveymonkey.com/)                                              |\n| `TicketTailor`             | [tickettailor.com](https://www.tickettailor.com)                                               |\n| `Tolt`                     | [tolt.io](https://tolt.io)                                                                     |\n| `TrackJS`                  | [trackjs.com](https://trackjs.com)                                                             |\n| `Vimeo`                    | [vimeo.com](https://vimeo.com)                                                                 |\n| `Visual Website Optimizer` | [vwo.com](https://vwo.com)                                                                     |\n| `Whereby`                  | [whereby.com](https://whereby.com)                                                             |\n\nRegister the presets you want to use for your application in `config/csp.php` under the `presets` or `report_only_presets` key.\n\nIf you have app-specific needs or the service you're integrated isn't included in this package, you can create your own preset as explained below. You can also register global directives in the configuration file using a tuple notation.\n\n```php\n'directives' =\u003e [\n    [Directive::SCRIPT, Keyword::UNSAFE_EVAL],\n],\n\n'report_only_directives' =\u003e [\n    [Directive::SCRIPT, Keyword::UNSAFE_INLINE],\n],\n```\n\nHere you may also create multiple directive \u0026 value combinations by padding multiple values in the tuple.\n\n```php\n'directives' =\u003e [\n    [[Directive::SCRIPT, Directive::STYLE], [Keyword::UNSAFE_EVAL, Keyword::UNSAFE_INLINE]],\n],\n```\n\n## Creating a preset\n\nAn example of a CSP directive is `script-src`. If this has the value `'self' www.google.com` then your site can only load scripts from its own domain or `www.google.com`. You'll find [a list with all CSP directives](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/#Directives) at Mozilla's excellent developer site.\n\nAccording to the spec certain directive values need to be surrounded by quotes. Examples of this are `'self'`, `'none'` and `'unsafe-inline'`. When using `add` function you're not required to surround the directive value with quotes manually. We will automatically add quotes. Script/style hashes, as well, will be auto-detected and surrounded with quotes.\n\n```php\npublic function configure(Policy $policy): void\n{\n    $policy\n        // Will output `'self'` when outputting headers\n        -\u003eadd(Directive::SCRIPT, Keyword::SELF)\n        // Will output `'sha256-hash'` when outputting headers\n        -\u003eadd(Directive::STYLE, 'sha256-hash');\n}\n```\n\nYou may also use the same keywords for multiple directives by passing an array of directives.\n\n```php\npublic function configure(Policy $policy): void\n{\n    $policy-\u003eadd([Directive::SCRIPT, DIRECTIVE::STYLE], 'www.google.com');\n}\n```\n\nOr multiple keywords for one or more directives.\n\n```php\npublic function configure(Policy $policy): void\n{\n    $policy\n        -\u003eadd(Directive::SCRIPT, [Keyword::UNSAFE_EVAL, Keyword::UNSAFE_INLINE])\n        -\u003eadd([Directive::SCRIPT, DIRECTIVE::STYLE], ['www.google.com', 'analytics.google.com']);\n}\n```\n\nThere are also a few cases where you don't have to or don't need to specify a value, eg. upgrade-insecure-requests, block-all-mixed-content, ... In this case you can use the following value:\n\n```php\npublic function configure(Policy $policy): void\n{\n    $policy\n        -\u003eadd(Directive::UPGRADE_INSECURE_REQUESTS, Value::NO_VALUE)\n        -\u003eadd(Directive::BLOCK_ALL_MIXED_CONTENT, Value::NO_VALUE);\n}\n```\n\nThis will output a CSP like this:\n```\nContent-Security-Policy: upgrade-insecure-requests;block-all-mixed-content\n```\n\nThe `presets` key of the `csp` config file is set to `[\\Spatie\\Csp\\Presets\\Basic::class]` by default. This class allows your site to only use images, scripts, form actions of your own site.\n\n```php\nnamespace Spatie\\Csp\\Presets;\n\nuse Spatie\\Csp\\Directive;\nuse Spatie\\Csp\\Keyword;\nuse Spatie\\Csp\\Policy;\nuse Spatie\\Csp\\Preset;\n\nclass Basic implements Preset\n{\n    public function configure(Policy $policy): void\n    {\n        $policy\n            -\u003eadd(Directive::BASE, Keyword::SELF)\n            -\u003eadd(Directive::CONNECT, Keyword::SELF)\n            -\u003eadd(Directive::DEFAULT, Keyword::SELF)\n            -\u003eadd(Directive::FORM_ACTION, Keyword::SELF)\n            -\u003eadd(Directive::IMG, Keyword::SELF)\n            -\u003eadd(Directive::MEDIA, Keyword::SELF)\n            -\u003eadd(Directive::OBJECT, Keyword::NONE)\n            -\u003eadd(Directive::SCRIPT, Keyword::SELF)\n            -\u003eadd(Directive::STYLE, Keyword::SELF)\n            -\u003eaddNonce(Directive::SCRIPT)\n            -\u003eaddNonce(Directive::STYLE);\n    }\n}\n```\n\nYou can allow fetching scripts from `www.google.com` by writing a custom preset.\n\n```php\nnamespace App\\Support;\n\nuse Spatie\\Csp\\Directive;\nuse Spatie\\Csp\\Keyword;\nuse Spatie\\Csp\\Policy;\nuse Spatie\\Csp\\Preset;\n\nclass MyCspPreset implements Preset\n{\n    public function configure(Policy $policy): void\n    {\n        $policy-\u003eadd(Directive::SCRIPT, 'www.google.com');\n    }\n}\n```\n\nDon't forget to update the `presets` key in the `csp` config file to the class name of your preset.\n\n```php\n'presets' =\u003e [\n    Spatie\\Csp\\Presets\\Basic::class,\n    App\\Support\\MyCspPreset::class,\n],\n```\n\n### Using inline scripts and styles\n\nWhen using CSP you must specifically allow the use of inline scripts or styles. The recommended way of doing that with this package is to use a `nonce`. A nonce is a number that is unique per request. The nonce must be specified in the CSP headers and in an attribute on the html tag. This way an attacker has no way of injecting malicious scripts or styles.\n\nFirst you must add the nonce to the right directives in your policy:\n\n```php\npublic function configure(Policy $policy): void\n{\n    $policy\n        -\u003eadd(Directive::SCRIPT, 'self')\n        -\u003eadd(Directive::STYLE, 'self')\n        -\u003eaddNonce(Directive::SCRIPT)\n        -\u003eaddNonce(Directive::STYLE);\n}\n```\n\nNext you must add the nonce to the html:\n\n```blade\n\u003cstyle @cspNonce\u003e\n   ...\n\u003c/style\u003e\n\n\u003cscript @cspNonce\u003e\n   ...\n\u003c/script\u003e\n```\n\nThere are few other options to use inline styles and scripts. Take a look at the [CSP docs on the Mozilla developer site](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src) to know more.\n\n### Integration with Vite\n\nWhen building assets, Laravel's Vite plugin can [generate a nonce](https://laravel.com/docs/9.x/vite#content-security-policy-csp-nonce) that you can retrieve with `Vite::cspNonce`.  You can use in your own `NonceGenerator`.\n\n```php\nnamespace App\\Support;\n\nuse Illuminate\\Support\\Facades\\Vite;\nuse Spatie\\Csp\\Nonce\\NonceGenerator;\n\nclass LaravelViteNonceGenerator implements NonceGenerator\n{\n    public function generate(): string\n    {\n        return Vite::cspNonce();\n    }\n}\n```\n\nDon't forget to specify the fully qualified class name of your `NonceGenerator` in the `nonce_generator` key of the `csp` config file.\n\nAlternatively, you can instruct Vite to use a specific value that it should use as nonce.\n\n```php\nnamespace App\\Support;\n\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Facades\\Vite;\n\nclass RandomString implements NonceGenerator\n{\n    public function generate(): string\n    {\n        // Determine the value for `$myNonce` however you want\n        $myNonce = '';\n    \n        Vite::useCspNonce($myNonce);\n        \n        return $myNonce;\n    }\n}\n```\n\nThe generated nonce should be a **base64-value** derived from at least **16 bytes of secure random data**\nThis limits the character set to characters safe for use in HTML attributes and HTTP headers.\nFor more details, see the [W3C Content Security Policy Level 3 specification](https://www.w3.org/TR/CSP3/#grammardef-base64-value)\n\n### Outputting a CSP Policy as a meta tag\n\nIn rare circumstances, a large site may have so many external connections that the CSP header actually exceeds the max header size. Or you might be generating a static page with Laravel and don't have control over the headers when the response is sent. Thankfully, the [CSP specification](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#using_the_html_meta_element) allows for outputting information as a meta tag in the head of a webpage.\n\nThis package provides a `@cspMetaTag` blade directive that you may place in the `\u003chead\u003e` of your site. This will render a header for all configured presets (both default and report-only).\n\n```blade\n\u003chead\u003e\n    @cspMetaTag\n\u003c/head\u003e\n```\n\nYou may also use this tag to render a specific preset.\n\n```blade\n\u003chead\u003e\n    @cspMetaTag(App\\Support\\MyCustomPreset::class)\n\u003c/head\u003e\n```\n\nOr use the `@cspMetaTagReportOnly` tag to render a specific preset in report-only mode.\n\n```blade\n\u003chead\u003e\n    @cspMetaTagReportOnly(App\\Support\\MyCustomPreset::class)\n\u003c/head\u003e\n```\n\n### Reporting CSP errors\n\n#### In the browser\n\nInstead of outright blocking all violations, you can put configure a CSP policy in report only mode by registering presets in the `report_only_presets` configuration option. In this case all requests will be made, but all violations will display in your favourite browser's console.\n\n#### To an external url\n\nAny violations against the policy can be reported to a given url. You can set that url in the `report_uri` key of the `csp` config file. A great service that is specifically built for handling these violation reports is [http://report-uri.io/](http://report-uri.io/). \n\n### Testing\n\nYou can run all the tests with:\n\n```bash\ncomposer test\n```\n\n### Changelog\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.\n\n## Contributing\n\nPlease see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.\n\n### Security\n\nIf you've found a bug regarding security please mail [security@spatie.be](mailto:security@spatie.be) instead of using the issue tracker.\n\n## Credits\n\n- [Freek Van der Herten](https://github.com/freekmurze)\n- [Sebastian De Deyne](https://github.com/sebastiandedeyne)\n- [Thomas Verhelst](https://github.com/TVke)\n- [All Contributors](../../contributors)\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspatie%2Flaravel-csp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspatie%2Flaravel-csp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspatie%2Flaravel-csp/lists"}