Ticket #766 (closed defect: fixed)
Integrating HTMLPurifier Library into QCubed
| Reported by: | vaibhav | Owned by: | |
|---|---|---|---|
| Priority: | important | Milestone: | 2.1 |
| Component: | QControls | Version: | 2.0.2 Stable |
| Keywords: | HTMLPurifier, HTML, XSS, Content Filtering, Security | Cc: |
Description (last modified by alex94040) (diff)
Related thread: http://qcu.be/content/safeguard-your-qcubed-based-app-xss-htmlpurifier-integrated-qcubed
Well, the first thing - I have marked this to the milestone of 3.0.0 because I DO THINK that this is a huge improvement / addition to QCubed (that may be perhaps coz I am really happy :) ). If an admin thinks it should be a bit lower, I would have no problems either.
There are two files attached. One is enumerations file and the other is the TextBox? base class file. Go through them or create a patch to see the differences. I did not create a patch because
1. I usually mess up with that, specially in QCubed.
2. The version of file on the server and mine might differ coz I do not apply all patches from here.
Basic changes I have done are described below:
=== to _enumerations.inc.php ====
[Add two new consts Purify and PurifyCustom? to the class]:
abstract class QCrossScripting {
const Allow = 'Allow';
const HtmlEntities? = 'HtmlEntities?';
const Deny = 'Deny';
const Purify = 'HTMLPurifierXSSProtectionConfig';
const PurifyCustom? = 'HTMLPurifierEmptyConfig';
}
/////////////////////
=== to QTextBoxBase.class.php ====
[create function]:
public function SetPurifierConfig?($Parameter, $Value) {
$this->HTMLPurifierConfig->set($Parameter, $Value);
}
///////////////////////
[Add switch cases to crossscripting in the validator function]:
case QCrossScripting::Purify:
case QCrossScripting::PurifyCustom?:
// let HTMLPurifier do the job! User should have set it up or be happy with the defaults!
$strText = strtolower($this->strText);
$objPurifier = new HTMLPurifier($this->HTMLPurifierConfig);
$this->strText = $objPurifier->purify($this->strText);
/////////////////////////
[Modified the set function's case of CrossScripting?]
case "CrossScripting?":
try {
$this->strCrossScripting = QType::Cast($mixValue, QType::String);
// Protect from XSS to the best we can do with HTMLPurifier.
if($this->strCrossScripting == QCrossScripting::Purify)
{
/**
- If we are purifying using HTMLPurify, we will need the autoloader be included.
- We load lazy to make sure that the library is not loaded everytime 'prepend.inc.php'
- or 'qcubed.inc.php' is inlcuded. HTMLPurifier is a HUGE and SLOW library. Lazy loading
- keeps it simpler. */
require_once(INCLUDES .'/external_libraries/htmlpurifier/library/HTMLPurifier.auto.php');
/**
- We configure the default set of tags (elements) and allowed here
- (in the setter function) so that the rules are applicable the moment
- CrossScripting? is set to 'Purify'.
- If you want to allow any of the tags or attributes blocked below,
- Please use QCrossScripting::PurifyCustom? and decide all for yourself. */
$this->HTMLPurifierConfig = HTMLPurifier_Config::createDefault();
$this->HTMLPurifierConfig->set('HTML.ForbiddenElements?', 'script,applet,embed,style,link,iframe,body,object');
$this->HTMLPurifierConfig->set('HTML.ForbiddenAttributes?', '*@onfocus,*@onblur,*@onkeydown,*@onkeyup,*@onkeypress,*@onmousedown,*@onmouseup,*@onmouseover,*@onmouseout,*@onmousemove,*@onclick');
}
// Just allow the user to use HTMLPurifier. He decides what HTMLPurifier should do.
if($this->strCrossScripting == QCrossScripting::PurifyCustom?)
{
// If we are purifying using HTMLPurify, we will need the autoloader be included.
require_once(INCLUDES .'/external_libraries/htmlpurifier/library/HTMLPurifier.auto.php');
/**
- We configure nothing, leaving all to the good wish of the user.
- It will create a blank / default config only. */
$this->HTMLPurifierConfig = HTMLPurifier_Config::createDefault();
}
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset?();
throw $objExc;
}
==============
That is all. To use the facilities provided, you need to use the crossscripting enums as:
$this->txtSomeTextBox->CrossScripting? = QCrossScripting::Purify;
OR
$this->txtSomeTextBox->CrossScripting? = QCrossScripting::Purify;
and use the SetPurifierConfig? function to add other configurations you want:
$this->txtSomeTextBox->SetPurifierConfig?('Core.Encoding', 'UTF-8');
$this->txtSomeTextBox->SetPurifierConfig?('AutoFormat?.AutoParagraph?', true);
$this->txtSomeTextBox->SetPurifierConfig?('HTML.Allowed', 'p,b,strong,i,em,u,i,code,img[src]');
====

