Plugin Directory

Changeset 1776322


Ignore:
Timestamp:
11/27/2017 05:30:10 PM (8 years ago)
Author:
dyland
Message:

Version 2.0

Location:
wp-content-security-policy
Files:
29 added
6 edited

Legend:

Unmodified
Added
Removed
  • wp-content-security-policy/trunk/admin/wpCSPadmin.php

    r1772554 r1776322  
    1919     * @return WP_Error|boolean
    2020     */
    21     public function permissions_check_edit_posts(  $request  ) {
     21    public static function permissions_check_edit_posts(  $request  ) {
    2222        return current_user_can( 'edit_posts' );
    2323    }
     
    3232     * @return WP_Error|boolean
    3333     */
    34     public function data_arg_sanitize_string_callback( $value, $request, $param ) {
     34    public static function data_arg_sanitize_string_callback( $value, $request, $param ) {
    3535        // It is as simple as returning the sanitized value.
    3636        return sanitize_text_field( $value );
     
    4444                array(
    4545                        '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' ),
    4848                        'args'            => array(
    4949                                'subaction' => array(
     
    5656                                        'required' => false,
    5757                                        'type' => 'string',
    58                                         "sanitize_callback" => array( $this, 'data_arg_sanitize_string_callback' ),
     58                                        "sanitize_callback" => array( __CLASS__, 'data_arg_sanitize_string_callback' ),
    5959                                        'description' => '',
    6060                                ),
     
    6262                                        'required' => false,
    6363                                        'type' => 'string',
    64                                         "sanitize_callback" => array( $this, 'data_arg_sanitize_string_callback' ),
     64                                        "sanitize_callback" => array( __CLASS__, 'data_arg_sanitize_string_callback' ),
    6565                                        'description' => '',
    6666                                ),
     
    6868                                        'required' => false,
    6969                                        'type' => 'string',
    70                                         "sanitize_callback" => array( $this, 'data_arg_sanitize_string_callback' ),
     70                                        "sanitize_callback" => array( __CLASS__, 'data_arg_sanitize_string_callback' ),
    7171                                        'description' => '',
    7272                                ),
     
    7474                                        'required' => false,
    7575                                        'type' => 'string',
    76                                         "sanitize_callback" => array( $this, 'data_arg_sanitize_string_callback' ),
     76                                        "sanitize_callback" => array( __CLASS__, 'data_arg_sanitize_string_callback' ),
    7777                                        'description' => '',
    7878                                ),
     
    8080                                        'required' => false,
    8181                                        'type' => 'string',
    82                                         "sanitize_callback" => array( $this, 'data_arg_sanitize_string_callback' ),
     82                                        "sanitize_callback" => array( __CLASS__, 'data_arg_sanitize_string_callback' ),
    8383                                        'description' => '',
    8484                                ),
     
    8686                                        'required' => false,
    8787                                        'type' => 'string',
    88                                         "sanitize_callback" => array( $this, 'data_arg_sanitize_string_callback' ),
     88                                        "sanitize_callback" => array( __CLASS__, 'data_arg_sanitize_string_callback' ),
    8989                                        'description' => '',
    9090                                ),
     
    104104        add_action( 'wpCSPAdmin_daily_event',  array(__CLASS__,'daily_maintenance')  );
    105105       
     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');
    106109       
    107110        register_uninstall_hook(__FILE__, array(__CLASS__,"plugin_uninstall") );
     
    154157        // Make sure the database table exists.
    155158        self::update_database() ;
     159        global $options;
    156160        $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() ;
    159165        foreach( wpCSPclass::$CSP_Policies as $PolicyKey => $CSPPolicy) :
    160166            $selected = !empty( $options[ $PolicyKey ] ) ? $options[ $PolicyKey ] : '' ;
     
    162168            $Errors = self::FindCSPErrors( $PolicyKey, $CSPOptions );
    163169            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>" ;
    165172            }
    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        }
    167211        ?>
    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 &lt;iframe&gt; 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?>
    309232                                           
    310                                        <tr class='wpcsp_test_row ' data-target='#btnWPCSPTestURLCheckerOutput'><th scope="row">&nbsp;</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 ?>
    321259     <?php
    322260    }
     
    734672                $StrippedPolicy = preg_replace("/[^a-zA-Z0-9\s]/", "", $Policy);
    735673                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 ;
    737675                }
    738676                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 ;
    740678                }
    741679                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 ;
    743681                }
    744682                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 ;
    746684                }
    747685                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 ;
    749687                }
    750688                foreach( $SchemeTags as $SchemeTag ) {
    751689                    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 ;
    753691                    }
    754692                }
     
    932870}
    933871
    934 $wpCSPAdmin = new wpCSPAdmin() ;
    935 $wpCSPAdmin->init();
     872add_action('init',array("wpCSPAdmin","init"));
    936873// If action "rest_api_init" hasn't run yet then use that, otherwise we have the route server in place, just register route
    937874if ( 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"));
    939876}
    940877else {
    941     $wpCSPAdmin->register_routes();
     878    wpCSPAdmin::register_routes();
    942879}
  • wp-content-security-policy/trunk/css/wpCSPadmin.css

    r1772554 r1776322  
    11
    2 #wpcsp-poststuff textarea {
     2.wpcsp-form-table textarea {
    33    background-color: #fff;
    44    min-height: 60px;
     
    88}
    99
     10 .wpcsp-form-table p{
     11    margin: 5px 0 1em 0;
     12 }
     13 
    1014.wpcsp-wpcspadmin label {
    1115    clear:both;
     
    5963    overflow: hidden;
    6064}
     65.wpcsp_option_row th{
     66    padding-top: 10px;
     67    pading-right:10px;
     68    min-width: 200px;
     69    text-align: right;
     70}
    6171.wpcsp-wpcspadmin table {
    6272    border-collapse: collapse;
     
    7686.wpcsp_option_errors{
    7787    clear:both;
     88    color:#ff0000;
    7889}
    7990.wpcsp_option_errors li{
    8091    color:#ff0000;
    8192}
    82 .wpcsp_test_row td{
    83      border-top:300px solid transparent;
    84      font-size:smaller;
    85 }
    8693.wpscp_Cannot_Allow{
    8794    display:inline-block;
  • wp-content-security-policy/trunk/includes/wpCSPclass.php

    r1772554 r1776322  
    1212    const SETTINGS_OPTIONS_ALLOPTIONS = 'wpcsp_all_options' ;
    1313   
    14     const SETTINGS_OPTIONS_REPORTONLY = 'wpcsp_reportonly' ;
     14    const SETTINGS_OPTIONS_CSP_MODE = 'wpcsp_reportonly' ;
    1515    const SETTINGS_OPTIONS_LOGVIOLATIONS = 'wpcsp_logviolations' ;
    1616    const SETTINGS_OPTIONS_VIOLATIONSTOIGNORE = 'wpcsp_ViolationsToIgnore' ;
     
    1919    const SETTINGS_OPTIONS_SANDBOX_NOTSET = '' ;
    2020    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' ;
    2132   
    2233    const PLUGIN_TRIGGER = 'wpcspReceiveCSPviol';
     
    3546   
    3647   
    37     const HEADERTAG_ENFORCEPOLICY = 'Content-Security-Policy' ;
    38     const HEADERTAG_REPORTONLY = 'Content-Security-Policy-Report-Only';
    39    
    40    
    41     const ROUTE_VERSION = 1 ;
    4248    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            ),
    4956            'script-src' => array( 'label' => 'Script SRC' ,
    5057                    'description' => 'Defines valid sources of JavaScript.' ,
     
    138145     */
    139146    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.
    141172        $CSPOutput = array() ;
    142         $options = get_option( self::SETTINGS_OPTIONS_ALLOPTIONS );
    143173        foreach( wpCSPclass::$CSP_Policies as $PolicyKey => $CSPPolicy) {
    144174            $CSPOption = self::CleanPolicyOptionText( $options[$PolicyKey] );
     
    188218            }
    189219        }
    190         $ReportOnly = $options[ self::SETTINGS_OPTIONS_REPORTONLY];
    191         $CSPHeaderTag = !empty( $ReportOnly ) ? self::HEADERTAG_REPORTONLY : self::HEADERTAG_ENFORCEPOLICY;
    192220       
    193221        // Do we want the browser to log the violations with the server, or only block without logging?
     
    216244                break ;
    217245        }
    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       
    226247        // 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        }
    228376    }
    229377   
     
    556704    }
    557705}
    558 $wpCSPclass = new wpCSPclass() ;
    559 $wpCSPclass->init();
     706
     707
     708add_action('init',array("wpCSPclass","init"));
    560709// If action "rest_api_init" hasn't run yet then use that, otherwise we have the route server in place, just register route
    561710if ( 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"));
    563712}
    564713else {
    565     $wpCSPclass->register_routes();
     714    wpCSPclass::register_routes();
    566715}
  • wp-content-security-policy/trunk/js/wpCSPadmin.js

    r1771898 r1776322  
    11jQuery(document).ready(function(){
    22    WPCSPHandleLogAdmin();
     3    jQuery('#wpcsp_tabsAdmin').tabs();
    34});
    45jQuery(document).on('change','.WPCSPBlockedURLPath, .WPCSPBlockedURLFile', WPCSPHandleLogAdmin  );
  • wp-content-security-policy/trunk/readme.txt

    r1772554 r1776322  
    55Requires at least: 4.8
    66Tested up to: 4.9
    7 Stable tag: 1.9
     7Stable tag: 2.0
    88License: GPLv2 or later
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    1616longer 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)
    1717
    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
     18CSP 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
     20Adding CSP to your site will protect your visitors from:
    2121
    2222* Cross-site scripting (XSS) attacks
    2323* Adware and Spyware while on your site
    2424
    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.
     25This 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
     27This 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
     31CSP allows you to control where your visitors' browser is allowed to run code from. The W3C specification allows for the following directives.
    2832
    2933* **default-src**<br>
     
    4246Applies to XMLHttpRequest (AJAX), WebSocket or EventSource.
    4347
     48* **manifest-src**<br>
     49Specifies which manifest can be applied to the resource
     50
     51* **worker-src**<br>
     52Specifies valid sources for Worker, SharedWorker, or ServiceWorker scripts.
     53
    4454* **font-src**<br>
    4555Defines valid sources of fonts.
     
    6979URL to post information on violations of the policies you set.
    7080
     81= CSP Entry Syntax =
     82
    7183Each directive can take one or more of the following values:
    7284
     
    7587
    7688* **'none'**<br>
    77 Blocks loading resources from all sources.
     89Blocks loading resources from all sources. The single quotes are required.
    7890
    7991* **'self'**<br>
    80 Refers to your own host.
     92Refers to your own host. The single quotes are required.
    8193
    8294* **'unsafe-inline'**<br>
    83 Allows inline elements, such as functions in script tags, onclicks, etc.
     95Allows inline elements, such as functions in script tags, onclicks, etc. The single quotes are required.
    8496
    8597* **'unsafe-eval'**<br>
    86 Allows unsafe dynamic code evaluation such as JavaScript eval()
     98Allows unsafe dynamic code evaluation such as JavaScript eval(). The single quotes are required.
     99
     100* **'strict-dynamic'**<br>
     101The 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.
    87102
    88103* **data:**<br>
    89 Allow loading resources from data scheme - usually inline images.
    90 
     104Allow 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>
     107Allows mediastream: URIs to be used as a content source.
     108
     109* **filesystem:**<br>
     110Allow loading resource from file system.
     111               
    91112* **https:**<br>
    92 Only allows loading resources from HTTPS: on any domain
     113Only allows loading resources from HTTPS: on any domain. This can be used to block insecure requests.
    93114
    94115* **www.example.com**<br>
     
    107128Allows loading this one file on this domain.
    108129
    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
     132In addition to the CSP headers, there are other security headers supported, including:
     133
     134* **Expect-CT**<br>
     135Instructs user agents (browsers) to expect valid Signed Certificate Timestamps (SCTs) to be served.
     136
     137* **Strict Transport Security**<br>
     138The 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>
     141The 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 &lt;frame&gt;, &lt;iframe&gt; or &lt;object&gt; . 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>
     144The 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>
     147The 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>
     150The Referrer-Policy HTTP header governs which referrer information, sent in the Referer header, should be included with requests made.
    114151
    115152== Installation ==
     
    146183Usually you would want to keep security as strict as possible while still allowing your application to run. Therefore, '*' should be avoided.
    147184
     185= No errors are getting logged =
     186
     1871. 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.
     1881. 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.
     1891. 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.
     1901. 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.
     1911. 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
    148193== 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)
    149201
    150202= 1.9 =
  • wp-content-security-policy/trunk/wp-content-security-policy.php

    r1772554 r1776322  
    44Plugin URI:  http://URI_Of_Page_Describing_Plugin_and_Updates
    55Description: Setup, output, and log content security policy information.
    6 Version:     1.9
     6Version:     2.0
    77Author:      Dylan Downhill
    88Author URI:  http://www.elixirinteractive.com
Note: See TracChangeset for help on using the changeset viewer.