Changeset 2085
- Timestamp:
- 11/16/2015 11:31:23 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/jetpack-tweaks.php
r1682 r2085 78 78 } 79 79 add_filter( 'pre_update_site_option_jetpack-network-settings', __NAMESPACE__ . '\auto_connect_new_sites', 10, 2 ); 80 81 /** 82 * Sanitize parsed Custom CSS rules 83 * 84 * @import rules are stripped because they can introduce security vulnerabilities by embedding external 85 * stylesheets that haven't been sanitized, and they also present a maintenance problem because they rely on 86 * external resources which could go offline at any point. 87 * 88 * @charset rules are stripped because manipulating the charset can allow an attacker to introduce XSS 89 * vulnerabilities by tricking the browser into interpreting the CSS as HTML. 90 * 91 * @param \safecss $safecss 92 */ 93 function sanitize_csstidy_parsed_rules( $safecss ) { 94 if ( ! empty( $safecss->parser->import ) ) { 95 update_option( 'custom_css_import_stripped', true ); 96 } 97 98 $safecss->parser->import = array(); 99 $safecss->parser->charset = array(); 100 } 101 add_action( 'csstidy_optimize_postparse', __NAMESPACE__ . '\sanitize_csstidy_parsed_rules' ); 102 103 /** 104 * Notify the user that @import rules were stripped from their CSS 105 */ 106 function notify_import_rules_stripped() { 107 global $current_screen; 108 $relevant_screens = array( 'appearance_page_editcss', 'appearance_page_remote-css' ); 109 110 if ( ! is_a( $current_screen, 'WP_Screen' ) || ! in_array( $current_screen->id, $relevant_screens, true ) ) { 111 return; 112 } 113 114 if ( ! get_option( 'custom_css_import_stripped' ) ) { 115 return; 116 } 117 118 delete_option( 'custom_css_import_stripped' ); 119 120 ?> 121 122 <div class="notice notice-warning"> 123 <p> 124 <?php printf( 125 __( 'WARNING: <code>@import</code> rules were stripped for security reasons. 126 Please use <a href="%s">the Fonts tool</a> to add web fonts, and copy/paste other stylesheets directly into your custom CSS.', 127 'wordcamporg' ), 128 admin_url( 'themes.php?page=wc-fonts-options' ) 129 ); ?> 130 </p> 131 </div> 132 133 <?php 134 } 135 add_action( 'admin_notices', __NAMESPACE__ . '\notify_import_rules_stripped' ); 136 137 /** 138 * Sanitize Custom CSS subvalues 139 * 140 * @param \safecss $safecss 141 */ 142 function sanitize_csstidy_subvalues( $safecss ) { 143 $safecss->sub_value = trim( $safecss->sub_value ); 144 145 // Send any urls through our filter 146 if ( preg_match( '!^\s*(?P<url_expression>url\s*(?P<opening_paren>\(|\\0028)(?P<parenthetical_content>.*)(?P<closing_paren>\)|\\0029))(.*)$!Dis', $safecss->sub_value, $matches ) ) { 147 $safecss->sub_value = sanitize_urls_in_css_properties( $matches['parenthetical_content'], $safecss->property ); 148 149 // Only replace the url([...]) portion of the sub_value so we don't 150 // lose things like trailing commas or !important declarations. 151 if ( $safecss->sub_value ) { 152 $safecss->sub_value = str_replace( $matches['url_expression'], $safecss->sub_value, $matches[0] ); 153 } 154 } 155 156 // Strip any expressions 157 if ( preg_match( '!^\\s*expression!Dis', $safecss->sub_value ) ) { 158 $safecss->sub_value = ''; 159 } 160 } 161 add_action( 'csstidy_optimize_subvalue', __NAMESPACE__ . '\sanitize_csstidy_subvalues' ); 162 163 /** 164 * Sanitize URLs used in CSS properties 165 * 166 * @param string $url 167 * @param string $property 168 * 169 * @return string 170 */ 171 function sanitize_urls_in_css_properties( $url, $property ) { 172 $allowed_properties = array( 'background', 'background-image', 'border-image', 'content', 'cursor', 'list-style', 'list-style-image' ); 173 $allowed_protocols = array( 'http', 'https' ); 174 175 // Clean up the string 176 $url = trim( $url, "' \" \r \n" ); 177 178 // Check against whitelist for properties allowed to have URL values 179 if ( ! in_array( trim( $property ), $allowed_properties, true ) ) { 180 // trim() is because multiple properties with the same name are stored with 181 // additional trailing whitespace so they don't overwrite each other in the hash. 182 return ''; 183 } 184 185 $url = wp_kses_bad_protocol_once( $url, $allowed_protocols ); 186 187 if ( empty( $url ) ) { 188 return ''; 189 } 190 191 return "url('" . str_replace( "'", "\\'", $url ) . "')"; 192 }
Note: See TracChangeset
for help on using the changeset viewer.