Escaper¶
Overview¶
Websites and web applications are vulnerable to XSS attacks and although PHP provides escaping functionality, in some contexts, it is not sufficient/appropriate. Phalcon\Html\Escaper provides contextual escaping and is written in Zephir, providing minimal overhead when escaping different kinds of texts.
We designed this component based on the XSS (Cross-Site Scripting) Prevention Cheat Sheet created by the OWASP. Additionally, this component relies on mbstring to support almost any charset. To illustrate how this component works and why it is important, consider the following example:
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
$title = '</title><script>alert(1)</script>';
echo $escaper->html($title);
// </title><script>alert(1)</script>
$css = ';`(';
echo $escaper->css($css);
// < / style>
$fontName = 'Verdana\"</style>';
echo $escaper->css($fontName);
// Verdana\22 \3c \2f style\3e
$js = "';</script>Hello";
echo $escaper->js($js);
// \x27\x3b\x3c\2fscript\x3eHello
HTML¶
You can escape text before printing it to your views using html()
. Without escaping you could potentially echo unsafe data in your HTML output.
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
$title = '</title><script>alert(1)</script>';
echo $escaper->html($title);
// </title><script>alert(1)</script>
HTML syntax:
Volt syntax:
HTML Attributes¶
Escaping attributes is different from escaping HTML content. The escaper works by changing every non-alphanumeric character to a safe format. It uses htmlspecialchars internally. This kind of escaping is intended escape excluding complex ones such as href
or url
. To escape attributes, you can use the attributes()
method. This method has been renamed. The old method escapeHtmlAttr()
will be removed in the future and emit a @deprecated
warning.
The method also accepts an array as a parameter. The keys are the attribute names and the values are attribute values. If a value is boolean (true
/false
) then the attribute will have no value:
The resulting string will have attribute pairs separated by a space.
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
$attr = '"><h1>Hello</table';
echo $escaper->attributes($attr);
// "><h1>Hello</table
HTML syntax:
Volt syntax:
URLs¶
url()
can be used to escape attributes such as href
or url
. This method has been renamed. The old method escapeUrl()
will be removed in the future and emit a @deprecated
warning.
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
$url = '"><script>alert(1)</script><a href="#';
echo $escaper->attributes($url);
// %22%3E%3Cscript%3Ealert%281%29%3C%2Fscript%3E%3Ca%20href%3D%22%23
HTML syntax:
CSS¶
CSS identifiers/values can be escaped by using css()
. This method has been renamed. The old method escapeCss()
will be removed in the future and emits a @deprecated
warning.
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
$css = '"><script>alert(1)</script><a href="#';
echo $escaper->css($css);
// \22 \3e \3c script\3e alert\28 1\29 \3c \2f script\3e \3c a\20 href\3d \22 \23
HTML syntax:
Volt syntax:
JavaScript¶
Content printed into javascript code must be properly escaped. js()
helps with this task. This method has been renamed. The old method escapeJs()
will be removed in the future and emits a @deprecated
warning.
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
$js = "'; alert(100); var x='";
echo $escaper->js($js);
// \x27; alert(100); var x\x3d\x27
HTML syntax:
Volt syntax:
Encoding¶
Phalcon\Html\Escape also offers methods regarding the encoding of the text to be escaped.
detectEncoding()
¶
Detects the character encoding of a string to be handled by an encoder. Special-handling for chr(172)
and chr(128)
to chr(159)
which fail to be detected mb_detect_encoding. The method returns a string
with the detected encoding or null
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
echo $escaper->detectEncoding('ḂḃĊċḊḋḞḟĠġṀṁ'); // UTF-8
getEncoding()
¶
Returns the internal encoding used by the escaper
normalizeEncoding()
¶
Utility method that normalizes a string's encoding to UTF-32.
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
echo $escaper->normalizeEncoding('ḂḃĊċḊḋḞḟĠġṀṁ');
setEncoding()
¶
Sets the encoding to be used by the escaper
<?php
use Phalcon\Html\Escaper;
$escaper = new Escaper();
$escaper->setEncoding('utf-8');
echo $escaper->getEncoding(); // 'utf-8'
setDoubleEncode()
¶
Sets the escaper to use double encoding or not (default true
)
setFlags(int $flags)
¶
You can set the quote type to be used by the escaper. This method has been renamed. The old method setHtmlQuoteType()
will be removed in the future and emit a @deprecated
warning.
The passed variable is one of the constants that htmlspecialchars accepts: - ENT_COMPAT
- ENT_QUOTES
- ENT_NOQUOTES
- ENT_IGNORE
- ENT_SUBSTITUTE
- ENT_DISALLOWED
- ENT_HTML401
- ENT_XML1
- ENT_XHTML
- ENT_HTML5
Exceptions¶
Any exceptions thrown in the Escaper component will be of type Phalcon\Html\Escaper\Exception. It is thrown when the data supplied to the component is not valid. You can use these exceptions to selectively catch exceptions thrown only from this component.
<?php
use Phalcon\Html\Escaper;
use Phalcon\Html\Escaper\Exception;
use Phalcon\Mvc\Controller;
/**
* @property Escaper $escaper
*/
class IndexController extends Controller
{
public function index()
{
try {
echo $this->escaper->normalizeEncoding('ḂḃĊċḊḋḞḟĠġṀṁ');
} catch (Exception $ex) {
echo $ex->getMessage();
}
}
}
Dependency Injection¶
If you use the Phalcon\Di\FactoryDefault container, the Phalcon\Html\Escaper is already registered for you with the name escaper
.
An example of the registration of the service as well as accessing it is below:
<?php
use Phalcon\Di\Di;
use Phalcon\Html\Escaper;
$container = new Di();
$container->set(
'escaper',
function () use {
return new Escaper();
}
);
You can now use the component in a controller (or a component that implements Phalcon\Di\Injectable)
<?php
namespace MyApp;
use Phalcon\Html\Escaper;
use Phalcon\Mvc\Controller;
/**
* Invoices controller
*
* @property Escaper $escaper
*/
class InvoicesController extends Controller
{
public function indexAction()
{
}
public function saveAction()
{
echo $this->escaper->html('The post was correctly saved!');
}
}
Custom¶
Phalcon also offers the Phalcon\Html\Escaper\EscaperInterface which can be implemented in a custom class. The class can offer the escaper functionality you require.
<?php
namespace MyApp\Escaper;
use Phalcon\Html\Escaper\EscaperInterface;
class Custom extends EscaperInterface
{
public function css(string $css): string;
public function html(string $text): string;
public function attributes(string $text): string;
public function js(string $js): string;
public function url(string $url): string;
public function getEncoding(): string;
public function setEncoding(string $encoding): void;
public function setHtmlQuoteType(int $quoteType): void;
}