Plugin Directory

Changeset 1772554


Ignore:
Timestamp:
11/21/2017 07:04:03 PM (8 years ago)
Author:
dyland
Message:

Version 1.9

Location:
wp-content-security-policy
Files:
12 added
5 edited

Legend:

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

    r1772018 r1772554  
    154154        // Make sure the database table exists.
    155155        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;     
    156167        ?>
    157  
    158168     <div class="wrap">
    159169        <div class="wpcsp-wpcspadmin wpcsp-optionsadmin">
     
    164174               
    165175              <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; ?>
    166182               
    167183              <div id="wpcsp-poststuff">
     
    169185                        <div id="post-body-content">
    170186                             <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?>
    173188                                  <table class="form-table">
    174189                                       <tr class='wpcsp_option_row'><th scope="row"><?php _e( "Run in 'report only' mode?", 'wpcsp' ); ?></th>
     
    176191                                                 <select name="<?php echo wpCSPclass::SETTINGS_OPTIONS_ALLOPTIONS;?>[<?php echo wpCSPclass::SETTINGS_OPTIONS_REPORTONLY; ?>]" id="<?php echo wpCSPclass::SETTINGS_OPTIONS_REPORTONLY; ?>">
    177192                                                      <?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>
    180195                                                 </select>
    181196                                                 <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>
     
    196211                                            </td>
    197212                                       </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>
    198224                                       
    199225                                       <tr><th scope="row"><?php _e( "Policy Entries", 'wpcsp' ); ?></th>
     
    205231                                            <tr><td>'unsafe-inline'</td><td>Allow use of inline source elements - scripts, fonts, etc.</td></tr>
    206232                                            <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>
    207234                                            <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>
    209236                                            <tr><td>domain.example.com</td><td>Allow loading resource from this specific domain, any scheme</td></tr>
    210237                                            <tr><td>*.example.com</td><td>Allow loading resource from any subdomain of the specified domain</td></tr>
     
    217244                                    $CSPOptions = wpCSPclass::CleanPolicyOptionText( $selected ) ;
    218245                                    $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                                    }
    220251                                    ?>
    221252                                   <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>
    225256                                             <?php if ( !empty( $Errors )) :?><div class='wpcsp_option_errors'><ul><li><?php echo implode("</li><li>",$Errors) ;?></li></ul></div><?php endif; ?>
    226257                                        </td>
     
    234265                                    $CSPOptions = wpCSPclass::CleanPolicyOptionText( $selected ) ;
    235266                                    $selected = implode( PHP_EOL, array_unique( $CSPOptions ) ) ;
    236                                     $Errors = self::FindCSPErrors( $CSPOptions );
     267                                    $Errors = self::FindCSPErrors( 'URLSToIgnore', $CSPOptions );
    237268                                    ?>
    238269                                             <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 />
     
    402433                                </td>
    403434                                <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; ?>
    405440                                    <input type="button" class="button-primary btnWPCSPIgnoreDomain" value="<?php _e('Ignore Domain Violations','wpcsp') ?>" />
    406441                                    <div class='WPCSPInfoBox' style='display:none;'></div>
     
    409444                        <tr class='trWPCSPViewErrors WPCSPHiddenEntry' id='<?php echo $TargetRow2;?>'><td colspan='4'></td></tr>
    410445                        <?php
    411                         elseif( in_array( $URIParts['path'], array('data','inline','eval') )) :
     446                        elseif( in_array( $URIParts['path'], array('data','inline','eval','blob','mediastream','filesystem') )) :
    412447                            switch( $URIParts['path'] ) {
    413448                                case 'data':
     
    416451                                case 'blob':
    417452                                    $BlockRule = "blob:" ;
     453                                    break ;
     454                                case 'mediastream':
     455                                    $BlockRule = "mediastream:" ;
     456                                    break ;
     457                                case 'filesystem':
     458                                    $BlockRule = "filesystem:" ;
    418459                                    break ;
    419460                                case 'inline':
     
    686727     * @return array            - Array of errors
    687728     */
    688     static private function FindCSPErrors( $Policies ) {
     729    static private function FindCSPErrors( $PolicyKey, $Policies ) {
    689730        $return = array() ;
    690         $SchemeTags = array( 'data', 'blob','filesystem','http','https',);
     731        $SchemeTags = array( 'data', 'blob','mediastream','filesystem','http','https',);
    691732        if( is_array( $Policies)){
    692733            foreach( $Policies as $Policy ) {
     
    704745                    $return[] = "Entry for <strong>none</strong> should read <strong>'none'</strong> (with single quotes) - entry: " .$Policy ;
    705746                }
     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                }
    706750                foreach( $SchemeTags as $SchemeTag ) {
    707751                    if ( $StrippedPolicy == $SchemeTag && $Policy != $SchemeTag . ":") {
     
    715759                    $return[] = "Allow all subdomain entry should start '*.domain.com' - entry: " .$Policy ;
    716760                }
     761                if ( $StrippedPolicy == 'data' && $PolicyKey == 'script-src' ) {
     762                    $return[] = "Avoid using 'data:' for script-src: " .$Policy ;
     763                }
     764                   
    717765            }
    718766        }
     
    886934$wpCSPAdmin = new wpCSPAdmin() ;
    887935$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
     937if ( did_action('rest_api_init') == 0 ){
     938    add_action('rest_api_init',array($wpCSPAdmin,"register_routes"));
     939}
     940else {
     941    $wpCSPAdmin->register_routes();
     942}
  • wp-content-security-policy/trunk/css/wpCSPadmin.css

    r1221818 r1772554  
    22#wpcsp-poststuff textarea {
    33    background-color: #fff;
    4     height: 200px;
     4    min-height: 60px;
     5    max-height: 300px;
    56    width: 80%;
    67    float: left;
     
    3940    min-width: 200px;
    4041}
    41 .wpcsp-logoferrors thead td {
     42.wpcsp-logoferrors thead td, .wpcsp_option_errors thead td {
    4243    font-weight: bold;
    4344}
     
    8384     font-size:smaller;
    8485}
     86.wpscp_Cannot_Allow{
     87    display:inline-block;
     88}
  • wp-content-security-policy/trunk/includes/wpCSPclass.php

    r1772018 r1772554  
    1818    const SETTINGS_OPTIONS_SANDBOX_BLANKENTRY = 'blankentry' ;
    1919    const SETTINGS_OPTIONS_SANDBOX_NOTSET = '' ;
     20    const SETTINGS_OPTIONS_MIXED_CONTENT = 'wpcsp_MixedContent';
    2021   
    2122    const PLUGIN_TRIGGER = 'wpcspReceiveCSPviol';
     
    3031    const LOGVIOLATIONS_LOG_POINT1PERC = 12;
    3132   
     33    const BLOCK_ALL_MIXED_CONTENT = 21 ;
     34    const UPGRADE_INSECURE_REQUESTS = 22 ;
     35   
    3236   
    3337    const HEADERTAG_ENFORCEPOLICY = 'Content-Security-Policy' ;
     
    6670            'media-src' => array( 'label' => 'Media SRC' ,
    6771                    'description' => 'Defines valid sources of audio and video, eg HTML5 &lt;audio&gt;, &lt;video&gt; 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.' ,
    6878            ),
    6979            'form-action' => array( 'label' => 'Form Action' ,
     
    129139    public static function add_header() {
    130140       
    131         $CSPOutput = "" ;
     141        $CSPOutput = array() ;
    132142        $options = get_option( self::SETTINGS_OPTIONS_ALLOPTIONS );
    133143        foreach( wpCSPclass::$CSP_Policies as $PolicyKey => $CSPPolicy) {
    134144            $CSPOption = self::CleanPolicyOptionText( $options[$PolicyKey] );
     145            // If self is listed, add the current site name to the CSP too as some browsers need it.
    135146            if ( in_array( "'self'", $CSPOption)) {
    136147                $CSPOption[] = site_url();
     
    140151            // if the option sting is not empty then output it. If it is empty it will default to default-src.
    141152            if ( !empty( $CSPOptionOptionString ) ) {
    142                 $CSPOutput .= $PolicyKey . " " . $CSPOptionOptionString . "; ";
     153                $CSPOutput[] = $PolicyKey . " " . $CSPOptionOptionString ;
    143154                // Legacy setting, some browsers still need it.
    144155                if ( $PolicyKey == 'frame-src' ) {
    145                     $CSPOutput .=  "child-src " . $CSPOptionOptionString . "; ";
     156                    $CSPOutput[] =  "child-src " . $CSPOptionOptionString ;
    146157                }
    147158            }
     
    159170                    $SandboxOptions = implode(" ", $options[ self::SETTINGS_OPTIONS_SANDBOX]  );
    160171                }
    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;
    162188            }
    163189        }
     
    196222            $URLParams = array("_wpnonce" => $Nonce);
    197223            $ReportURI = add_query_arg( $URLParams, $ReportURIBase) ;
    198             $CSPOutput .= "report-uri " . $ReportURI  ;
     224            $CSPOutput[] = "report-uri " . $ReportURI  ;
    199225        }
    200226        // Output the CSP header
    201         header($CSPHeaderTag . ": " . $CSPOutput);
     227        header($CSPHeaderTag . ": " . implode( "; ", $CSPOutput ));
    202228    }
    203229   
     
    532558$wpCSPclass = new wpCSPclass() ;
    533559$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
     561if ( did_action('rest_api_init') == 0 ){
     562    add_action('rest_api_init',array($wpCSPclass,"register_routes"));
     563}
     564else {
     565    $wpCSPclass->register_routes();
     566}
  • wp-content-security-policy/trunk/readme.txt

    r1772018 r1772554  
    55Requires at least: 4.8
    66Tested up to: 4.9
    7 Stable tag: 1.8
     7Stable tag: 1.9
    88License: GPLv2 or later
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    148148== Changelog ==
    149149
     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
    150158= 1.8 =
    151159* Fixed issues running on WP 4.8
  • wp-content-security-policy/trunk/wp-content-security-policy.php

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