Changeset 1772554
- Timestamp:
- 11/21/2017 07:04:03 PM (8 years ago)
- Location:
- wp-content-security-policy
- Files:
-
- 12 added
- 5 edited
-
tags/1.9 (added)
-
tags/1.9/admin (added)
-
tags/1.9/admin/wpCSPadmin.php (added)
-
tags/1.9/css (added)
-
tags/1.9/css/wpCSPadmin.css (added)
-
tags/1.9/includes (added)
-
tags/1.9/includes/wpCSPclass.php (added)
-
tags/1.9/js (added)
-
tags/1.9/js/wpCSPadmin.js (added)
-
tags/1.9/readme.txt (added)
-
tags/1.9/uninstall.php (added)
-
tags/1.9/wp-content-security-policy.php (added)
-
trunk/admin/wpCSPadmin.php (modified) (15 diffs)
-
trunk/css/wpCSPadmin.css (modified) (3 diffs)
-
trunk/includes/wpCSPclass.php (modified) (8 diffs)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/wp-content-security-policy.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
wp-content-security-policy/trunk/admin/wpCSPadmin.php
r1772018 r1772554 154 154 // Make sure the database table exists. 155 155 self::update_database() ; 156 $options = get_option( wpCSPclass::SETTINGS_OPTIONS_ALLOPTIONS ); 157 158 $ErrorOutput = array() ; 159 foreach( wpCSPclass::$CSP_Policies as $PolicyKey => $CSPPolicy) : 160 $selected = !empty( $options[ $PolicyKey ] ) ? $options[ $PolicyKey ] : '' ; 161 $CSPOptions = wpCSPclass::CleanPolicyOptionText( $selected ) ; 162 $Errors = self::FindCSPErrors( $PolicyKey, $CSPOptions ); 163 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>" ; 165 } 166 endforeach; 156 167 ?> 157 158 168 <div class="wrap"> 159 169 <div class="wpcsp-wpcspadmin wpcsp-optionsadmin"> … … 164 174 165 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; ?> 166 182 167 183 <div id="wpcsp-poststuff"> … … 169 185 <div id="post-body-content"> 170 186 <form method="post" action="options.php"> 171 <?php settings_fields( wpCSPclass::SETTINGS_OPTIONS_SECTION ); ?> 172 <?php $options = get_option( wpCSPclass::SETTINGS_OPTIONS_ALLOPTIONS ); ?> 187 <?php settings_fields( wpCSPclass::SETTINGS_OPTIONS_SECTION ); // Outputs nonces and other necessary items?> 173 188 <table class="form-table"> 174 189 <tr class='wpcsp_option_row'><th scope="row"><?php _e( "Run in 'report only' mode?", 'wpcsp' ); ?></th> … … 176 191 <select name="<?php echo wpCSPclass::SETTINGS_OPTIONS_ALLOPTIONS;?>[<?php echo wpCSPclass::SETTINGS_OPTIONS_REPORTONLY; ?>]" id="<?php echo wpCSPclass::SETTINGS_OPTIONS_REPORTONLY; ?>"> 177 192 <?php $selected = $options[ wpCSPclass::SETTINGS_OPTIONS_REPORTONLY ]; ?> 178 <option value="0" <?php selected( $selected, 0 ); ?> > No, enforce policies</option>179 <option value="1" <?php selected( $selected, 1 ); ?> > Yes, report only</option>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> 180 195 </select> 181 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> … … 196 211 </td> 197 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> 198 224 199 225 <tr><th scope="row"><?php _e( "Policy Entries", 'wpcsp' ); ?></th> … … 205 231 <tr><td>'unsafe-inline'</td><td>Allow use of inline source elements - scripts, fonts, etc.</td></tr> 206 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> 207 234 <tr><td>data:</td><td>Allow loading resource from data scheme</td></tr> 208 <tr><td>https:</td><td>Allow loading resource over a secure connection from any domain </td></tr>235 <tr><td>https:</td><td>Allow loading resource over a secure connection from any domain (block insecure content)</td></tr> 209 236 <tr><td>domain.example.com</td><td>Allow loading resource from this specific domain, any scheme</td></tr> 210 237 <tr><td>*.example.com</td><td>Allow loading resource from any subdomain of the specified domain</td></tr> … … 217 244 $CSPOptions = wpCSPclass::CleanPolicyOptionText( $selected ) ; 218 245 $selected = implode( PHP_EOL, array_unique( $CSPOptions ) ) ; 219 $Errors = self::FindCSPErrors( $CSPOptions ); 246 $Errors = self::FindCSPErrors( $PolicyKey, $CSPOptions ); 247 $RowsToDisplay = count( array_unique( $CSPOptions ) ) + 1 ; 248 if ( $RowsToDisplay < 3 ) { 249 $RowsToDisplay = 3 ; 250 } 220 251 ?> 221 252 <tr class='wpcsp_option_row'><th scope="row"><?php _e( $CSPPolicy['label'], 'wpcsp' ); ?></th> 222 <td class='wpcsp_option_cell'> 223 <textarea name="<?php echo wpCSPclass::SETTINGS_OPTIONS_ALLOPTIONS;?>[<?php echo $PolicyKey;?>]" id="<?php echo $PolicyKey;?>" ><?php echo $selected;?></textarea><br />224 <label class="wpcsp_option_description" for="<?php echo $PolicyKey;?>" ><?php esc_html( _e( $CSPPolicy['description'], 'wpcsp' ) ) ; ?></label>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> 225 256 <?php if ( !empty( $Errors )) :?><div class='wpcsp_option_errors'><ul><li><?php echo implode("</li><li>",$Errors) ;?></li></ul></div><?php endif; ?> 226 257 </td> … … 234 265 $CSPOptions = wpCSPclass::CleanPolicyOptionText( $selected ) ; 235 266 $selected = implode( PHP_EOL, array_unique( $CSPOptions ) ) ; 236 $Errors = self::FindCSPErrors( $CSPOptions );267 $Errors = self::FindCSPErrors( 'URLSToIgnore', $CSPOptions ); 237 268 ?> 238 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 /> … … 402 433 </td> 403 434 <td class='tdWPCSPActionButtons'> 404 <input type="button" class="button-primary btnWPCSPAddSafeDomain" value="<?php _e('Allow ' . strtoupper( $obj->violated_directive ) . ' Access' ,'wpcsp') ?>" /> 435 <?php if ( isset( wpCSPclass::$CSP_Policies[ $obj->violated_directive ] )) : ?> 436 <input type="button" class="button-primary btnWPCSPAddSafeDomain" value="<?php _e('Allow ' . strtoupper( $obj->violated_directive ) . ' Access' ,'wpcsp') ?>" /> 437 <?php else:?> 438 <div class='wpscp_Cannot_Allow'>No allow Option</div> 439 <?php endif; ?> 405 440 <input type="button" class="button-primary btnWPCSPIgnoreDomain" value="<?php _e('Ignore Domain Violations','wpcsp') ?>" /> 406 441 <div class='WPCSPInfoBox' style='display:none;'></div> … … 409 444 <tr class='trWPCSPViewErrors WPCSPHiddenEntry' id='<?php echo $TargetRow2;?>'><td colspan='4'></td></tr> 410 445 <?php 411 elseif( in_array( $URIParts['path'], array('data','inline','eval' ) )) :446 elseif( in_array( $URIParts['path'], array('data','inline','eval','blob','mediastream','filesystem') )) : 412 447 switch( $URIParts['path'] ) { 413 448 case 'data': … … 416 451 case 'blob': 417 452 $BlockRule = "blob:" ; 453 break ; 454 case 'mediastream': 455 $BlockRule = "mediastream:" ; 456 break ; 457 case 'filesystem': 458 $BlockRule = "filesystem:" ; 418 459 break ; 419 460 case 'inline': … … 686 727 * @return array - Array of errors 687 728 */ 688 static private function FindCSPErrors( $Polic ies ) {729 static private function FindCSPErrors( $PolicyKey, $Policies ) { 689 730 $return = array() ; 690 $SchemeTags = array( 'data', 'blob',' filesystem','http','https',);731 $SchemeTags = array( 'data', 'blob','mediastream','filesystem','http','https',); 691 732 if( is_array( $Policies)){ 692 733 foreach( $Policies as $Policy ) { … … 704 745 $return[] = "Entry for <strong>none</strong> should read <strong>'none'</strong> (with single quotes) - entry: " .$Policy ; 705 746 } 747 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 ; 749 } 706 750 foreach( $SchemeTags as $SchemeTag ) { 707 751 if ( $StrippedPolicy == $SchemeTag && $Policy != $SchemeTag . ":") { … … 715 759 $return[] = "Allow all subdomain entry should start '*.domain.com' - entry: " .$Policy ; 716 760 } 761 if ( $StrippedPolicy == 'data' && $PolicyKey == 'script-src' ) { 762 $return[] = "Avoid using 'data:' for script-src: " .$Policy ; 763 } 764 717 765 } 718 766 } … … 886 934 $wpCSPAdmin = new wpCSPAdmin() ; 887 935 $wpCSPAdmin->init(); 888 // $wpCSPAdmin->register_routes(); 889 add_action('rest_api_init',array($wpCSPAdmin,"register_routes")); 936 // If action "rest_api_init" hasn't run yet then use that, otherwise we have the route server in place, just register route 937 if ( did_action('rest_api_init') == 0 ){ 938 add_action('rest_api_init',array($wpCSPAdmin,"register_routes")); 939 } 940 else { 941 $wpCSPAdmin->register_routes(); 942 } -
wp-content-security-policy/trunk/css/wpCSPadmin.css
r1221818 r1772554 2 2 #wpcsp-poststuff textarea { 3 3 background-color: #fff; 4 height: 200px; 4 min-height: 60px; 5 max-height: 300px; 5 6 width: 80%; 6 7 float: left; … … 39 40 min-width: 200px; 40 41 } 41 .wpcsp-logoferrors thead td {42 .wpcsp-logoferrors thead td, .wpcsp_option_errors thead td { 42 43 font-weight: bold; 43 44 } … … 83 84 font-size:smaller; 84 85 } 86 .wpscp_Cannot_Allow{ 87 display:inline-block; 88 } -
wp-content-security-policy/trunk/includes/wpCSPclass.php
r1772018 r1772554 18 18 const SETTINGS_OPTIONS_SANDBOX_BLANKENTRY = 'blankentry' ; 19 19 const SETTINGS_OPTIONS_SANDBOX_NOTSET = '' ; 20 const SETTINGS_OPTIONS_MIXED_CONTENT = 'wpcsp_MixedContent'; 20 21 21 22 const PLUGIN_TRIGGER = 'wpcspReceiveCSPviol'; … … 30 31 const LOGVIOLATIONS_LOG_POINT1PERC = 12; 31 32 33 const BLOCK_ALL_MIXED_CONTENT = 21 ; 34 const UPGRADE_INSECURE_REQUESTS = 22 ; 35 32 36 33 37 const HEADERTAG_ENFORCEPOLICY = 'Content-Security-Policy' ; … … 66 70 'media-src' => array( 'label' => 'Media SRC' , 67 71 'description' => 'Defines valid sources of audio and video, eg HTML5 <audio>, <video> elements.' , 72 ), 73 'manifest-src' => array( 'label' => 'Manifest SRC' , 74 'description' => 'manifest-src directive specifies which manifest can be applied to the resource.' , 75 ), 76 'worker-src' => array( 'label' => 'Worker SRC' , 77 'description' => 'worker-src directive specifies valid sources for Worker, SharedWorker, or ServiceWorker scripts.' , 68 78 ), 69 79 'form-action' => array( 'label' => 'Form Action' , … … 129 139 public static function add_header() { 130 140 131 $CSPOutput = "";141 $CSPOutput = array() ; 132 142 $options = get_option( self::SETTINGS_OPTIONS_ALLOPTIONS ); 133 143 foreach( wpCSPclass::$CSP_Policies as $PolicyKey => $CSPPolicy) { 134 144 $CSPOption = self::CleanPolicyOptionText( $options[$PolicyKey] ); 145 // If self is listed, add the current site name to the CSP too as some browsers need it. 135 146 if ( in_array( "'self'", $CSPOption)) { 136 147 $CSPOption[] = site_url(); … … 140 151 // if the option sting is not empty then output it. If it is empty it will default to default-src. 141 152 if ( !empty( $CSPOptionOptionString ) ) { 142 $CSPOutput .= $PolicyKey . " " . $CSPOptionOptionString . "; ";153 $CSPOutput[] = $PolicyKey . " " . $CSPOptionOptionString ; 143 154 // Legacy setting, some browsers still need it. 144 155 if ( $PolicyKey == 'frame-src' ) { 145 $CSPOutput .= "child-src " . $CSPOptionOptionString . "; ";156 $CSPOutput[] = "child-src " . $CSPOptionOptionString ; 146 157 } 147 158 } … … 159 170 $SandboxOptions = implode(" ", $options[ self::SETTINGS_OPTIONS_SANDBOX] ); 160 171 } 161 $CSPOutput .= "sandbox " . $SandboxOptions . "; "; 172 $CSPOutput[] = "sandbox " . $SandboxOptions ; 173 } 174 } 175 176 // Mixed Content - if its blank its not set, if its not blank then something needs outputting.. 177 if ( !empty( $options[ self::SETTINGS_OPTIONS_MIXED_CONTENT]) ) { 178 switch( $options[ self::SETTINGS_OPTIONS_MIXED_CONTENT] ) { 179 case self::BLOCK_ALL_MIXED_CONTENT: 180 $CSPOutput[] = "block-all-mixed-content"; 181 break ; 182 183 case self::UPGRADE_INSECURE_REQUESTS: 184 $CSPOutput[] = "upgrade-insecure-requests"; 185 break ; 186 default: 187 break; 162 188 } 163 189 } … … 196 222 $URLParams = array("_wpnonce" => $Nonce); 197 223 $ReportURI = add_query_arg( $URLParams, $ReportURIBase) ; 198 $CSPOutput .= "report-uri " . $ReportURI ;224 $CSPOutput[] = "report-uri " . $ReportURI ; 199 225 } 200 226 // Output the CSP header 201 header($CSPHeaderTag . ": " . $CSPOutput);227 header($CSPHeaderTag . ": " . implode( "; ", $CSPOutput )); 202 228 } 203 229 … … 532 558 $wpCSPclass = new wpCSPclass() ; 533 559 $wpCSPclass->init(); 534 // $wpCSPclass->register_routes(); 535 add_action('rest_api_init',array($wpCSPclass,"register_routes")); 560 // If action "rest_api_init" hasn't run yet then use that, otherwise we have the route server in place, just register route 561 if ( did_action('rest_api_init') == 0 ){ 562 add_action('rest_api_init',array($wpCSPclass,"register_routes")); 563 } 564 else { 565 $wpCSPclass->register_routes(); 566 } -
wp-content-security-policy/trunk/readme.txt
r1772018 r1772554 5 5 Requires at least: 4.8 6 6 Tested up to: 4.9 7 Stable tag: 1. 87 Stable tag: 1.9 8 8 License: GPLv2 or later 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 148 148 == Changelog == 149 149 150 = 1.9 = 151 * Add support for block-mixed-content and upgrade-insecure-requests 152 * Add support for worker-src and manifest-src 153 * Add support for mediastream: and filesystem: 154 * Add display of configuration errors at the top of the save page. 155 * Fix register_route issues 156 * Change size of configuration entry boxes to match their contents. 157 150 158 = 1.8 = 151 159 * Fixed issues running on WP 4.8 -
wp-content-security-policy/trunk/wp-content-security-policy.php
r1772018 r1772554 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. 86 Version: 1.9 7 7 Author: Dylan Downhill 8 8 Author URI: http://www.elixirinteractive.com
Note: See TracChangeset
for help on using the changeset viewer.