/** * * @param string $URI URI we're tryiug to match * @param string $OptionString String we're trying to match in. * @param array $args Future use. * @return false - no match, otherwise match URI. */ public static function IsURIInOptionString($URI, $OptionString, $args = array()) { $return = -1; $OptionURLArray = wpCSPclass::CleanPolicyOptionText($OptionString); // No URI to check therefore no match possible. if (empty($URI) || empty($OptionURLArray)) { $return = false; } // Does the URL include a scheme? $URI = trim($URI); if (strpos($URI, ":") === false) { $URLPathDirectory = ""; if (strpos($URI, "/") !== false) { $URLPathDirectory = substr($URI, strpos($URI, "/")); $URI = substr($URI, 0, strpos($URI, "/")); } $URIParts = array('scheme' => '', 'host' => $URI, 'path' => $URLPathDirectory); } else { $URIParts = parse_url($URI); if ($URIParts === false) { return false; } } // For matching against anything with a wildcard - remove the subdomain. $URIHostnameWildcard = substr($URIParts['host'], strpos($URIParts['host'], ".")); // Split the path into path and file. if (substr($URIParts['path'], -1) == '/') { $URLPathDirectory = $URIParts['path']; $URLPathFile = ''; } else { $URLPathDirectory = substr($URIParts['path'], 0, strrpos($URIParts['path'], "/") + 1); $URLPathFile = substr($URIParts['path'], strrpos($URIParts['path'], "/") + 1); } // Quick search for special options! if ($return === -1) { foreach ($OptionURLArray as $key => $OptionURL) { // Empty option - ignore. if (empty($OptionURL)) { continue; } // Find out the options parts. $OptionURL = trim($OptionURL); if ($OptionURL == "'self'") { $OptionURL = site_url(); } if (strpos($OptionURL, ":") === false) { $OptionURLPathDirectory = ""; if (strpos($OptionURL, "/") !== false) { $OptionURLPathDirectory = substr($OptionURL, strpos($OptionURL, "/")); $OptionURL = substr($OptionURL, 0, strpos($OptionURL, "/")); } $OptionURLParts = array('scheme' => '', 'host' => $OptionURL, 'path' => $OptionURLPathDirectory); } else { $OptionURLParts = parse_url($OptionURL); if ($OptionURLParts === false) { continue; } } if (substr($OptionURLParts['path'], -1) == '/') { $OptionURLPathDirectory = $OptionURLParts['path']; $OptionURLPathFile = ''; } else { $OptionURLPathDirectory = substr($OptionURLParts['path'], 0, strrpos($OptionURLParts['path'], "/") + 1); $OptionURLPathFile = substr($OptionURLParts['path'], strrpos($OptionURLParts['path'], "/") + 1); } // * matched everything! if ($OptionURL == "*") { if ($URIParts['scheme'] != 'blob' && $URIParts['scheme'] != 'data' && $URIParts['scheme'] != 'filesystem') { $return = true; } } elseif (substr($OptionURL, -1, 1) == ':') { if (substr($OptionURL, 0, -1) == $URIParts['scheme']) { $return = true; } } elseif ($OptionURL == "'unsafe-inline'") { } elseif ($OptionURL == "'unsafe-eval'") { } elseif ($OptionURL == "'none'") { $return = false; } else { // Does the option have a scheme to check? if (strpos($OptionURL, ":") !== false) { // If the host name starts with a '*' then remvoe subdomain and check against the other url minus the subdomain if (substr($OptionURL, 0, 1) == '*') { if (substr($OptionURLParts['host'], strpos($OptionURLParts['host'], ".")) != $URIHostnameWildcard) { continue; } } elseif ($OptionURLParts['host'] != $URIParts['host'] || $OptionURLParts['scheme'] != $URIParts['scheme']) { continue; } } elseif (substr($OptionURL, 0, 1) == '*') { if (substr($OptionURLParts['host'], strpos($OptionURLParts['host'], ".")) != $URIHostnameWildcard) { continue; } } elseif ($OptionURL != $URIParts['host']) { continue; } if (!empty($OptionURLPathDirectory)) { if ($OptionURLPathDirectory !== $URLPathDirectory) { continue; } if (!empty($OptionURLPathFile)) { if ($OptionURLPathFile !== $URLPathFile) { continue; } } } $return = true; } // Did something set something this time around? Then stop checking options. if ($return !== -1) { break; } } } if ($return === -1) { $return = false; } return $return; }
/** * Handle the admin ajaz calls for data and setting options. */ public static function WPCSPAjax() { global $wpdb; @ob_end_clean(); if (session_status() == PHP_SESSION_NONE) { session_start(); } $ReturnStatus = true; $Data = array(); $HTML = "Unknown error"; $AdditionalReturn = array(); if (!is_user_logged_in() || !is_admin()) { $ReturnStatus = false; $HTML = "Restricted"; } else { $SubAction = !empty($_REQUEST['subaction']) ? $_REQUEST['subaction'] : ""; $ViolatedDirective = !empty($_REQUEST['violateddirective']) ? $_REQUEST['violateddirective'] : ""; $BlockedURI = !empty($_REQUEST['blockeduri']) ? $_REQUEST['blockeduri'] : ""; $Scheme = !empty($_REQUEST['scheme']) ? $_REQUEST['scheme'] : ""; $Domain = !empty($_REQUEST['domain']) ? $_REQUEST['domain'] : ""; $Path = !empty($_REQUEST['path']) ? $_REQUEST['path'] : ""; $File = !empty($_REQUEST['file']) ? $_REQUEST['file'] : ""; switch ($SubAction) { case 'getdata': $sql = $wpdb->prepare("SELECT document_uri, useragent, count(*) as numerrors " . " FROM " . wpCSPclass::LogTableName() . " WHERE violated_directive = %s" . " AND blocked_uri = %s " . " GROUP BY document_uri, useragent", $ViolatedDirective, $BlockedURI); $rows = $wpdb->get_results($sql); foreach ($rows as $obj) { $Data[] = array('document_uri' => !empty($obj->document_uri) ? $obj->document_uri : '(not set)', 'useragent' => !empty($obj->useragent) ? $obj->useragent : '(not set)', 'numerrors' => $obj->numerrors); } $HTML = ''; break; case 'addSafeDomain': if (!empty($Scheme) && empty($Domain)) { $BlockedURI = $Scheme . ':'; } else { if (!empty($Scheme) && !empty($Domain)) { $BlockedURI = $Scheme . "://" . $Domain; } else { $BlockedURI = $Domain; } if (!empty($Path)) { $BlockedURI .= $Path; if (!empty($File)) { $BlockedURI .= $File; } } } $options = get_option(wpCSPclass::SETTINGS_OPTIONS_ALLOPTIONS); $selected = !empty($options[$ViolatedDirective]) ? $options[$ViolatedDirective] : ''; $selected .= " " . $BlockedURI; $options[$ViolatedDirective] = implode(" ", wpCSPclass::CleanPolicyOptionText($selected)); $options = update_option(wpCSPclass::SETTINGS_OPTIONS_ALLOPTIONS, $options); $HTML = 'Successfully added <strong>' . $BlockedURI . '</strong> to the <strong>' . strtoupper($ViolatedDirective) . '</strong> domains list'; break; case 'addIgnoreDomain': if (!empty($Scheme) && empty($Domain)) { $BlockedURI = $Scheme . ':'; } else { if (!empty($Scheme) && !empty($Domain)) { $BlockedURI = $Scheme . "://" . $Domain; } else { $BlockedURI = $Domain; } if (!empty($Path)) { $BlockedURI .= $Path; if (!empty($File)) { $BlockedURI .= $File; } } } $options = get_option(wpCSPclass::SETTINGS_OPTIONS_ALLOPTIONS); $selected = !empty($options[wpCSPclass::SETTINGS_OPTIONS_VIOLATIONSTOIGNORE]) ? $options[wpCSPclass::SETTINGS_OPTIONS_VIOLATIONSTOIGNORE] : ''; $selected .= " " . $BlockedURI; $options[wpCSPclass::SETTINGS_OPTIONS_VIOLATIONSTOIGNORE] = implode(" ", wpCSPclass::CleanPolicyOptionText($selected)); $options = update_option(wpCSPclass::SETTINGS_OPTIONS_ALLOPTIONS, $options); $HTML = 'Successfully added <strong>' . $BlockedURI . '</strong> to the <strong>IGNORED</strong> domains list'; break; case 'clearLogFile': self::ClearLogFile(); $HTML = 'Successfully cleared the log file. Refresh screen to see'; $ReturnStatus = true; break; case 'TestURLChecker': $HTML = self::TestURLChecker(); $ReturnStatus = true; break; default: $HTML = 'Unknown action'; $ReturnStatus = false; break; } } // response output $return = array('success' => $ReturnStatus, 'html' => $HTML, 'data' => $Data); header("HTTP/1.1 200 OK"); header("Content-Type: application/json"); echo json_encode($return); exit; }