KOK - MANAGER
Edit File: le-advanced-scanner.php
<?php /** * @package WP Encryption * * @author WP Encryption * @copyright Copyright (C) 2019-2024, WP Encryption. All Rights Reserved. * @link https://wpencryption.com * @since Class available since Release 5.7.0 * */ class WPLE_DeepScanner { private $permalinks_list = []; private $insecure_links_within_posts = []; private $permalink_vs_mxresource = []; private $permalink_vs_inlinemx = []; private $widget_issues = []; private $merged_widget_issues = []; public function __construct() { $this->get_all_permalinks(); if ( !empty( $this->permalinks_list ) ) { foreach ( $this->permalinks_list as $PID => $link ) { $excludes = [ 'shop', 'cart', 'checkout', 'my-account' ]; foreach ( $excludes as $exclude ) { if ( stripos( $link, $exclude ) !== false ) { continue 2; } } $webpage = $this->retrieve_content( $link ); $this->parse_content_for_http_links( $PID, $link, $webpage ); $this->find_inline_insecure_items( $PID, $link, $webpage ); } } //$this->p($this->insecure_links_within_posts); $this->find_widgets_insecure_items(); //$this->p($this->widget_issues); ///$this->p($this->merged_widget_issues); //$this->p($this->permalink_vs_mxresource); //$this->p($this->permalink_vs_inlinemx); //Table starts if ( empty( $this->permalink_vs_mxresource ) ) { delete_option( 'wple_mixed_issues' ); echo 'success'; exit; } //have issues update_option( 'wple_mixed_issues', 1 ); $table = '<table id="wple-advanced-scanner"> <th>Type</th> <th>Insecure URL<br><small>URLs that needs updating to <strong>https://</strong></small></th> <th>Source File<br><small>Where it\'s coming from?</small></th>'; foreach ( $this->permalink_vs_mxresource as $ID => $research ) { if ( empty( $research['mx_resources'] ) ) { continue; } $table .= '<tr> <td colspan="3" class="wple-scan-head">Analyzed Page URL: ' . esc_url( $research['webpage'] ) . ' (ID=' . (int) $ID . ')</td> </tr>'; $issue_found = false; foreach ( $research['mx_resources'] as $key => $data ) { if ( empty( $data ) || count( $data ) == 1 && false !== stripos( $data[0], '/svg' ) ) { continue; } if ( $key == 'secure_css' || $key == 'secure_js' ) { //insecure items within secure files $issue_found = true; foreach ( $data as $key => $files_w_issue ) { $table .= '<tr> <td class="issue_type">' . esc_html__( 'Insecure links within css/js files', 'wp-letsencrypt-ssl' ) . '</td>'; $rcount = 1; foreach ( $files_w_issue['issues'] as $key => $items ) { $table .= '<td>http://' . implode( "<br>http://", $items ) . '</td>'; $rcount++; } $table .= '<td class="wple-tooltip" data-tippy="Find & fix these insecure urls via Appearance ~ Theme Editor">' . esc_url( $files_w_issue['resource'] ) . '</td>'; $table .= '</tr>'; } } else { $tds = ''; $tdcount = 1; foreach ( $data as $resource ) { if ( stripos( $resource, '/svg' ) ) { continue; } $issue_found = true; $issue_location = ''; $issue_tooltip = 'Try updating Site & WordPress urls to https:// protocol in Settings > General to resolve this issue. Likewise, this could be coming from your active theme files or active plugin files.'; if ( in_array( $resource, $this->merged_widget_issues ) ) { $issue_location = '<a href="' . admin_url( "widgets.php" ) . '" target="_blank">WIDGET</a>'; $issue_tooltip = 'Update this insecure url via Appearance > Widgets on left sidebar'; } if ( isset( $this->insecure_links_within_posts[$ID] ) ) { foreach ( $this->insecure_links_within_posts[$ID] as $type => $items ) { if ( in_array( $resource, $items ) ) { $ID = (int) $ID; $issue_location = '<a href="' . admin_url( "post.php?post={$ID}&action=edit" ) . '" target="_blank">POST CONTENT</a>'; $issue_tooltip = 'Update this insecure url via Edit Post'; } } } if ( isset( $this->permalink_vs_inlinemx[$ID] ) ) { foreach ( $this->permalink_vs_inlinemx[$ID]['mx_resources'] as $indx => $arr ) { if ( in_array( $resource, $arr ) ) { $issue_location = 'INLINE STYLE / SCRIPT'; $issue_tooltip = 'This issue is found within webpage html and might be coming from custom css / js section of your active theme or plugins.'; } } } $tds .= '<tr><td>' . esc_url( $resource ) . '</td><td class="wple-tooltip" data-tippy="' . esc_attr( $issue_tooltip ) . '">' . $issue_location . '</td></tr>'; $tdcount++; } if ( $tdcount > 1 ) { $table .= '<tr> <td rowspan="' . $tdcount . '" class="issue_type">' . esc_html( $key ) . '</td> ' . $tds . ' </tr>'; } } } if ( !$issue_found ) { $table .= '<tr> <td colspan="3" class="issue_type">Great!.. No mixed content issues found.</td> </tr>'; } } $table .= '</table>'; echo wp_kses_post( $table ); } private function get_all_permalinks() { global $wpdb; $ptypes_query = array(); $args = array( 'public' => true, ); $ptypes = get_post_types( $args ); foreach ( $ptypes as $post_type ) { if ( $post_type == 'product' ) { //dont include products continue; } $ptypes_query[] = " post_type = '" . $post_type . "'"; } $sql = implode( " OR ", $ptypes_query ); $sql = "SELECT ID, post_content FROM {$wpdb->posts} where post_status='publish' and (" . $sql . ") LIMIT 25"; $res = $wpdb->get_results( $sql ); if ( !empty( $res ) ) { foreach ( $res as $item ) { if ( @(!in_array( get_permalink( $item->ID ), $this->permalinks_list )) ) { $this->permalinks_list[$item->ID] = get_permalink( $item->ID ); } } $this->locate_insecure_items_in_posts( $res ); } } private function locate_insecure_items_in_posts( $results ) { $url_pattern = '([\\w.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-]?)(?:[\'|\\"])'; $image_pattern = '([\\w.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-]?[.jpg|.gif|.jpeg|.png|.svg])(?:((\\?.*[\'|"])|[\'|"]))'; $script_pattern = '([\\w.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-]?[.js])(?:((\\?.*[\'|\\"])|[\'|\\"]))'; $style_pattern = '([\\w.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-]?[.css])(?:((\\?.*[\'|\\"])|[\'|\\"]))'; $patterns = array( 'inline_css' => '/url\\([\'"]?\\K(http:\\/\\/)()' . $image_pattern . '/i', 'link' => '/<link[^>].*?href=[\'"]\\K(http:\\/\\/)()' . $style_pattern . '/i', 'meta' => '/<meta property="og:image" .*?content=[\'"]\\K(http:\\/\\/)()' . $image_pattern . '/i', 'img' => '/<(?:img)[^>].*?src=[\'"]\\K(http:\\/\\/)()' . $image_pattern . '/i', 'iframe' => '/<(?:iframe)[^>].*?src=[\'"]\\K(http:\\/\\/)()' . $url_pattern . '/i', 'script' => '/<script[^>]*?src=[\'"]\\K(http:\\/\\/)()' . $script_pattern . '/i', 'form' => '/<form[^>]*?action=[\'"]\\K(http:\\/\\/)()' . $url_pattern . '/i', 'inline_js' => '/"url":"\\K(http:\\/\\/)()' . $image_pattern . '/i', ); foreach ( $results as $res ) { foreach ( $patterns as $key => $pattern ) { $matches = []; if ( preg_match_all( $pattern, $res->post_content, $matches, PREG_PATTERN_ORDER ) ) { $this->insecure_links_within_posts[$res->ID][$key] = $matches[3]; } } } } private function retrieve_content( $url ) { if ( strpos( $url, "//" ) === 0 ) { $url = "https:" . $url; } $home = WPLE_Trait::get_root_domain( false ); if ( strpos( $url, $home ) !== FALSE ) { $url = add_query_arg( 'wpen_scan', time(), $url ); } $res = wp_remote_get( $url ); $maincontent = ""; if ( is_array( $res ) ) { $maincontent = wp_remote_retrieve_body( $res ); } if ( is_wp_error( $res ) ) { return ''; } return $maincontent; } private function parse_content_for_http_links( $pid, $link, $content ) { $patterns = array( "/(http:\\/\\/)([\\w.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-]?[.jpg|.gif|.jpeg|.png])(?:((\\?.*[\\'|\"])|['|\"]))/", "/(http:\\/\\/)([\\w.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-]?\\.mp4)(?:((\\?.*[\\'|\"])|['|\"]))/", "/(http:\\/\\/)([\\w.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-]?\\.js)(?:((\\?.*[\\'|\"])|['|\"]))/", "/(http:\\/\\/)([\\w.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-]?\\.css)(?:((\\?.*[\\'|\"])|['|\"]))/" ); $mx_resources = []; $matches = []; $count = 0; foreach ( $patterns as $pattern ) { $key = ( $count == 2 ? 'insecure_js' : (( $count == 3 ? 'insecure_css' : 'insecure_images' )) ); if ( preg_match_all( $pattern, $content, $matches, PREG_PATTERN_ORDER ) ) { $mx_resources[$key] = $matches[2]; } $count++; } $patterns = array("/(http:\\/\\/|https:\\/\\/|\\/\\/)([\\w.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-]?\\.js)(?:((\\?.*[\\'|\"])|['|\"]))/", "/(http:\\/\\/|https:\\/\\/|\\/\\/)([\\w.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-]?\\.css)(?:((\\?.*[\\'|\"])|['|\"]))/"); $all_cssjs_files = []; foreach ( $patterns as $index => $pattern ) { $key = ( $index == 0 ? 'secure_js' : 'secure_css' ); if ( preg_match_all( $pattern, $content, $matches, PREG_PATTERN_ORDER ) ) { $all_cssjs_files[$key] = $matches[2]; } } foreach ( $all_cssjs_files as $key => $items ) { foreach ( $items as $index => $cssjsfile ) { $foundissues = $this->check_mxissues_within_cssjs( 'https://' . $cssjsfile ); if ( !empty( $foundissues ) ) { $mx_resources[$key][$index] = [ 'resource' => $cssjsfile, 'issues' => $foundissues, ]; } } } if ( !empty( $mx_resources ) ) { $this->permalink_vs_mxresource[$pid] = [ 'webpage' => $link, 'mx_resources' => $mx_resources, ]; } } private function check_mxissues_within_cssjs( $cssjs_url ) { $url_pattern = '([\\w.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-]?)'; $patterns = array( '/url\\([\'"]?\\K(http:\\/\\/)' . $url_pattern . '/i', '/<script [^>]*?src=[\'"]\\K(http:\\/\\/)' . $url_pattern . '/i', '/<meta property="og:image" .*?content=[\'"]\\K(http:\\/\\/)' . $url_pattern . '/i', '/<(?:img|iframe)[^>].*?src=[\'"]\\K(http:\\/\\/)' . $url_pattern . '/i', '/<link [^>].*?href=[\'"]\\K(http:\\/\\/)' . $url_pattern . '/i' ); $filestr = file_get_contents( $cssjs_url ); $totalmatches = []; foreach ( $patterns as $pattern ) { $matches = []; if ( preg_match_all( $pattern, $filestr, $matches, PREG_PATTERN_ORDER ) ) { $totalmatches[] = $matches[2]; } } return $totalmatches; } private function find_inline_insecure_items( $pid, $link, $webpage ) { $url_pattern = '([\\w.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-]?)(?:[\'|\\"])'; $image_pattern = '([\\w.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-]?[.jpg|.gif|.jpeg|.png|.svg])(?:((\\?.*[\'|"])|[\'|"]))'; $patterns = array('/url\\([\'"]?\\K(http:\\/\\/)' . $image_pattern . '/i', '/<(?:iframe)[^>].*?src=[\'"]\\K(http:\\/\\/)' . $url_pattern . '/i', '/<form[^>]*?action=[\'"]\\K(http:\\/\\/)' . $url_pattern . '/i'); $type = 'inline_style'; $count = 0; $inline_issues = []; foreach ( $patterns as $pattern ) { $type = ( $count == 1 ? 'inline_iframe' : (( $count == 2 ? 'inline_form' : '' )) ); $matches = []; if ( preg_match_all( $pattern, $webpage, $matches, PREG_PATTERN_ORDER ) ) { $inline_issues[$type] = $matches[2]; } $count++; } if ( !empty( $inline_issues ) ) { $this->permalink_vs_inlinemx[$pid] = [ 'webpage' => $link, 'mx_resources' => $inline_issues, ]; } } private function find_widgets_insecure_items() { $widget_areas = wp_get_sidebars_widgets(); foreach ( $widget_areas as $widgets ) { foreach ( $widgets as $widget_title ) { $widget_data = $this->get_widget_data( $widget_title ); if ( $widget_data ) { $patterns = array( "images" => "/(http:\\/\\/)([\\w.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-]?[.jpg|.gif|.jpeg|.png|.svg])(?:((\\?.*[\\'|\"])|['|\"]))/", "video" => "/(http:\\/\\/)([\\w.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-]?\\.mp4)(?:((\\?.*[\\'|\"])|['|\"]))/", "js" => "/(http:\\/\\/)([\\w.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-]?\\.js)(?:((\\?.*[\\'|\"])|['|\"]))/", "css" => "/(http:\\/\\/)([\\w.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-]?\\.css)(?:((\\?.*[\\'|\"])|['|\"]))/", ); foreach ( $patterns as $type => $pattern ) { $matches = []; if ( preg_match_all( $pattern, $widget_data['html'], $matches, PREG_PATTERN_ORDER ) ) { $this->widget_issues[$widget_data['type'] . '-' . $widget_data['id']][] = $matches[2]; $this->merged_widget_issues = array_merge( $this->merged_widget_issues, $matches[2] ); } } } } } } public function get_widget_data( $title ) { $type = substr( $title, 0, strpos( $title, '-' ) ); $id = substr( $title, strpos( $title, '-' ) + 1 ); $widget_array = get_option( "widget_" . $type ); $widget_html = ""; $widget_title = ""; $type_found = false; if ( isset( $widget_array[$id]["content"] ) ) { $type_found = true; $widget_html = $widget_array[$id]["content"]; } if ( isset( $widget_array[$id]["url"] ) ) { $type_found = true; $widget_html = $widget_array[$id]["url"]; } if ( isset( $widget_array[$id]["text"] ) ) { $type_found = true; $widget_html = $widget_array[$id]["text"]; } if ( isset( $widget_array[$id]["title"] ) ) { $widget_title = $widget_array[$id]["title"]; } if ( isset( $widget_array[$id]["html"] ) ) { $type_found = true; $widget_html = $widget_array[$id]["html"]; } if ( $type_found ) { return array( "type" => $type, "id" => $id, "html" => $widget_html, "title" => $widget_title, ); } else { return false; } } }