Changeset 3296463
- Timestamp:
- 05/19/2025 12:50:17 PM (10 months ago)
- Location:
- category-icon/trunk
- Files:
-
- 2 edited
-
category-icon.php (modified) (4 diffs)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
category-icon/trunk/category-icon.php
r3167145 r3296463 4 4 * Plugin URI: http://pixelgrade.com 5 5 * Description: Easily attach an icon and/or an image to a category, tag or any other taxonomy term. 6 * Version: 1.0. 16 * Version: 1.0.2 7 7 * Author: Pixelgrade 8 8 * Author URI: http://pixelgrade.com … … 13 13 * Domain Path: /lang 14 14 * Requires at least: 4.9.19 15 * Tested up to: 6. 6.215 * Tested up to: 6.8.1 16 16 * Requires PHP: 5.6.40 17 17 */ … … 31 31 protected $plugin_baseurl = null; 32 32 protected $plugin_screen_hook_suffix = null; 33 protected $version = '1.0. 0';33 protected $version = '1.0.2'; 34 34 protected $plugin_slug = 'category-icon'; 35 35 protected $plugin_key = 'category-icon'; … … 120 120 121 121 /** 122 * Sanitizes SVG content by removing <script> elements and any unsafe attributes. 123 * This helps mitigate potential XSS vulnerabilities from SVG uploads. 122 * Sanitize raw SVG markup before it is stored in the uploads directory. 124 123 * 125 * @param string $svg_content The raw SVG content to be sanitized. 126 * @return string The sanitized SVG content. 127 */ 128 private function sanitize_svg_content($svg_content) { 129 // Create a new DOMDocument instance to parse the SVG XML content 130 $dom = new DOMDocument(); 131 132 // Suppress XML parsing errors for invalid SVG formats 133 libxml_use_internal_errors(true); 134 135 // Load the SVG content into the DOMDocument for manipulation 136 $dom->loadXML($svg_content, LIBXML_NOENT | LIBXML_DTDLOAD); 137 138 // Clear any XML parsing errors 139 libxml_clear_errors(); 140 141 // Step 1: Remove any <script> elements, which can execute JavaScript 142 $scripts = $dom->getElementsByTagName('script'); 143 while ($scripts->length > 0) { 144 $scripts->item(0)->parentNode->removeChild($scripts->item(0)); 145 } 146 147 // Step 2: Remove unsafe attributes that could contain JavaScript (like onclick, onload) 148 $xpath = new DOMXPath($dom); 149 foreach ($xpath->query('//@*') as $attr) { 150 if (stripos($attr->name, 'on') === 0 || stripos($attr->value, 'javascript:') === 0) { 151 $attr->parentNode->removeAttribute($attr->name); 152 } 153 } 154 155 // Return the sanitized SVG content as XML 156 return $dom->saveXML(); 157 } 124 * The function loads the SVG into a DOMDocument *without* expanding external 125 * entities or allowing network I/O, preventing XXE/SSRF. After a successful 126 * parse it walks the document and strips any element or attribute that is not 127 * explicitly allow-listed. 128 * 129 * @param string $svg_content Raw SVG file contents. 130 * @return string Clean SVG (empty string on failure or if unsafe). 131 */ 132 private function sanitize_svg_content( $svg_content ) { 133 // Collect libxml errors internally – we decide what to do with them. 134 libxml_use_internal_errors( true ); 135 136 $dom = new DOMDocument(); 137 $load_opts = LIBXML_NONET // deny all network access (blocks XXE/SSRF) 138 | LIBXML_NOERROR // suppress warnings 139 | LIBXML_NOWARNING; // suppress notices 140 141 // PHP < 8.0 still allows the entity loader unless we disable it globally. 142 if ( PHP_VERSION_ID < 80000 ) { 143 $previous_loader_state = libxml_disable_entity_loader( true ); // phpcs:ignore PHPCompatibility.Extensions.RemovedFunctions 144 } 145 146 // Abort if XML is invalid *or* references external entities. 147 if ( ! $dom->loadXML( $svg_content, $load_opts ) ) { 148 if ( PHP_VERSION_ID < 80000 ) { 149 libxml_disable_entity_loader( $previous_loader_state ); // restore 150 } 151 return ''; // fail closed 152 } 153 154 // Restore global entity loader setting for legacy PHP versions. 155 if ( PHP_VERSION_ID < 80000 ) { 156 libxml_disable_entity_loader( $previous_loader_state ); 157 } 158 159 /* -------------------------------------------------------------------- 160 * Phase 2 – Allow-list-based cleanup 161 * ------------------------------------------------------------------ */ 162 163 $allowed_tags = array( 164 'svg', 'g', 'path', 'polygon', 'circle', 'ellipse', 'line', 165 'polyline', 'rect', 'use', 'defs', 'linearGradient', 166 'radialGradient', 'stop', 'clipPath', 'mask', 'title', 'desc', 167 ); 168 169 $allowed_attrs = array( 170 'id', 'class', 'fill', 'stroke', 'stroke-width', 'stroke-linecap', 171 'stroke-linejoin', 'stroke-miterlimit', 'stroke-dasharray', 172 'stroke-dashoffset', 'transform', 'd', 'points', 'x', 'y', 'cx', 173 'cy', 'r', 'rx', 'ry', 'width', 'height', 'x1', 'y1', 'x2', 'y2', 174 'gradientUnits', 'gradientTransform', 'offset', 'stop-color', 175 'stop-opacity', 'viewBox', 'xmlns', 'version', 176 'preserveAspectRatio', 177 ); 178 179 $xpath = new DOMXPath( $dom ); 180 181 /** @var DOMElement $node */ 182 foreach ( $xpath->query( '//*' ) as $node ) { 183 // Drop any element that is not allowed. 184 if ( ! in_array( $node->nodeName, $allowed_tags, true ) ) { 185 $node->parentNode->removeChild( $node ); 186 continue; 187 } 188 189 // Prune disallowed attributes. 190 if ( $node->hasAttributes() ) { 191 /** @var DOMAttr $attr */ 192 foreach ( iterator_to_array( $node->attributes ) as $attr ) { 193 if ( ! in_array( $attr->nodeName, $allowed_attrs, true ) ) { 194 $node->removeAttributeNode( $attr ); 195 } 196 } 197 } 198 } 199 200 // Return compact, sanitized SVG. 201 $dom->formatOutput = false; 202 return $dom->saveXML( $dom->documentElement ); 203 } 204 158 205 159 206 -
category-icon/trunk/readme.txt
r3167148 r3296463 3 3 Tags: category, taxonomy, term, icon, image 4 4 Requires at least: 4.9.19 5 Tested up to: 6. 6.25 Tested up to: 6.8.1 6 6 Requires PHP: 5.6.40 7 Stable tag: 1.0. 17 Stable tag: 1.0.2 8 8 License: GPLv2 or later 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 26 26 27 27 == Changelog == 28 29 = 1.0.2 = 30 * Security: patched blind XXE/SSRF in SVG upload flow – external entity loading and network access are now disabled; malformed SVGs are rejected (fail-closed). 28 31 29 32 = 1.0.1 =
Note: See TracChangeset
for help on using the changeset viewer.