Title: No unsafe-inline
Author: Giuseppe
Published: <strong>25 Mart 2022</strong>
Last modified: 04 Dekabr 2025

---

Qoşmaları axtar

![](https://ps.w.org/no-unsafe-inline/assets/banner-772x250.png?rev=2703514)

![](https://ps.w.org/no-unsafe-inline/assets/icon-256x256.png?rev=2699768)

# No unsafe-inline

 By [Giuseppe](https://profiles.wordpress.org/mociofiletto/)

[Download](https://downloads.wordpress.org/plugin/no-unsafe-inline.1.3.0.zip)

 * [Details](https://az.wordpress.org/plugins/no-unsafe-inline/#description)
 * [Reviews](https://az.wordpress.org/plugins/no-unsafe-inline/#reviews)
 *  [Installation](https://az.wordpress.org/plugins/no-unsafe-inline/#installation)
 * [Development](https://az.wordpress.org/plugins/no-unsafe-inline/#developers)

 [Dəstək](https://wordpress.org/support/plugin/no-unsafe-inline/)

## Description

Content Security Policy (CSP) is a computer security standard introduced to prevent
cross-site scripting (XSS), clickjacking and other code injection attacks resulting
from execution of malicious content in the trusted web page context.
 Cross-site
scripting (XSS) is a type of security vulnerability that can be found in some web
applications. XSS attacks enable attackers to inject client-side scripts into web
pages viewed by other users. A cross-site scripting vulnerability may be used by
attackers to bypass access controls like the same-origin policy. Looking at National
Vulnerability Database run by US NIST, _more than 1100 (November 2025) vulnerabilities_
are reported as [XSS for WordPress’ plugins and themes](https://nvd.nist.gov/vuln/search#/nvd/home?vulnRevisionStatusList=published&keyword=XSS%20Wordpress&resultType=records).

_Keeping your site up-to-date_ with the latest versions of plugins and themes is
the **first** line of defense to ensure your site’s security.

The second thing to do, is to **deploy a strict Content Security Policy**.

### The main problem

The main problem with Content Security Policies implemented in the real world is
that [they are too weak to really protect your site](https://research.google/pubs/pub45542/)
and that many of them can be trivially bypassed by an attacker.

### The proposed solution

Google researchers recommend, instead of whole host whitelisting, to activate individual
scripts via a CSP nonces approach.
 In addition, in order to facilitate the adoption
of nonce-based CSP, they proposed the ’strict-dynamic’ keyword.

### The problem(s) with CSP in WordPress

 1.  Manual creation of a policy
 2.  Usually, a WordPress project is a mix of code written by different authors who
     contributed to the Core and or wrote plugins and themes.
      If it is possible to
     whitelist every external script loaded from a `<script src="">`, the real truth
     is that in a WordPress project you can have dozens of those scripts included with
     your plugins and calculate a cryptographic hash for each of them to be included
     in your CSP header can be a frustrating job. However, there are many browser extensions
     and WordPress’ plugins that can help you in this job.
 3.  Inline scripts
 4.  WordPress core, and plugins, use inline scripts. For these scripts, you can compute
     hashes to be inserted manually into your policy, only if these scripts do not 
     change at any page load. Unfortunately, this is not very common, as it is frequent
     to include variable values calculated server side in inline scripts. And it means
     that your inline scripts change too frequently to manually add their hashes to
     your policy.
      This commonly happens when scripts are [“localized”](https://github.com/WordPress/WordPress/blob/a793be201b9c23dbe8b90a6ecd53ab52336f0f91/wp-includes/script-loader.php#L636).
 5.  WordPress has no API to implement nonces for CSP
 6.  Even if it is easy to generate a nonce for each page view, this nonce has to be
     inserted in every script tag used to embed inline scripts in your page as
 7.      ```
         <script nonce="rAnd0m">
             doWhatever();
         </script>
         ```
     
 8.  and in your script-src directive:
 9.      ```
         script-src 'nonce-rAnd0m';
         ```
     
 10. And, of course, a nonce must be unique for each HTTP response.
 11. Unsafe hashes / Inline styles
 12. Sometimes, HTML elements as images or buttons use HTML Event Attributes (onclick,
     onsubmit…) to let events trigger actions in a browser.
      You cannot use hashes 
     or nonces for script included in event attributes and, adopting a strict CSP, 
     requires refactoring those patterns into safer alternatives or to use ‘unsafe-
     hashes’. You got a similar problem when inline styles are used in HTML tags:
 13.     ```
         <h1 style="color:blue;text-align:center;">This is a heading</h1>
         <p style="color:red;">This is a paragraph.</p>
         ```
     
 14. CSP Level 2 browsers may be ok with just putting the hash in your style-src directive.
     However, to allow hashes in the style attribute on inline CSS on browsers that
     support CSP Level 3, you may get an error like this
 15.     ```
             Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' 'sha256-nMxMqdZhkHxz5vAuW/PAoLvECzzsmeAxD/BNwG15HuA='". Either the 'unsafe-inline' keyword, a hash ('sha256-nMxMqdZhkHxz5vAuW/PAoLvECzzsmeAxD/BNwG15HuA='), or a nonce ('nonce-...') is required to enable inline execution.
         ```
     
 16. To allow inline styles you need to use ‘unsafe-hashes’ in your style-src directive(
     that is, in facts, unsafe).
      ^

### This plugin approach

This plugin affords those problems in this way:

 1. During a capture phase, it detects the scripts, styles and other embedded content
    present in the pages of your site and stores them in the database.
 2. Then you have to whitelist these contents from plugin admin.
 3. The plugin uses machine learning to cluster inline scripts trying to aggregate 
    scripts generated by the same server side (PHP) code. So, you can authorize one
    script example to authorize all scripts that the classifier predicts to label as
    whitelisted clusters.
 4. You can choose to use hashes to authorize external scripts (and the plugin will
    allow you to include Subresource Integrity in your `<script>` and `<link>`)
 5. You can use hashes or nonces to authorize inline scripts.
 6. You can ask the plugin to refactor your page to not use event attributes (converted
    in a inline script) and inline styles (converted in an internal CSS).
 7. You can set one or more violations’ report endpoints.

The plugin supports multisite installations and has (too) many options documented
in inline help.

### Creating a Content Security Policy

After plugin activation, go to Settings menu and search for CSP Settings submenu.

The steps you are supposed to do are the following.

 1. From the Tools tab, activate the capture of the tags and use your site by visiting
    all the pages or having your users visit them for a long time long period based
    on the use of your site (hours or days).
 2. From the Tools tab, perform the data clustering in the database (it can use many
    server resources).
 3. Go to the Base rules tab and include in the CSP directives the desired values ​​(
    help you with the table at the bottom of the page).
 4. Go to the external scripts tab, inline scripts tab and scripts invoked by event
    handlers tab and authorize the execution of all the legitimate scripts present 
    on the pages of your site.
 5. Leaving the tag capture active, activate the policy test (at this stage the plugin
    will generate some violations of the temporary policy used to record additional
    values to be included in the directives of your “content security policy”).
 6. After visiting again your site pages, disable the capture of the tags and repeat
    the previous steps 2, 3 and 4.
 7. Enable site protection.

N.B. When you update plugins or themes, if something doesn’t work properly on your
site pages, temporarily deactivate the protection and repeat steps 1 to 7.

### Plugin hooks

#### Filters

 * [nunil_output_csp_headers_header_csp](https://github.com/MocioF/No-unsafe-inline/blob/d068711d56c2d7b228b524f640f5e13af3327097/public/class-no-unsafe-inline-public.php#L419)
   
   nunil_output_csp_headers_header_csp is available since version 1.2.3 and can 
   be used to modify the Content-Security-Policy header before it is sent to browser
 * [no_unsafe_inline_not_sri_sources](https://github.com/MocioF/No-unsafe-inline/blob/d068711d56c2d7b228b524f640f5e13af3327097/src/Nunil_Manipulate_DOM.php#L930)
   
   no_unsafe_inline_not_sri_sources can be used to modify the list of external resources
   that do not support SRI (Subresource Integrity)
 * [no_unsafe_inline_final_output](https://github.com/MocioF/No-unsafe-inline/blob/d068711d56c2d7b228b524f640f5e13af3327097/mu-plugin/no-unsafe-inline-output-buffering.php#L100)
   
   no_unsafe_inline_final_output is an internal filter used to manipulate the output
   of the WordPress process just before the output is sent to the browser.
 * [no_unsafe_inline_meta_injector](https://github.com/MocioF/No-unsafe-inline/blob/d068711d56c2d7b228b524f640f5e13af3327097/mu-plugin/no-unsafe-inline-output-buffering.php#L107)
   
   no_unsafe_inline_meta_injector is an internal filter hook used to inject meta
   http-equiv=”Content-Security-Policy” if variable is set

#### Actions

 * [nunil_upgrade](https://github.com/MocioF/No-unsafe-inline/blob/d068711d56c2d7b228b524f640f5e13af3327097/includes/class-no-unsafe-inline.php#L213-L217)
   Functions hooked on nunil_upgrade will run when the plugin is upgraded
 * [nunil_output_csp_headers](https://github.com/MocioF/No-unsafe-inline/blob/d068711d56c2d7b228b524f640f5e13af3327097/includes/class-no-unsafe-inline.php#L254)
   Functions hooked to nunil_output_csp_headers will run when the plugin output 
   the CSP HTTP response header

### Code and libraries

This version of the plugin uses:
 * to parse HTML: * [ivopetkov/HTML5DOMDocument](https://github.com/ivopetkov/html5-dom-document-php)
on PHP<8.4 and libxml<=2.13.09 * [Masterminds\HTML5](https://github.com/Masterminds/html5-php)
on PHP<8.4 and libxml>2.13.09 * [\Dom\HTMLDocument](https://www.php.net/manual/en/migration84.new-features.php#migration84.new-features.dom):
The new ext-dom features with HTML5 support on PHP>8.4 * [RubixML](https://rubixml.com/)
for machine learning **_from version 1.1.0_** – _[PHP-ML](https://php-ml.readthedocs.io/en/latest/)
was used in versions 1.0.x_; * [opctim/php-nilsimsa](https://github.com/opctim/php-nilsimsa)
to calculate and compare Nilsimsa digests.

The log functions have been taken from
 * [perfectyorg/perfecty-push-wp](https://github.com/perfectyorg/perfecty-push-wp),**
_something you should [really try](https://wordpress.org/plugins/perfecty-push-notifications/)
if you want to implement web Push notifications in your site._**

The **complete list of dependencies** used in this plugin can be seen in [dependency graph](https://github.com/MocioF/No-unsafe-inline/network/dependencies)
on GitHub.

### Contributions, Issues, Bugs

Plugin code is hosted on a public repository on [GitHub](https://github.com/MocioF/No-unsafe-inline).

Reach me over there to help and suggest.

## Screenshots

 * [[
 * Plugin’s tools tab in a multisite enviroment.
 * [[
 * External scripts tab.
 * [[
 * Inline scripts/styles tab.
 * [[
 * List of CSP directives managed in Settings tab.
 * [[
 * A database summary table at the bottom of tools tab.

## Installation

#### Automatic installation

 1. Plugin admin panel and `add new` option.
 2. Search in the text box `No unsafe-inline`.
 3. Position yourself on the description of this plugin and select install.
 4. Activate the plugin from the WordPress admin panel.

#### Manual installation of ZIP file

 1. Download the .ZIP file from this screen.
 2. Select add plugin option from the admin panel.
 3. Select `upload` option at the top and select the file you downloaded.
 4. Confirm installation and activation of the plugin from the administration panel.

#### Manual FTP installation

 1. Download the .ZIP file from this screen and unzip it.
 2. FTP access to your folder on the web server.
 3. Copy the whole `no-unsafe-inline` folder to the `/wp-content/plugins/` directory
 4. Activate the plugin from the WordPress admin panel.

## FAQ

### Is this plugin easy to use?

This is not a click and go tool, but you can follow the instructions and implement
a strict CSP.

### Has this plugin been widely tested?

No.

### Will this plugin impact the site’s performance?

During capturing phase this plugin needs to write many data to database, so your
site can slow down.
 When the plugin enforces the CSP, it uses a mu-plugin to capture
the output of the WordPress process, manipulate it and then send to browser. I don’t
have any measure of inherent overhead.

### Is there another way to implement a strict content security policy in WordPress?

Not in my knowledge.

### Do you offer professional support for this plugin?

No. But I do my best to offer free support on wordpress.org support forum in my 
spare time.

### Do you offer professional support for CSP?

No.

## Reviews

![](https://secure.gravatar.com/avatar/b121af1bd5fc43ba29b4dac32950c9b7e46bd2f15946b7c06d7c727d147a468e?
s=60&d=retro&r=g)

### 󠀁[Exceeds Expectations](https://wordpress.org/support/topic/exceeds-expectations-5/)󠁿

 [hohumtiddleypom](https://profiles.wordpress.org/hohumtiddleypom/) 12 Noyabr 2024

This plugin has a learning curve. And it demands patience. But the results exceed
expectations. I used this plugin on a local server. I aimed to find Gutenberg Inline
styles in (rendered) HTML. This plugin found the inline styles and several style
attributes.

![](https://secure.gravatar.com/avatar/799a3436846a54b8df63d0fa93fb72261e9a9d04d779ad85072e542b9fca5213?
s=60&d=retro&r=g)

### 󠀁[Excellent plugin](https://wordpress.org/support/topic/excellent-plugin-9223/)󠁿

 [mdbraber](https://profiles.wordpress.org/mdbraber/) 08 İyul 2024 1 reply

Works like it says on the box. Make sure you have the right PHP modules installed.
Thanks for building this!

![](https://secure.gravatar.com/avatar/edf256ea62b196e829777dd2b326e3df7fe0faec9003dfd3839cf372822605fd?
s=60&d=retro&r=g)

### 󠀁[Extremely useful plugin](https://wordpress.org/support/topic/extremely-useful-plugin-41/)󠁿

 [feofanidze](https://profiles.wordpress.org/feofanidze/) 03 Mart 2024 1 reply

Not everything went smoothly, I had to abandon the Clearfy plugin and tinker with
the settings, but it was worth it. All СSP headers passed the evaluator-test successfully.

![](https://secure.gravatar.com/avatar/a377c1c28361c49b0ca776512739f3c7dc746687b66385fc0144493475609335?
s=60&d=retro&r=g)

### 󠀁[The only plugin that can build a strict CSP](https://wordpress.org/support/topic/the-only-plugin-that-can-build-a-strict-csp/)󠁿

 [esadc](https://profiles.wordpress.org/esadc/) 02 Yanvar 2023 1 reply

I’ve tried countless plugins for creating CSP policies, but none of them let you
create strong policies that could actually mitigate XSS attacks. This plugin is 
pretty young and is made by a solo developer, naturally there are some rough edges
for such a plugin. But these problems should go away with time.

![](https://secure.gravatar.com/avatar/58337216926ce9ac385bf9caaec3a5c6f543137325c18ab21b038dd521f49cc9?
s=60&d=retro&r=g)

### 󠀁[Absolutely the best plugin for strict csp](https://wordpress.org/support/topic/absolutely-the-best-plugin-for-strict-csp/)󠁿

 [gianni65](https://profiles.wordpress.org/gianni65/) 19 Sentyabr 2022

The only possible solution for those who want to adopt a stricted csp. I have installed
dozens of plugins for the management of the CSP, but THERE IS NO OTHER FREE PLUGIN
that allows to use scripts and CSS online without disabling the protection against
XSS vulnerabilities. All others disable the protection by adding the “unsafe-inline”
directive. The solution adopted by this plugin is the only intelligent one: it removes
styles and scripts in line, putting them in external files (allowed by stricted 
policy). Furthermore, the creator was very kind, thorough and helpful. Although 
perhaps a bit immature, I absolutely recommend this plugin, to try! Gianni

 [ Read all 5 reviews ](https://wordpress.org/support/plugin/no-unsafe-inline/reviews/)

## Contributors & Developers

“No unsafe-inline” is open source software. The following people have contributed
to this plugin.

Contributors

 *   [ Giuseppe ](https://profiles.wordpress.org/mociofiletto/)

“No unsafe-inline” has been translated into 1 locale. Thank you to [the translators](https://translate.wordpress.org/projects/wp-plugins/no-unsafe-inline/contributors)
for their contributions.

[Translate “No unsafe-inline” into your language.](https://translate.wordpress.org/projects/wp-plugins/no-unsafe-inline)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/no-unsafe-inline/),
check out the [SVN repository](https://plugins.svn.wordpress.org/no-unsafe-inline/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/no-unsafe-inline/)
by [RSS](https://plugins.trac.wordpress.org/log/no-unsafe-inline/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 1.3.0

 * Add management of trusted-types’ API directives
 * Bug fix for PHP 8.4
 * Avoid using replace on TrustedHTML
 * Improve js to fix-style and prefilter override

#### 1.2.5

 * Bug fix for PHP 8.4

#### 1.2.4

 * Added a support box in tools’ panel
 * Updated the HTML5 parser to work with libxml>2.13.09 and with the new \Dom\ namespaced
   class on PHP>=8.4
 * Added rel=”noopener noreferrer” in external links with _blank target

#### 1.2.3

 * Added a filter on no_unsafe_inline_not_sri_sources (thanks [@jkirrane](https://github.com/jkirrane))
 * Added a filter for $header_csp (nunil_output_csp_headers_header_csp) (thanks 
   [@tripflex](https://github.com/tripflex))
 * Fixed a fatal error if training estimator fails (thanks [@tripflex](https://github.com/tripflex))
 * Fixed processing multiple reports while capturing by violations
 * Improved the user interface for settings
 * Added an option to manage Reporting API v.1 and the Reporting-Endpoints HTTP 
   response header field
 * Added options to exclude protection and script capture on administration pages
 * Bug fixes

#### 1.2.2

 * Update mu-plugin to run callbacks attached to lower buffer levels and to the 
   shutdown hook
 * Extend overriding of native js functions
 * Adding jqueryui v. 1.13.3 theme
 * Remove legacy dependencies from distribution package
 * Bug fixes

#### 1.2.1

Bug fixes

#### 1.2.0

 * Added persistence and online (partial) training to Knn classifiers
 * Added checks on startup for PHP build options
 * Fixed error thrown when malfromed URL are parsed while capture is enabled
 * Modified classificators tests
 * Improvements at the UI

#### 1.1.5

 * Update external scripts table on plugin/theme/core update
 * Added a check for PHP extension requirements on startup
 * Added a polyfill to be used when PHP is built with –disable-mbregex

#### 1.1.4

 * Fix src_attrib field size for long URLs
 * Remove spatie\async from codebase and use fibers to execute long processes after
   page output
 * Fix summary report

#### 1.1.3

 * Reduce the number of capture occurences
 * (dev) adding support for SCRIPT_DEBUG
 * Update composer and npm dependencies
 * Fix admin js for jquery deprecations
 * Adding some cookie scripts to the list of scripts that do not support SRI

#### 1.1.2

 * Removed the use of ‘hash-value’ to allow external styles – not supported by CSP
 * Removed the use of ‘hash-value’ to allow external images – not supported by CSP
 * Added code to prune legacy external assets when pruning db
 * Forced synchronous code execution

#### 1.1.1

 * Bug fixes
 * Improved compatibility with PHP 8.2

#### 1.1.0

 * Moving to RubixML lib for machine-learning.
 * Fixed bug in capturing tags.
 * Fixed bug in pruning clusters.
 * Added a mutation observer for inline styles transfered to the internal css.

#### 1.0.2

 * Fix results count error and default order in list_tables.
 * Avoid sending CSP on not HTML or XML Document responses.
 * Include page capture in asyncronous execution.
 * Removing double conversion of nilsimsa, while clustering.

#### 1.0.1

 * Lowered priority for action and filter called on shutdown hook.
 * Moved default value for inline_scripts_mode option to ‘nonce’.
 * Fixed server error when csp header is too long.
 * Added setting to define HTTP Response Header Limit.
 * Added a waiting spinner on tools’ page of admin interface.

#### 1.0.0

 * First plugin submission to WordPress.org

## Meta

 *  Version **1.3.0**
 *  Last updated **4 ay öncə**
 *  Active installations **200+**
 *  WordPress version ** 5.9 or higher **
 *  Tested up to **6.9.4**
 *  PHP version ** 7.4 or higher **
 *  Languages
 * [English (US)](https://wordpress.org/plugins/no-unsafe-inline/) və [Italian](https://it.wordpress.org/plugins/no-unsafe-inline/).
 *  [Translate into your language](https://translate.wordpress.org/projects/wp-plugins/no-unsafe-inline)
 * Tags
 * [content security policy](https://az.wordpress.org/plugins/tags/content-security-policy/)
   [csp](https://az.wordpress.org/plugins/tags/csp/)[multisite](https://az.wordpress.org/plugins/tags/multisite/)
   [security](https://az.wordpress.org/plugins/tags/security/)
 *  [Advanced View](https://az.wordpress.org/plugins/no-unsafe-inline/advanced/)

## Reytinqlər

 5 out of 5 stars.

 *  [  5 5-star reviews     ](https://wordpress.org/support/plugin/no-unsafe-inline/reviews/?filter=5)
 *  [  0 4-star reviews     ](https://wordpress.org/support/plugin/no-unsafe-inline/reviews/?filter=4)
 *  [  0 3-star reviews     ](https://wordpress.org/support/plugin/no-unsafe-inline/reviews/?filter=3)
 *  [  0 2-star reviews     ](https://wordpress.org/support/plugin/no-unsafe-inline/reviews/?filter=2)
 *  [  0 1-star reviews     ](https://wordpress.org/support/plugin/no-unsafe-inline/reviews/?filter=1)

[Your review](https://wordpress.org/support/plugin/no-unsafe-inline/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/no-unsafe-inline/reviews/)

## Contributors

 *   [ Giuseppe ](https://profiles.wordpress.org/mociofiletto/)

## Dəstək

Issues resolved in last two months:

     0 out of 4

 [Dəstək forumuna bax](https://wordpress.org/support/plugin/no-unsafe-inline/)

## Donate

Would you like to support the advancement of this plugin?

 [ Donate to this plugin ](https://paypal.me/GiuseppeF77)