Changeset 1776322
- Timestamp:
- 11/27/2017 05:30:10 PM (8 years ago)
- Location:
- wp-content-security-policy
- Files:
-
- 29 added
- 6 edited
-
assets/banner-1544x500.png (added)
-
assets/banner-772x250.png (added)
-
assets/icon-128x128.png (added)
-
assets/icon-256x256.png (added)
-
assets/wp-csp-header.png (added)
-
assets/wp-csp-header.psd (added)
-
assets/wp-csp-icon.psd (added)
-
tags/2.0 (added)
-
tags/2.0/admin (added)
-
tags/2.0/admin/part-cspcontrol.php (added)
-
tags/2.0/admin/part-cspheaders.php (added)
-
tags/2.0/admin/part-cspoptions.php (added)
-
tags/2.0/admin/part-cspsavechanges.php (added)
-
tags/2.0/admin/part-csptest.php (added)
-
tags/2.0/admin/wpCSPadmin.php (added)
-
tags/2.0/css (added)
-
tags/2.0/css/wpCSPadmin.css (added)
-
tags/2.0/includes (added)
-
tags/2.0/includes/wpCSPclass.php (added)
-
tags/2.0/js (added)
-
tags/2.0/js/wpCSPadmin.js (added)
-
tags/2.0/readme.txt (added)
-
tags/2.0/uninstall.php (added)
-
tags/2.0/wp-content-security-policy.php (added)
-
trunk/admin/part-cspcontrol.php (added)
-
trunk/admin/part-cspheaders.php (added)
-
trunk/admin/part-cspoptions.php (added)
-
trunk/admin/part-cspsavechanges.php (added)
-
trunk/admin/part-csptest.php (added)
-
trunk/admin/wpCSPadmin.php (modified) (14 diffs)
-
trunk/css/wpCSPadmin.css (modified) (4 diffs)
-
trunk/includes/wpCSPclass.php (modified) (7 diffs)
-
trunk/js/wpCSPadmin.js (modified) (1 diff)
-
trunk/readme.txt (modified) (7 diffs)
-
trunk/wp-content-security-policy.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
wp-content-security-policy/trunk/admin/wpCSPadmin.php
r1772554 r1776322 19 19 * @return WP_Error|boolean 20 20 */ 21 public function permissions_check_edit_posts( $request ) {21 public static function permissions_check_edit_posts( $request ) { 22 22 return current_user_can( 'edit_posts' ); 23 23 } … … 32 32 * @return WP_Error|boolean 33 33 */ 34 public function data_arg_sanitize_string_callback( $value, $request, $param ) {34 public static function data_arg_sanitize_string_callback( $value, $request, $param ) { 35 35 // It is as simple as returning the sanitized value. 36 36 return sanitize_text_field( $value ); … … 44 44 array( 45 45 'methods' => WP_REST_Server::CREATABLE, 46 'callback' => array( $this, 'RestAdmin' ),47 'permission_callback' => array( $this, 'permissions_check_edit_posts' ),46 'callback' => array( __CLASS__, 'RestAdmin' ), 47 'permission_callback' => array( __CLASS__, 'permissions_check_edit_posts' ), 48 48 'args' => array( 49 49 'subaction' => array( … … 56 56 'required' => false, 57 57 'type' => 'string', 58 "sanitize_callback" => array( $this, 'data_arg_sanitize_string_callback' ),58 "sanitize_callback" => array( __CLASS__, 'data_arg_sanitize_string_callback' ), 59 59 'description' => '', 60 60 ), … … 62 62 'required' => false, 63 63 'type' => 'string', 64 "sanitize_callback" => array( $this, 'data_arg_sanitize_string_callback' ),64 "sanitize_callback" => array( __CLASS__, 'data_arg_sanitize_string_callback' ), 65 65 'description' => '', 66 66 ), … … 68 68 'required' => false, 69 69 'type' => 'string', 70 "sanitize_callback" => array( $this, 'data_arg_sanitize_string_callback' ),70 "sanitize_callback" => array( __CLASS__, 'data_arg_sanitize_string_callback' ), 71 71 'description' => '', 72 72 ), … … 74 74 'required' => false, 75 75 'type' => 'string', 76 "sanitize_callback" => array( $this, 'data_arg_sanitize_string_callback' ),76 "sanitize_callback" => array( __CLASS__, 'data_arg_sanitize_string_callback' ), 77 77 'description' => '', 78 78 ), … … 80 80 'required' => false, 81 81 'type' => 'string', 82 "sanitize_callback" => array( $this, 'data_arg_sanitize_string_callback' ),82 "sanitize_callback" => array( __CLASS__, 'data_arg_sanitize_string_callback' ), 83 83 'description' => '', 84 84 ), … … 86 86 'required' => false, 87 87 'type' => 'string', 88 "sanitize_callback" => array( $this, 'data_arg_sanitize_string_callback' ),88 "sanitize_callback" => array( __CLASS__, 'data_arg_sanitize_string_callback' ), 89 89 'description' => '', 90 90 ), … … 104 104 add_action( 'wpCSPAdmin_daily_event', array(__CLASS__,'daily_maintenance') ); 105 105 106 wp_enqueue_script('jquery-ui-core', array( 'jquery' )); 107 wp_enqueue_script('jquery-ui-tabs', array( 'jquery-ui-core' )); 108 wp_enqueue_style( 'jquery-ui', '//ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/themes/base/jquery-ui.css'); 106 109 107 110 register_uninstall_hook(__FILE__, array(__CLASS__,"plugin_uninstall") ); … … 154 157 // Make sure the database table exists. 155 158 self::update_database() ; 159 global $options; 156 160 $options = get_option( wpCSPclass::SETTINGS_OPTIONS_ALLOPTIONS ); 157 158 $ErrorOutput = array() ; 161 162 // Go through the options looking for errors. 163 $PolicyKeyErrors = array() ; 164 $ErrorOutput = array() ; 159 165 foreach( wpCSPclass::$CSP_Policies as $PolicyKey => $CSPPolicy) : 160 166 $selected = !empty( $options[ $PolicyKey ] ) ? $options[ $PolicyKey ] : '' ; … … 162 168 $Errors = self::FindCSPErrors( $PolicyKey, $CSPOptions ); 163 169 if ( !empty( $Errors )) { 164 $ErrorOutput[] = "<tr><td><a href='#anchor". $PolicyKey ."'>".$PolicyKey."</a></td><td><ul><li>". implode("</li><li>",$Errors) . "</li></ul></td></tr>" ; 170 $PolicyKeyErrors[ $PolicyKey ] = "<ul><li>". implode("</li><li>",$Errors) . "</li></ul>"; 171 $ErrorOutput[] = "<tr><td><a href='#anchor". $PolicyKey ."'>".$PolicyKey."</a></td><td>".$PolicyKeyErrors[ $PolicyKey ]."</td></tr>" ; 165 172 } 166 endforeach; 173 endforeach; 174 175 $selected = !empty( $options[ wpCSPclass::SETTINGS_OPTIONS_VIOLATIONSTOIGNORE ] ) ? $options[ wpCSPclass::SETTINGS_OPTIONS_VIOLATIONSTOIGNORE ] : ''; 176 $CSPOptions = wpCSPclass::CleanPolicyOptionText( $selected ) ; 177 $Errors = self::FindCSPErrors( 'URLSToIgnore', $CSPOptions ); 178 if ( !empty( $Errors )) { 179 $PolicyKeyErrors[ 'URLSToIgnore'] = "<ul><li>". implode("</li><li>",$Errors) . "</li></ul>"; 180 $ErrorOutput[] = "<tr><td><a href='#anchor". $PolicyKey ."'>".$PolicyKey."</a></td><td>".$PolicyKeyErrors[ 'URLSToIgnore' ]."</td></tr>" ; 181 } 182 183 if ( !empty( $options[ wpCSPclass::SETTINGS_OPTIONS_REPORT_URI_REPORTONLY] ) ) { 184 $ReportURI = $options[ wpCSPclass::SETTINGS_OPTIONS_REPORT_URI_REPORTONLY] ; 185 if ( !filter_var($ReportURI, FILTER_VALIDATE_URL)) { 186 $PolicyKeyErrors[ wpCSPclass::SETTINGS_OPTIONS_REPORT_URI_REPORTONLY] = "REPORT-URI url invalid: $ReportURI"; 187 $ErrorOutput[] = "<tr><td>REPORT-URI - Report Only</td><td>".$PolicyKeyErrors[ wpCSPclass::SETTINGS_OPTIONS_REPORT_URI_REPORTONLY ]."</td></tr>" ; 188 } 189 } 190 if ( !empty( $options[ wpCSPclass::SETTINGS_OPTIONS_REPORT_URI_ENFORCE] ) ) { 191 $ReportURI = $options[ wpCSPclass::SETTINGS_OPTIONS_REPORT_URI_ENFORCE] ; 192 if ( !filter_var($ReportURI, FILTER_VALIDATE_URL)) { 193 $PolicyKeyErrors[ wpCSPclass::SETTINGS_OPTIONS_REPORT_URI_ENFORCE] = "REPORT-URI url invalid: $ReportURI"; 194 $ErrorOutput[] = "<tr><td>REPORT-URI - Enforce</td><td>".$PolicyKeyErrors[ wpCSPclass::SETTINGS_OPTIONS_REPORT_URI_ENFORCE]."</td></tr>" ; 195 } 196 } 197 198 if ( isset( $options[ wpCSPclass::SETTINGS_OPTIONS_FRAME_OPTIONS] ) && 3 == $options[ wpCSPclass::SETTINGS_OPTIONS_FRAME_OPTIONS] ) { 199 $AllowFromURL = $options[ wpCSPclass::SETTINGS_OPTIONS_FRAME_OPTIONS_ALLOW_FROM ] ; 200 if ( !filter_var($AllowFromURL, FILTER_VALIDATE_URL)) { 201 $PolicyKeyErrors[ wpCSPclass::SETTINGS_OPTIONS_FRAME_OPTIONS_ALLOW_FROM ] = "ALLOW-FROM url invalid: $AllowFromURL"; 202 $ErrorOutput[] = "<tr><td>X-Frame-Options</td><td>".$PolicyKeyErrors[ wpCSPclass::SETTINGS_OPTIONS_FRAME_OPTIONS_ALLOW_FROM ]."</td></tr>" ; 203 } 204 } 205 $selected = isset( $options[ wpCSPclass::SETTINGS_OPTIONS_CSP_MODE ] ) ? $options[ wpCSPclass::SETTINGS_OPTIONS_CSP_MODE ] : '' ; 206 if ( $selected == '' || $selected == -1 ){ 207 208 $PolicyKeyErrors[ wpCSPclass::SETTINGS_OPTIONS_CSP_MODE ] = "CSP is currently turned off"; 209 $ErrorOutput[] = "<tr><td>CSP Mode</td><td>".$PolicyKeyErrors[ wpCSPclass::SETTINGS_OPTIONS_CSP_MODE]."</td></tr>" ; 210 } 167 211 ?> 168 <div class="wrap"> 169 <div class="wpcsp-wpcspadmin wpcsp-optionsadmin"> 170 171 <?php if ( !empty( $_REQUEST['settings-updated'] ) ) : ?> 172 <div class="updated fade"><p><strong><?php _e( 'Content Security Policy Options saved!', 'wpcsp' ); ?></strong></p></div> 173 <?php endif; ?> 174 175 <h1><?php echo esc_html( get_admin_page_title() ); ?></h1> 176 <?php if ( !empty( $ErrorOutput )): ?> 177 <table class='wpcsp_option_errors'> 178 <thead><tr><td colspan='2'>Errors found in configuration:</td></tr></thead> 179 <tbody><?php echo implode("",$ErrorOutput);?></tbody> 180 </table> 181 <?php endif; ?> 182 183 <div id="wpcsp-poststuff"> 184 <div id="post-body"> 185 <div id="post-body-content"> 186 <form method="post" action="options.php"> 187 <?php settings_fields( wpCSPclass::SETTINGS_OPTIONS_SECTION ); // Outputs nonces and other necessary items?> 188 <table class="form-table"> 189 <tr class='wpcsp_option_row'><th scope="row"><?php _e( "Run in 'report only' mode?", 'wpcsp' ); ?></th> 190 <td class='wpcsp_option_cell'> 191 <select name="<?php echo wpCSPclass::SETTINGS_OPTIONS_ALLOPTIONS;?>[<?php echo wpCSPclass::SETTINGS_OPTIONS_REPORTONLY; ?>]" id="<?php echo wpCSPclass::SETTINGS_OPTIONS_REPORTONLY; ?>"> 192 <?php $selected = $options[ wpCSPclass::SETTINGS_OPTIONS_REPORTONLY ]; ?> 193 <option value="0" <?php selected( $selected, 0 ); ?> >Enforce policies</option> 194 <option value="1" <?php selected( $selected, 1 ); ?> >Report only - do not enforce policies</option> 195 </select> 196 <label class="wpcsp_option_description" for="<?php echo wpCSPclass::SETTINGS_OPTIONS_REPORTONLY; ?>"><?php _e( 'Toggles whether or not to run in report only mode or cause the browsers to enforce the security policy.', 'wpcsp' ); ?></label> 197 </td> 198 </tr> 199 <tr class='wpcsp_option_row'><th scope="row"><?php _e( "Log violations?", 'wpcsp' ); ?></th> 200 <td class='wpcsp_option_cell'> 201 <select name="<?php echo wpCSPclass::SETTINGS_OPTIONS_ALLOPTIONS;?>[<?php echo wpCSPclass::SETTINGS_OPTIONS_LOGVIOLATIONS; ?>]" id="<?php echo wpCSPclass::SETTINGS_OPTIONS_LOGVIOLATIONS; ?>"> 202 <?php $selected = $options[ wpCSPclass::SETTINGS_OPTIONS_LOGVIOLATIONS]; ?> 203 <option value="<?php echo wpCSPclass::LOGVIOLATIONS_IGNORE; ?>" <?php selected( $selected, wpCSPclass::LOGVIOLATIONS_IGNORE ); ?> >No, ignore</option> 204 <option value="<?php echo wpCSPclass::LOGVIOLATIONS_LOG_ALL; ?>" <?php selected( $selected, wpCSPclass::LOGVIOLATIONS_LOG_ALL ); ?> >Yes, log all</option> 205 <option value="<?php echo wpCSPclass::LOGVIOLATIONS_LOG_10PERC; ?>" <?php selected( $selected, wpCSPclass::LOGVIOLATIONS_LOG_10PERC ); ?> >Yes, log for 10% of page loads</option> 206 <option value="<?php echo wpCSPclass::LOGVIOLATIONS_LOG_1PERC; ?>" <?php selected( $selected, wpCSPclass::LOGVIOLATIONS_LOG_1PERC ); ?> >Yes, log for 1% of page loads</option> 207 <option value="<?php echo wpCSPclass::LOGVIOLATIONS_LOG_POINT1PERC; ?>" <?php selected( $selected, wpCSPclass::LOGVIOLATIONS_LOG_POINT1PERC ); ?> >Yes, log for 0.1% of page loads</option> 208 209 </select> 210 <label class="wpcsp_option_description" for="<?php echo wpCSPclass::SETTINGS_OPTIONS_LOGVIOLATIONS; ?>"><?php _e( 'Whether to store the CSP violations or ignore them. Logging can be a system drain, you can lower the number of log entries by not logging errors on all page loads.', 'wpcsp' ); ?></label> 211 </td> 212 </tr> 213 <tr class='wpcsp_option_row'><th scope="row"><?php _e( "Mixed Content", 'wpcsp' ); ?></th> 214 <td class='wpcsp_option_cell'> 215 <select name="<?php echo wpCSPclass::SETTINGS_OPTIONS_ALLOPTIONS;?>[<?php echo wpCSPclass::SETTINGS_OPTIONS_MIXED_CONTENT; ?>]" id="<?php echo wpCSPclass::SETTINGS_OPTIONS_MIXED_CONTENT; ?>"> 216 <?php $selected = $options[ wpCSPclass::SETTINGS_OPTIONS_MIXED_CONTENT]; ?> 217 <option value="" <?php selected( $selected, ""); ?> >None</option> 218 <option value="<?php echo wpCSPclass::BLOCK_ALL_MIXED_CONTENT; ?>" <?php selected( $selected, wpCSPclass::BLOCK_ALL_MIXED_CONTENT); ?> >Block Mixed Content</option> 219 <option value="<?php echo wpCSPclass::UPGRADE_INSECURE_REQUESTS; ?>" <?php selected( $selected, wpCSPclass::UPGRADE_INSECURE_REQUESTS); ?> >Upgrade Insecure Requests</option> 220 </select> 221 <label class="wpcsp_option_description" for="<?php echo wpCSPclass::SETTINGS_OPTIONS_LOGVIOLATIONS; ?>"><?php _e( "Block Mixed Content - All mixed content resource requests are blocked, including both active and passive mixed content. This also applies to <iframe> documents, ensuring the entire page is mixed content free.<br>upgrade-insecure-requests directive instructs user agents to treat all of a site's insecure URLs (those served over HTTP) as though they have been replaced with secure URLs (those served over HTTPS).", 'wpcsp' ); ?></label> 222 </td> 223 </tr> 224 225 <tr><th scope="row"><?php _e( "Policy Entries", 'wpcsp' ); ?></th> 226 <td><p>Content Security Policy allows the following entries - one per line:</p> 227 <table> 228 <tr><td>*</td><td>Allow Anything (try to avoid)</td></tr> 229 <tr><td>'none'</td><td>Allow nothing</td></tr> 230 <tr><td>'self'</td><td>Allow from the same domain (scheme and host) only</td></tr> 231 <tr><td>'unsafe-inline'</td><td>Allow use of inline source elements - scripts, fonts, etc.</td></tr> 232 <tr><td>'unsafe-eval'</td><td>Allow unsafe execution of evaluated javascript code.</td></tr> 233 <tr><td>'strict-dynamic'</td><td>The trust explicitly given to a script present in the markup, by accompanying it with a nonce or a hash, shall be propagated to all the scripts loaded by that root script.</td></tr> 234 <tr><td>data:</td><td>Allow loading resource from data scheme</td></tr> 235 <tr><td>https:</td><td>Allow loading resource over a secure connection from any domain (block insecure content)</td></tr> 236 <tr><td>domain.example.com</td><td>Allow loading resource from this specific domain, any scheme</td></tr> 237 <tr><td>*.example.com</td><td>Allow loading resource from any subdomain of the specified domain</td></tr> 238 <tr><td>http://domain.example.com</td><td>Allow loading resource from this specific domain and this scheme</td></tr> 239 </table> 240 </td></tr> 241 <?php 242 foreach( wpCSPclass::$CSP_Policies as $PolicyKey => $CSPPolicy) : 243 $selected = !empty( $options[ $PolicyKey ] ) ? $options[ $PolicyKey ] : '' ; 244 $CSPOptions = wpCSPclass::CleanPolicyOptionText( $selected ) ; 245 $selected = implode( PHP_EOL, array_unique( $CSPOptions ) ) ; 246 $Errors = self::FindCSPErrors( $PolicyKey, $CSPOptions ); 247 $RowsToDisplay = count( array_unique( $CSPOptions ) ) + 1 ; 248 if ( $RowsToDisplay < 3 ) { 249 $RowsToDisplay = 3 ; 250 } 251 ?> 252 <tr class='wpcsp_option_row'><th scope="row"><?php _e( $CSPPolicy['label'], 'wpcsp' ); ?></th> 253 <td class='wpcsp_option_cell'><a name='anchor<?php echo $PolicyKey;?>'></a> 254 <textarea name="<?php echo wpCSPclass::SETTINGS_OPTIONS_ALLOPTIONS;?>[<?php echo $PolicyKey;?>]" id="<?php echo $PolicyKey;?>" rows="<?php echo intval( $RowsToDisplay ) ;?>"><?php echo $selected;?></textarea><br /> 255 <label class="wpcsp_option_description" for="<?php echo $PolicyKey;?>" name='label<?php echo $PolicyKey; ?>'><?php esc_html( _e( $CSPPolicy['description'], 'wpcsp' ) ) ; ?></label> 256 <?php if ( !empty( $Errors )) :?><div class='wpcsp_option_errors'><ul><li><?php echo implode("</li><li>",$Errors) ;?></li></ul></div><?php endif; ?> 257 </td> 258 </tr> 259 <?php 260 endforeach; ?> 261 <tr class='wpcsp_option_row'><th scope="row"><?php _e( 'URLs to Ignore', 'wpcsp' ); ?></th> 262 <td class='wpcsp_option_cell'> 263 <?php 264 $selected = !empty( $options[ wpCSPclass::SETTINGS_OPTIONS_VIOLATIONSTOIGNORE ] ) ? $options[ wpCSPclass::SETTINGS_OPTIONS_VIOLATIONSTOIGNORE ] : ''; 265 $CSPOptions = wpCSPclass::CleanPolicyOptionText( $selected ) ; 266 $selected = implode( PHP_EOL, array_unique( $CSPOptions ) ) ; 267 $Errors = self::FindCSPErrors( 'URLSToIgnore', $CSPOptions ); 268 ?> 269 <textarea name="<?php echo wpCSPclass::SETTINGS_OPTIONS_ALLOPTIONS;?>[<?php echo wpCSPclass::SETTINGS_OPTIONS_VIOLATIONSTOIGNORE;?>]" id="<?php echo wpCSPclass::SETTINGS_OPTIONS_VIOLATIONSTOIGNORE;?>"><?php echo $selected;?></textarea><br /> 270 <label class="wpcsp_option_description" for="<?php echo wpCSPclass::SETTINGS_OPTIONS_VIOLATIONSTOIGNORE;?>"><?php _e( 'Ignore violations from these URLs', 'wpcsp' ); ?></label> 271 <?php if ( !empty( $Errors )) :?><div class='wpcsp_option_errors'><ul><li><?php echo implode("</li><li>",$Errors) ;?></li></ul></div><?php endif; ?> 272 </td> 273 </tr> 274 275 <tr class='wpcsp_option_row'><th scope="row"><?php _e( 'Sandbox', 'wpcsp' ); ?></th> 276 <td class='wpcsp_option_cell'> 277 <?php 278 $SandboxOptions = array( 279 wpCSPclass::SETTINGS_OPTIONS_SANDBOX_NOTSET => 'Not Set' , 280 wpCSPclass::SETTINGS_OPTIONS_SANDBOX_BLANKENTRY => 'Most Restrictive Sandbox' , // pseudo element I made up. 281 "allow-forms" => 'allow-forms' , 282 "allow-pointer-lock" => 'allow-pointer-lock' , 283 "allow-popups" => 'allow-popups' , 284 "allow-same-origin" => 'allow-same-origin' , 285 "allow-scripts" => 'allow-scripts' , 286 "allow-top-navigation" => 'allow-top-navigation' , ) ; 287 ?> 288 <select name="<?php echo wpCSPclass::SETTINGS_OPTIONS_ALLOPTIONS;?>[<?php echo wpCSPclass::SETTINGS_OPTIONS_SANDBOX; ?>][]" 289 id="<?php echo wpCSPclass::SETTINGS_OPTIONS_SANDBOX; ?>" class='wpcsp-selectpolicysandbox' multiple="multiple" size="7"> 290 <?php 291 $CurrentOptions = !empty( $options[ wpCSPclass::SETTINGS_OPTIONS_SANDBOX ] ) ? $options[ wpCSPclass::SETTINGS_OPTIONS_SANDBOX ] : ''; 292 foreach( $SandboxOptions as $key => $option ) : 293 if ( is_array( $CurrentOptions )) { 294 $selected = in_array( $key, $CurrentOptions ) ? ' selected="selected" ' : '' ; 295 } 296 else{ 297 $selected = $key == '' ? ' selected="selected" ' : '' ; 298 }?> 299 <option value="<?php echo $key; ?>" <?php echo $selected; ?> ><?php echo $option; ?></option> 300 <?php endforeach; ?> 301 </select> 302 <label class="wpcsp_option_description" for="<?php echo wpCSPclass::SETTINGS_OPTIONS_SANDBOX;?>"><?php _e( "HTML5 defines a sandbox attribute for iframe elements, intended to allow web authors to reduce the risk of including potentially untrusted content by imposing restrictions on that content's abilities. When the attribute is set, the content is forced into a unique origin, prevented from submitting forms, running script, creating or navigating other browsing contexts, and prevented from running plugins. These restrictions can be loosened by setting certain flags as the attribute's value.", 'wpcsp' ); ?></label> 303 </td> 304 </tr> 305 306 <tr class='wpcsp_option_row'><th scope="row"><?php _e( "Save Changes", 'wpcsp' ); ?></th> 307 <td><input type="submit" class="button-primary" value="<?php _e('Save Changes','wpcsp') ?>" /></td> 308 </tr> 212 <div class="wrap"> 213 <div class="wpcsp-wpcspadmin wpcsp-optionsadmin"> 214 215 <h1><?php echo esc_html( get_admin_page_title() ); ?></h1> 216 217 <?php if ( !empty( $_REQUEST['settings-updated'] ) ) : ?> 218 <div class="updated fade"><p><strong><?php _e( 'Content Security Policy Options saved!', 'wpcsp' ); ?></strong></p></div> 219 <?php endif; ?> 220 221 <?php if ( !empty( $ErrorOutput )): ?> 222 <div class="updated fade"> 223 <table class='wpcsp_option_errors'> 224 <thead><tr><td colspan='2'>Errors found in configuration:</td></tr></thead> 225 <tbody><?php echo implode("",$ErrorOutput);?></tbody> 226 </table> 227 </div> 228 <?php endif; ?> 229 230 <form method="post" action="options.php"> 231 <?php settings_fields( wpCSPclass::SETTINGS_OPTIONS_SECTION ); // Outputs nonces and other necessary items?> 309 232 310 <tr class='wpcsp_test_row ' data-target='#btnWPCSPTestURLCheckerOutput'><th scope="row"> </th> 311 <td class="btnWPCSPTestURLChecker"><?php _e('Test URL Checker','wpcsp') ?> 312 <div id='btnWPCSPTestURLCheckerOutput'></div></td> 313 </tr> 314 </table> 315 </form> 316 </div> <!-- end post-body-content --> 317 </div> <!-- end post-body --> 318 </div> <!-- end poststuff --> 319 </div> 320 </div> 233 <div id="wpcsp_tabsAdmin" class='wpcsp_tabsAdmin'> 234 <ul> 235 <li><a href="#wpcsp_tabsAdmin_Control">CSP Control</a></li> 236 <li><a href="#wpcsp_tabsAdmin_CSP">Content Security Policies</a></li> 237 <li><a href="#wpcsp_tabsAdmin_Headers">Headers</a></li> 238 <li><a href="#wpcsp_tabsAdmin_Test">Test</a></li> 239 </ul> 240 <div id='wpcsp_tabsAdmin_Control'> 241 <?php include('part-cspcontrol.php'); ?> 242 <?php include('part-cspsavechanges.php'); ?> 243 </div> 244 <div id='wpcsp_tabsAdmin_CSP'> 245 <?php include('part-cspoptions.php'); ?> 246 <?php include('part-cspsavechanges.php'); ?> 247 </div> 248 <div id='wpcsp_tabsAdmin_Headers'> 249 <?php include('part-cspheaders.php'); ?> 250 <?php include('part-cspsavechanges.php'); ?> 251 </div> 252 <div id='wpcsp_tabsAdmin_Test'> 253 <?php include('part-csptest.php'); ?> 254 </div> 255 </div> 256 </form> 257 </div> 258 </div> <?php // end of class=wrap ?> 321 259 <?php 322 260 } … … 734 672 $StrippedPolicy = preg_replace("/[^a-zA-Z0-9\s]/", "", $Policy); 735 673 if ( $StrippedPolicy == 'self' && $Policy != "'self'") { 736 $return[] = "Entry for <strong>self</strong> should read <strong>'self'</strong> (with single quotes) - entry: " .$Policy ;674 $return[] = "Entry for <strong>self</strong> should read <strong>'self'</strong> (with single quotes) - Policy: " .$Policy ; 737 675 } 738 676 if ( $StrippedPolicy == 'unsafeinline' && $Policy != "'unsafe-inline'") { 739 $return[] = "Entry for <strong>unsafe-inline</strong> should read <strong>'unsafe-inline'</strong> (with single quotes) - entry: " .$Policy ;677 $return[] = "Entry for <strong>unsafe-inline</strong> should read <strong>'unsafe-inline'</strong> (with single quotes) - Policy: " .$Policy ; 740 678 } 741 679 if ( $StrippedPolicy == 'unsafeeval' && $Policy != "'unsafe-eval'") { 742 $return[] = "Entry for <strong>unsafe-eval</strong> should read <strong>'unsafe-eval'</strong> (with single quotes) - entry: " .$Policy ;680 $return[] = "Entry for <strong>unsafe-eval</strong> should read <strong>'unsafe-eval'</strong> (with single quotes) - Policy: " .$Policy ; 743 681 } 744 682 if ( $StrippedPolicy == 'none' && $Policy != "'none'") { 745 $return[] = "Entry for <strong>none</strong> should read <strong>'none'</strong> (with single quotes) - entry: " .$Policy ;683 $return[] = "Entry for <strong>none</strong> should read <strong>'none'</strong> (with single quotes) - Policy: " .$Policy ; 746 684 } 747 685 if ( $StrippedPolicy == 'strict-dynamic' && $Policy != "'strict-dynamic'") { 748 $return[] = "Entry for <strong>strict-dynamic</strong> should read <strong>'strict-dynamic'</strong> (with single quotes) - entry: " .$Policy ;686 $return[] = "Entry for <strong>strict-dynamic</strong> should read <strong>'strict-dynamic'</strong> (with single quotes) - Policy: " .$Policy ; 749 687 } 750 688 foreach( $SchemeTags as $SchemeTag ) { 751 689 if ( $StrippedPolicy == $SchemeTag && $Policy != $SchemeTag . ":") { 752 $return[] = "Entry for <strong>".$SchemeTag.":</strong> should read <strong>".$SchemeTag.":</strong> - entry: " .$Policy ;690 $return[] = "Entry for <strong>".$SchemeTag.":</strong> should read <strong>".$SchemeTag.":</strong> (with ending colon) - Policy: " .$Policy ; 753 691 } 754 692 } … … 932 870 } 933 871 934 $wpCSPAdmin = new wpCSPAdmin() ; 935 $wpCSPAdmin->init(); 872 add_action('init',array("wpCSPAdmin","init")); 936 873 // If action "rest_api_init" hasn't run yet then use that, otherwise we have the route server in place, just register route 937 874 if ( did_action('rest_api_init') == 0 ){ 938 add_action('rest_api_init',array( $wpCSPAdmin,"register_routes"));875 add_action('rest_api_init',array("wpCSPAdmin","register_routes")); 939 876 } 940 877 else { 941 $wpCSPAdmin->register_routes();878 wpCSPAdmin::register_routes(); 942 879 } -
wp-content-security-policy/trunk/css/wpCSPadmin.css
r1772554 r1776322 1 1 2 #wpcsp-poststufftextarea {2 .wpcsp-form-table textarea { 3 3 background-color: #fff; 4 4 min-height: 60px; … … 8 8 } 9 9 10 .wpcsp-form-table p{ 11 margin: 5px 0 1em 0; 12 } 13 10 14 .wpcsp-wpcspadmin label { 11 15 clear:both; … … 59 63 overflow: hidden; 60 64 } 65 .wpcsp_option_row th{ 66 padding-top: 10px; 67 pading-right:10px; 68 min-width: 200px; 69 text-align: right; 70 } 61 71 .wpcsp-wpcspadmin table { 62 72 border-collapse: collapse; … … 76 86 .wpcsp_option_errors{ 77 87 clear:both; 88 color:#ff0000; 78 89 } 79 90 .wpcsp_option_errors li{ 80 91 color:#ff0000; 81 92 } 82 .wpcsp_test_row td{83 border-top:300px solid transparent;84 font-size:smaller;85 }86 93 .wpscp_Cannot_Allow{ 87 94 display:inline-block; -
wp-content-security-policy/trunk/includes/wpCSPclass.php
r1772554 r1776322 12 12 const SETTINGS_OPTIONS_ALLOPTIONS = 'wpcsp_all_options' ; 13 13 14 const SETTINGS_OPTIONS_ REPORTONLY= 'wpcsp_reportonly' ;14 const SETTINGS_OPTIONS_CSP_MODE = 'wpcsp_reportonly' ; 15 15 const SETTINGS_OPTIONS_LOGVIOLATIONS = 'wpcsp_logviolations' ; 16 16 const SETTINGS_OPTIONS_VIOLATIONSTOIGNORE = 'wpcsp_ViolationsToIgnore' ; … … 19 19 const SETTINGS_OPTIONS_SANDBOX_NOTSET = '' ; 20 20 const SETTINGS_OPTIONS_MIXED_CONTENT = 'wpcsp_MixedContent'; 21 const SETTINGS_OPTIONS_EXPECTCT_OPTIONS = 'wpcsp_expectct_enforce' ; 22 const SETTINGS_OPTIONS_EXPECTCT_MAXAGE = 'wpcsp_expectct_maxage' ; 23 const SETTINGS_OPTIONS_STS_OPTIONS = 'wpcsp_sts_options' ; 24 const SETTINGS_OPTIONS_STS_MAXAGE = 'wpcsp_sts_maxage' ; 25 const SETTINGS_OPTIONS_FRAME_OPTIONS = 'wpcsp_frame_options' ; 26 const SETTINGS_OPTIONS_FRAME_OPTIONS_ALLOW_FROM = 'wpcsp_frame_options_allow_from' ; 27 const SETTINGS_OPTIONS_XSS_PROTECTION = 'wpcsp_xss_protection' ; 28 const SETTINGS_OPTIONS_CONTENT_TYPE_OPTIONS = 'wpcsp_content_type_options' ; 29 const SETTINGS_OPTIONS_REFERRER_POLICY_OPTIONS = 'wpcsp_referrer_policy_options' ; 30 const SETTINGS_OPTIONS_REPORT_URI_REPORTONLY = 'wpcsp_report_uri+reportonly' ; 31 const SETTINGS_OPTIONS_REPORT_URI_ENFORCE = 'wpcsp_report_uri_enforce' ; 21 32 22 33 const PLUGIN_TRIGGER = 'wpcspReceiveCSPviol'; … … 35 46 36 47 37 const HEADERTAG_ENFORCEPOLICY = 'Content-Security-Policy' ;38 const HEADERTAG_REPORTONLY = 'Content-Security-Policy-Report-Only';39 40 41 const ROUTE_VERSION = 1 ;42 48 const ROUTE_BASE = 'route'; 43 const ROUTE_NAMESPACE = 'wpcsp/v' . self::ROUTE_VERSION; 44 45 46 static $CSP_Policies = array( 'default-src' => array( 'label' => 'Default SRC' , 47 'description' => "The default-src is the default policy for loading content such as JavaScript, Images, CSS, Font's, AJAX requests, Frames, HTML5 Media." , 48 ), 49 const ROUTE_NAMESPACE = 'wpcsp/v1' ; 50 51 52 static $CSP_Policies = array( 53 'default-src' => array( 'label' => 'Default SRC' , 54 'description' => "The default-src is the default policy for loading content such as JavaScript, Images, CSS, Font's, AJAX requests, Frames, HTML5 Media." , 55 ), 49 56 'script-src' => array( 'label' => 'Script SRC' , 50 57 'description' => 'Defines valid sources of JavaScript.' , … … 138 145 */ 139 146 public static function add_header() { 140 147 // Find the user set options from the database 148 $options = get_option( self::SETTINGS_OPTIONS_ALLOPTIONS ); 149 150 151 $Nonce = wp_create_nonce( "wp_rest" ); 152 $ReportURI_ReportOnlyBase = site_url( "/wp-json/" . wpCSPclass::ROUTE_NAMESPACE . "/" . wpCSPclass::ROUTE_BASE . "/LogPolicyViolation" ) ; 153 $ReportURI_ThisServer = add_query_arg( array("_wpnonce" => $Nonce), $ReportURI_ReportOnlyBase) ; 154 155 // Work out the report URI - used a few times in the settings. 156 if ( empty( $options[ self::SETTINGS_OPTIONS_REPORT_URI_REPORTONLY ])){ 157 $Nonce = wp_create_nonce( "wp_rest" ); 158 $ReportURI_ReportOnly = $ReportURI_ThisServer ; 159 } 160 else { 161 $ReportURI_ReportOnly = $options[ self::SETTINGS_OPTIONS_REPORT_URI_REPORTONLY] ; 162 } 163 164 if ( empty( $options[ self::SETTINGS_OPTIONS_REPORT_URI_ENFORCE ])){ 165 $ReportURI_Enforce = $ReportURI_ThisServer ; 166 } 167 else { 168 $ReportURI_Enforce = $options[ self::SETTINGS_OPTIONS_REPORT_URI_ENFORCE ] ; 169 } 170 171 // Work out the content security policy settings. 141 172 $CSPOutput = array() ; 142 $options = get_option( self::SETTINGS_OPTIONS_ALLOPTIONS );143 173 foreach( wpCSPclass::$CSP_Policies as $PolicyKey => $CSPPolicy) { 144 174 $CSPOption = self::CleanPolicyOptionText( $options[$PolicyKey] ); … … 188 218 } 189 219 } 190 $ReportOnly = $options[ self::SETTINGS_OPTIONS_REPORTONLY];191 $CSPHeaderTag = !empty( $ReportOnly ) ? self::HEADERTAG_REPORTONLY : self::HEADERTAG_ENFORCEPOLICY;192 220 193 221 // Do we want the browser to log the violations with the server, or only block without logging? … … 216 244 break ; 217 245 } 218 // We want to log violations - set the correct URL to log the errors. 219 if ( $LogViolations === true || !empty( $ReportOnly ) ) { 220 $Nonce = wp_create_nonce( "wp_rest" ); 221 $ReportURIBase = site_url( "/wp-json/" . wpCSPclass::ROUTE_NAMESPACE . "/" . wpCSPclass::ROUTE_BASE . "/LogPolicyViolation" ) ; 222 $URLParams = array("_wpnonce" => $Nonce); 223 $ReportURI = add_query_arg( $URLParams, $ReportURIBase) ; 224 $CSPOutput[] = "report-uri " . $ReportURI ; 225 } 246 226 247 // Output the CSP header 227 header($CSPHeaderTag . ": " . implode( "; ", $CSPOutput )); 248 $ReportOnly = isset( $options[ self::SETTINGS_OPTIONS_CSP_MODE] ) ? $options[ self::SETTINGS_OPTIONS_CSP_MODE ] : 0; 249 switch( $ReportOnly ) { 250 case "": 251 case -1: // Not In use - -1 because this was added after 0/1 were allocated. 252 break ; 253 case 0: 254 // We want to log violations - set the correct URL to log the errors. 255 if ( $LogViolations === true ) { 256 $CSPOutput[] = "report-uri " . $ReportURI_Enforce ; 257 } 258 header("Content-Security-Policy: " . implode( "; ", $CSPOutput )); 259 break ; 260 case 1: 261 if ( $LogViolations === true ) { 262 $CSPOutput[] = "report-uri " . $ReportURI_ReportOnly ; 263 } 264 header("Content-Security-Policy-Report-Only: " . implode( "; ", $CSPOutput )); 265 break ; 266 } 267 268 // Ensure all the header options are set before continuing. 269 $HeaderOptions = array( wpCSPclass::SETTINGS_OPTIONS_EXPECTCT_OPTIONS, wpCSPclass::SETTINGS_OPTIONS_STS_OPTIONS, wpCSPclass::SETTINGS_OPTIONS_FRAME_OPTIONS, 270 wpCSPclass::SETTINGS_OPTIONS_XSS_PROTECTION, wpCSPclass::SETTINGS_OPTIONS_CONTENT_TYPE_OPTIONS, wpCSPclass::SETTINGS_OPTIONS_REFERRER_POLICY_OPTIONS , 271 wpCSPclass::SETTINGS_OPTIONS_EXPECTCT_MAXAGE, wpCSPclass::SETTINGS_OPTIONS_STS_MAXAGE, 272 ) ; 273 foreach( $HeaderOptions as $HeaderOption ) { 274 if ( !isset( $options[ $HeaderOption ] ) || !is_numeric( $options[ $HeaderOption ] )){ 275 $options[ $HeaderOption ] = 0 ; 276 } 277 } 278 279 // Find the other header options. 280 $ExpectCTMaxAge = intval( $options[ wpCSPclass::SETTINGS_OPTIONS_EXPECTCT_MAXAGE] ) ; 281 $STSMaxAge = intval( $options[ wpCSPclass::SETTINGS_OPTIONS_STS_MAXAGE] ) ; 282 switch($options[ wpCSPclass::SETTINGS_OPTIONS_EXPECTCT_OPTIONS ] ) { 283 case "": 284 case 0: 285 break ; 286 case 1: // Report only - do not enforce Expect CT 287 header( "Expect-CT: max-age=$ExpectCTMaxAge,report-uri=$ReportURI_ReportOnly" ); 288 break ; 289 case 2: // Enforce Expect CT 290 header( "Expect-CT: enforce,max-age=$ExpectCTMaxAge,report-uri=$ReportURI_ReportOnly" ); 291 break ; 292 } 293 switch($options[ wpCSPclass::SETTINGS_OPTIONS_STS_OPTIONS] ) { 294 case "": 295 case 0: 296 break ; 297 case 1: // Use with no options 298 header( "Strict-Transport-Security: max-age=$STSMaxAge" ); 299 break ; 300 case 2: // Include Sub Domains 301 header( "Strict-Transport-Security: max-age=$STSMaxAge; includeSubDomains" ); 302 break ; 303 case 3: // Preload 304 header( "Strict-Transport-Security: max-age=$STSMaxAge; preload" ); 305 break ; 306 } 307 switch( $options[ wpCSPclass::SETTINGS_OPTIONS_FRAME_OPTIONS] ) { 308 case "": 309 case 0: 310 break ; 311 case 1: // DENY 312 header( "X-Frame-Options: DENY" ); 313 break ; 314 case 2: // SAMEORIGIN 315 header( "X-Frame-Options: SAMEORIGIN" ); 316 break ; 317 case 3: // ALLOW-FROM 318 $AllowFromURL = $options[ wpCSPclass::SETTINGS_OPTIONS_FRAME_OPTIONS_ALLOW_FROM ] ; 319 header( "X-Frame-Options: ALLOW-FROM $AllowFromURL" ); 320 break ; 321 } 322 switch($options[ wpCSPclass::SETTINGS_OPTIONS_XSS_PROTECTION] ) { 323 case "": 324 case 0: 325 break ; 326 case 1: // 0 - Disable Filtering 327 header( "X-XSS-Protection: 0" ); 328 break ; 329 case 2: // 1 - Enable Filtering 330 header( "X-XSS-Protection: 1" ); 331 break ; 332 case 3: // 1; mode=block 333 header( "X-XSS-Protection: 1; mode=block" ); 334 break ; 335 case 4: // 1; report 336 header( "X-XSS-Protection: 1; report=$ReportURI_Enforce" ); 337 break ; 338 } 339 switch($options[ wpCSPclass::SETTINGS_OPTIONS_CONTENT_TYPE_OPTIONS] ) { 340 case "": 341 case 0: 342 break ; 343 case 1: //NOSNIFF 344 header( "X-Content-Type-Options: nosniff"); 345 break ; 346 } 347 switch( $options[ wpCSPclass::SETTINGS_OPTIONS_REFERRER_POLICY_OPTIONS] ) { 348 case "": 349 case 0: 350 break ; 351 case 1: // no-referrer 352 header( "Referrer-Policy: no-referrer" ); 353 break ; 354 case 2: // no-referrer-when-downgrade 355 header( "Referrer-Policy: no-referrer-when-downgrade" ); 356 break ; 357 case 3: // origin 358 header( "Referrer-Policy: origin" ); 359 break ; 360 case 4: // origin-when-cross-origin 361 header( "Referrer-Policy: origin-when-cross-origin" ); 362 break ; 363 case 5: // same-origingin 364 header( "Referrer-Policy: same-origin" ); 365 break ; 366 case 6: // strict-origin 367 header( "Referrer-Policy: strict-origin" ); 368 break ; 369 case 7: // strict-origin-when-cross-origin 370 header( "Referrer-Policy: strict-origin-when-cross-origin" ); 371 break ; 372 case 8: // unsafe-url (not recommended) 373 header( "Referrer-Policy: unsafe-url" ); 374 break ; 375 } 228 376 } 229 377 … … 556 704 } 557 705 } 558 $wpCSPclass = new wpCSPclass() ; 559 $wpCSPclass->init(); 706 707 708 add_action('init',array("wpCSPclass","init")); 560 709 // If action "rest_api_init" hasn't run yet then use that, otherwise we have the route server in place, just register route 561 710 if ( did_action('rest_api_init') == 0 ){ 562 add_action('rest_api_init',array( $wpCSPclass,"register_routes"));711 add_action('rest_api_init',array("wpCSPclass","register_routes")); 563 712 } 564 713 else { 565 $wpCSPclass->register_routes();714 wpCSPclass::register_routes(); 566 715 } -
wp-content-security-policy/trunk/js/wpCSPadmin.js
r1771898 r1776322 1 1 jQuery(document).ready(function(){ 2 2 WPCSPHandleLogAdmin(); 3 jQuery('#wpcsp_tabsAdmin').tabs(); 3 4 }); 4 5 jQuery(document).on('change','.WPCSPBlockedURLPath, .WPCSPBlockedURLFile', WPCSPHandleLogAdmin ); -
wp-content-security-policy/trunk/readme.txt
r1772554 r1776322 5 5 Requires at least: 4.8 6 6 Tested up to: 4.9 7 Stable tag: 1.97 Stable tag: 2.0 8 8 License: GPLv2 or later 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 16 16 longer your application running on your site, and opens your whole domain to attack due to "Same-Origin Policy" - XSS anywhere on your domain is XSS everywhere on your domain. (see https://www.youtube.com/watch?v=WljJ5guzcLs) 17 17 18 CSP tell your browser to push least-privilege environment on your application, allowing the client to only use resources from trusted domains and block all resources from anywhere else.19 20 Adding CSP to your site will protect your visitors from 18 CSP tells your browser to push least-privilege environment on your application, allowing the client to only use resources from trusted domains and block all resources from anywhere else. 19 20 Adding CSP to your site will protect your visitors from: 21 21 22 22 * Cross-site scripting (XSS) attacks 23 23 * Adware and Spyware while on your site 24 24 25 = Directives = 26 27 CSP allows you to control where your visitors' browser is allowed to run code from. The W3C specification allows for 9 directives. 25 This plugin will help you set your CSP settings and will add them to the page the visitor requested. Policy violations will be logged in a database table which can be viewed via an admin page that supplies all the violations, along with counts. Buttons easily allow you to add the sites to your headers or to ignore them. 26 27 This plugin also allows you to ignore sites that repeatedly violate your policies. For example, some tracking images will show as violating your policies but you still don't want them to run, therefore you can block the site from showing up in your logs - note, however, that the browser will still call your server and your server will still spend resources processing the call. 28 29 = CSP Directives = 30 31 CSP allows you to control where your visitors' browser is allowed to run code from. The W3C specification allows for the following directives. 28 32 29 33 * **default-src**<br> … … 42 46 Applies to XMLHttpRequest (AJAX), WebSocket or EventSource. 43 47 48 * **manifest-src**<br> 49 Specifies which manifest can be applied to the resource 50 51 * **worker-src**<br> 52 Specifies valid sources for Worker, SharedWorker, or ServiceWorker scripts. 53 44 54 * **font-src**<br> 45 55 Defines valid sources of fonts. … … 69 79 URL to post information on violations of the policies you set. 70 80 81 = CSP Entry Syntax = 82 71 83 Each directive can take one or more of the following values: 72 84 … … 75 87 76 88 * **'none'**<br> 77 Blocks loading resources from all sources. 89 Blocks loading resources from all sources. The single quotes are required. 78 90 79 91 * **'self'**<br> 80 Refers to your own host. 92 Refers to your own host. The single quotes are required. 81 93 82 94 * **'unsafe-inline'**<br> 83 Allows inline elements, such as functions in script tags, onclicks, etc. 95 Allows inline elements, such as functions in script tags, onclicks, etc. The single quotes are required. 84 96 85 97 * **'unsafe-eval'**<br> 86 Allows unsafe dynamic code evaluation such as JavaScript eval() 98 Allows unsafe dynamic code evaluation such as JavaScript eval(). The single quotes are required. 99 100 * **'strict-dynamic'**<br> 101 The trust explicitly given to a script present in the markup, by accompanying it with a nonce or a hash, shall be propagated to all the scripts loaded by that root script. The single quotes are required. The single quotes are required. 87 102 88 103 * **data:**<br> 89 Allow loading resources from data scheme - usually inline images. 90 104 Allow loading resources from data scheme - usually inline images. **This is insecure**; an attacker can also inject arbitrary data: URIs. Use this sparingly and definitely not for scripts. 105 106 * **mediastream:**<br> 107 Allows mediastream: URIs to be used as a content source. 108 109 * **filesystem:**<br> 110 Allow loading resource from file system. 111 91 112 * **https:**<br> 92 Only allows loading resources from HTTPS: on any domain 113 Only allows loading resources from HTTPS: on any domain. This can be used to block insecure requests. 93 114 94 115 * **www.example.com**<br> … … 107 128 Allows loading this one file on this domain. 108 129 109 This plugin will help you set your CSP settings, and will add them to the page the visitor requested. Polivy violations will be logged in a database table. 110 An admin page is provided that supplies all the violations, along with counts. Buttons easily allow you to add the sites to your headers. 111 112 This plugin also allows you to ignore sites that repeatedly violate your policies. For example, some tracking images will show as violating your 113 policies but you still don't want them to run, therefore you can block the site from showing up in your logs. 130 = Security Headers = 131 132 In addition to the CSP headers, there are other security headers supported, including: 133 134 * **Expect-CT**<br> 135 Instructs user agents (browsers) to expect valid Signed Certificate Timestamps (SCTs) to be served. 136 137 * **Strict Transport Security**<br> 138 The HTTP Strict-Transport-Security response header (HSTS) lets a web site tell browsers that it should only be accessed using HTTPS, instead of using HTTP. 139 140 * **X-Frame-Options**<br> 141 The X-Frame-Options HTTP response header can be used to indicate whether or not a browser should be allowed to render a page in a <frame>, <iframe> or <object> . Sites can use this to avoid clickjacking attacks, by ensuring that their content is not embedded into other sites. 142 143 * **X-XSS-Protection**<br> 144 The HTTP X-XSS-Protection response header is a feature of Internet Explorer, Chrome and Safari that stops pages from loading when they detect reflected cross-site scripting (XSS) attacks. Although these protections are largely unnecessary in modern browsers when sites implement a strong Content-Security-Policy that disables the use of inline JavaScript ('unsafe-inline'), they can still provide protections for users of older web browsers that don't yet support CSP. 145 146 * **X-Content-Type-Options**<br> 147 The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised in the Content-Type headers should not be changed and be followed. This allows to opt-out of MIME type sniffing, or, in other words, it is a way to say that the webmasters knew what they were doing. 148 149 * **Referrer-Policy**<br> 150 The Referrer-Policy HTTP header governs which referrer information, sent in the Referer header, should be included with requests made. 114 151 115 152 == Installation == … … 146 183 Usually you would want to keep security as strict as possible while still allowing your application to run. Therefore, '*' should be avoided. 147 184 185 = No errors are getting logged = 186 187 1. First check that your site is producing CSP errors by starting the dev tools in your browser (usually F12) and checking whether anything is mentioned in the console output. 188 1. If nothing is in the console output then check the page has a CSP header by looking at the page in the 'network' tab of the dev tools. Check the 'response' has a header called 'content-security-policy' or 'content-security-policy-report-only' - if this is misisng then the plugin is not running or CSP is not enabled. 189 1. If there is a CSP header and nothing is reported in the console then you have no violations and everything is running as it should. 190 1. If there is a CSP header and errors in the console then the REST route might not be registered properly. Go to <your domain>/wp-json and look for 'wpcsp' (usually CTRL-F for find and type in wpcsp) - if nothing is listed then the REST route is not getting registered. 191 1. Look in the PHP error logs for an error - post the error, file name and line number in the support forums and I should be able to work out why it's failing. 192 148 193 == Changelog == 194 195 = 2.0 = 196 * Added support for various other security related header options 197 * Added ability to change URL violations are reported to 198 * Added validation of URLs entered 199 * Added ability to turn off CSP headers while keeping other security related headers 200 * Fixed issue when run on PHP below 5.6 (tested on PHP 5.3) 149 201 150 202 = 1.9 = -
wp-content-security-policy/trunk/wp-content-security-policy.php
r1772554 r1776322 4 4 Plugin URI: http://URI_Of_Page_Describing_Plugin_and_Updates 5 5 Description: Setup, output, and log content security policy information. 6 Version: 1.96 Version: 2.0 7 7 Author: Dylan Downhill 8 8 Author URI: http://www.elixirinteractive.com
Note: See TracChangeset
for help on using the changeset viewer.