File: //home/shrsglobal/www/wp-content/plugins/wp-letsencrypt-ssl/classes/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;
}
}
}