Skip to content

Commit

Permalink
Centralize instantiation of HTMLPurifier; add policy to filter extern…
Browse files Browse the repository at this point in the history
…al references in user input (Eg. img tags)
  • Loading branch information
collectiveaccess committed Sep 30, 2021
1 parent 6c0e8ae commit 5a3c20b
Show file tree
Hide file tree
Showing 12 changed files with 53 additions and 26 deletions.
4 changes: 2 additions & 2 deletions app/controllers/ClassroomController.php
Expand Up @@ -104,7 +104,7 @@ public function __construct(&$po_request, &$po_response, $pa_view_paths=null) {
$this->view->setVar('classroom_display_name', $this->ops_classroom_display_name);
$this->view->setVar('classroom_display_name_plural', $this->ops_classroom_display_name_plural);

$this->purifier = new HTMLPurifier();
$this->purifier = caGetHTMLPurifier();

$this->view->setVar('educator_role', 'EDUCATOR');
$this->view->setVar('student_role', 'STUDENT');
Expand Down Expand Up @@ -164,4 +164,4 @@ function present($pa_options = null) {
parent::present(array('controller' => 'Classroom', 'display_name' => $this->ops_classroom_display_name, 'display_name_plural' => $this->ops_classroom_display_name_plural));
}
# -------------------------------------------------------
}
}
4 changes: 2 additions & 2 deletions app/controllers/ContactController.php
Expand Up @@ -50,7 +50,7 @@ public function Form() {
# ------------------------------------------------------
public function Send() {
caValidateCSRFToken($this->request);
$o_purifier = new HTMLPurifier();
$o_purifier = caGetHTMLPurifier();
# --- check for errors
$va_errors = array();
if($this->config->get("check_security")){
Expand Down Expand Up @@ -108,4 +108,4 @@ public function Send() {
}
}
# -------------------------------------------------------
}
}
2 changes: 1 addition & 1 deletion app/controllers/DetailController.php
Expand Up @@ -1005,7 +1005,7 @@ public function SendShare() {
$this->render("Form/reload_html.php");
return;
}
$o_purifier = new HTMLPurifier();
$o_purifier = caGetHTMLPurifier();
$ps_to_email = $o_purifier->purify($this->request->getParameter('to_email', pString));
$ps_from_email = $o_purifier->purify($this->request->getParameter('from_email', pString));
$ps_from_name = $o_purifier->purify($this->request->getParameter('from_name', pString));
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/FindController.php
Expand Up @@ -64,7 +64,7 @@ public function __construct(&$po_request, &$po_response, $pa_view_paths=null) {
// Make application plugin manager available to superclasses
$this->opo_app_plugin_manager = new ApplicationPluginManager();

$this->purifier = new HTMLPurifier();
$this->purifier = caGetHTMLPurifier();

parent::__construct($po_request, $po_response, $pa_view_paths);
}
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/system/ErrorController.php
Expand Up @@ -33,7 +33,7 @@ class ErrorController extends ActionController {

# -------------------------------------------------------
function Show() {
$o_purify = new HTMLPurifier(HTMLPurifier_Config::createDefault());
$o_purify = caGetHTMLPurifier();

$va_nums = array_map(function($v) { return intval($v); }, explode(';', $this->request->getParameter('n', pString)));

Expand All @@ -51,4 +51,4 @@ function Show() {
$this->render('error_html.php');
}
# -------------------------------------------------------
}
}
19 changes: 15 additions & 4 deletions app/helpers/errorHelpers.php
Expand Up @@ -7,7 +7,7 @@
* ----------------------------------------------------------------------
*
* Software by Whirl-i-Gig (http://www.whirl-i-gig.com)
* Copyright 2015-2018 Whirl-i-Gig
* Copyright 2015-2021 Whirl-i-Gig
*
* For more information visit http://www.CollectiveAccess.org
*
Expand Down Expand Up @@ -97,7 +97,7 @@ function caDisplayFatalError($pn_errno, $ps_errstr, $ps_errfile, $pn_errline, $p
function caExtractStackTraceArguments($pa_errcontext) {
if(!is_array($pa_errcontext)) { return []; }

$o_purifier = new HTMLPurifier();
$o_purifier = caGetHTMLPurifier();
$pa_args = [];

foreach($pa_errcontext as $vn_i => $va_trace) {
Expand Down Expand Up @@ -134,15 +134,26 @@ function caExtractRequestParams() {

if(!is_array($_REQUEST)) { return []; }

$o_purifier = new HTMLPurifier();
$o_purifier = caGetHTMLPurifier();
$pa_params = [];
foreach($_REQUEST as $vs_k => $vm_val) {
if(is_array($vs_k)) { $vs_k = join(',', caFlattenArray($vs_k));}
if(is_array($vm_val)) { $vm_val = join(',', caFlattenArray($vm_val));}
if($vs_k == 'password') { continue; } // don't dump plain text passwords on screen
$pa_params[$o_purifier->purify($vs_k)] = $o_purifier->purify($vm_val);
}

return $pa_params;
}
# --------------------------------------------------------------------------------------------
/**
* Return URL path to themes directory, guessing based upon PHP script name is constants aren't set
*
* @return string
*/
function caGetThemeUrlPath() : string {
$tmp = explode("/", str_replace("\\", "/", $_SERVER['SCRIPT_NAME']));
array_pop($tmp);
return defined('__CA_THEME_URL__') ? __CA_THEME_URL__ : join("/", $tmp).'/themes/default';
}
# ---------------------------------------------------------------------------------------------

19 changes: 16 additions & 3 deletions app/helpers/utilityHelpers.php
Expand Up @@ -2344,7 +2344,7 @@ function caPurifyArray($pa_array, $pa_options=null) {
if (!is_array($pa_array)) { return array(); }

if (!(($o_purifier = caGetOption('purifier', $pa_options, null)) instanceof HTMLPurifier)) {
$o_purifier = new HTMLPurifier();
$o_purifier = caGetHTMLPurifier();
}

if (!is_array($pa_array)) { return $o_purifier->purify($pa_array); }
Expand Down Expand Up @@ -4022,7 +4022,7 @@ function caNormalizeValueArray($pa_values, $pa_options=null) {
$o_purifier = null;
if($pb_purify = caGetOption('purify', $pa_options, false)) {
if (!(($o_purifier = caGetOption('purifier', $pa_options, null)) instanceof HTMLPurifier)) {
$o_purifier = new HTMLPurifier();
$o_purifier = caGetHTMLPurifier();
}
}

Expand Down Expand Up @@ -4474,7 +4474,9 @@ function caPrettyJson( $var ) {
);
}
# ----------------------------------------

/**
*
*/
function caReturnValueInBytes($vs_val) {
$vs_val = trim($vs_val);
$vs_last = strtolower($vs_val[strlen($vs_val)-1]);
Expand All @@ -4490,3 +4492,14 @@ function caReturnValueInBytes($vs_val) {
}
return $vs_val;
}
# ----------------------------------------
/**
*
*/
function caGetHTMLPurifier(?array $options=null) : HTMLPurifier {
$config = HTMLPurifier_Config::createDefault();
$config->set('URI.DisableExternalResources', !Configuration::load()->get('purify_allow_external_references'));
return new HTMLPurifier($config);
}
# ----------------------------------------

4 changes: 3 additions & 1 deletion app/lib/BaseModel.php
Expand Up @@ -551,7 +551,9 @@ public function purify($pb_purify=null) {
* @return HTMLPurifier Returns instance
*/
static public function getPurifier() {
if (!BaseModel::$html_purifier) { BaseModel::$html_purifier = new HTMLPurifier(); }
if (!BaseModel::$html_purifier) {
BaseModel::$html_purifier = caGetHTMLPurifier();
}
return BaseModel::$html_purifier;
}
# --------------------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions app/lib/Browse/BrowseEngine.php
Expand Up @@ -362,9 +362,9 @@ public function addCriteria($ps_facet_name, $pa_row_ids, $pa_display_strings=nul
$va_criteria_display_strings = $this->opo_ca_browse_cache->getParameter('criteria_display_strings');
if (!is_array($pa_row_ids)) { $pa_row_ids = array($pa_row_ids); }

$purifier = new HTMLPurifier();
$o_purifier = caGetHTMLPurifier();
foreach($pa_row_ids as $vn_i => $vn_row_id) {
$vn_row_id = $purifier->purify(urldecode($vn_row_id)); // sanitize facet values
$vn_row_id = $o_purifier->purify(urldecode($vn_row_id)); // sanitize facet values
$va_criteria[$ps_facet_name][urldecode($vn_row_id)] = true;

if (isset($pa_display_strings[$vn_i])) { $va_criteria_display_strings[$ps_facet_name][urldecode($vn_row_id)] = $pa_display_strings[$vn_i]; }
Expand Down
4 changes: 3 additions & 1 deletion app/lib/Controller/Request/RequestHTTP.php
Expand Up @@ -521,7 +521,9 @@ public function getRequestUrl($pb_absolute=false) {
* @return HTMLPurifier Returns instance
*/
static public function getPurifier() {
if (!RequestHTTP::$html_purifier) { RequestHTTP::$html_purifier = new HTMLPurifier(); }
if (!RequestHTTP::$html_purifier) {
RequestHTTP::$html_purifier = caGetHTMLPurifier();
}
return RequestHTTP::$html_purifier;
}
# -------------------------------------------------------
Expand Down
11 changes: 5 additions & 6 deletions app/lib/Logging/Eventlog.php
Expand Up @@ -77,13 +77,13 @@ public function log($pa_entry) {
if (!$pa_entry["MESSAGE"]) {
return false;
}
$purifier = new HTMLPurifier();
$o_purifier = caGetHTMLPurifier();
$this->o_db->query("
INSERT INTO ca_eventlog
(date_time, code, message, source)
VALUES
(unix_timestamp(), ?, ?, ?)
", $pa_entry["CODE"], $purifier->purify($pa_entry["MESSAGE"]), $pa_entry["SOURCE"]);
", $pa_entry["CODE"], $o_purifier->purify($pa_entry["MESSAGE"]), $pa_entry["SOURCE"]);

return true;
}
Expand Down Expand Up @@ -126,9 +126,9 @@ public function search($ps_datetime_expression, $ps_code=null) {
");
}
$entries = $qr_log->getAllRows();
$purifier = new HTMLPurifier();
return array_map(function($e) use ($purifier) {
$e['message'] = $purifier->purify($e['message']);
$o_purifier = caGetHTMLPurifier();
return array_map(function($e) use ($o_purifier) {
$e['message'] = $o_purifier->purify($e['message']);
return $e;
}, $entries);
}
Expand All @@ -137,4 +137,3 @@ public function search($ps_datetime_expression, $ps_code=null) {
}
# ----------------------------------------
}
?>
2 changes: 1 addition & 1 deletion app/models/ca_users.php
Expand Up @@ -1641,7 +1641,7 @@ public function getPreferenceDefault($ps_pref, $pa_options=null) {
public function setPreference($ps_pref, $ps_val) {
if ($this->isValidPreference($ps_pref)) {
if ($this->purify()) {
if (!BaseModel::$html_purifier) { BaseModel::$html_purifier = new HTMLPurifier(); }
if (!BaseModel::$html_purifier) { BaseModel::$html_purifier = caGetHTMLPurifier(); }
if(!is_array($ps_val)) { $ps_val = BaseModel::$html_purifier->purify($ps_val); }
}
if ($this->isValidPreferenceValue($ps_pref, $ps_val, 1)) {
Expand Down

0 comments on commit 5a3c20b

Please sign in to comment.