Websites and web applications are vulnerable to XSS attacks and although PHP provides escaping functionality, in some contexts it is not sufficient/appropriate. Phalcon\Escaper provides contextual escaping and is written in Zephir, providing the 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. Para ilustrar cómo funciona este componente y por qué es importante, considere el siguiente ejemplo:
<?php
use Phalcon\Escaper;
$escaper = new Escaper();
$title = '</title><script>alert(1)</script>';
echo $escaper->escapeHtml($title);
// </title><script>alert(1)</script>
$css = ';`(';
echo $escaper->escapeCss($css);
// < / style>
$fontName = 'Verdana\"</style>';
echo $escaper->escapeCss($fontName);
// Verdana\22 \3c \2f style\3e
$js = "';</script>Hello";
echo $escaper->escapeJs($js);
// \x27\x3b\x3c\2fscript\x3eHello
Puede escapar el texto antes de imprimirlo en sus vistas usando escapeHtml()
. Sin escapar podría mostrar datos potencialmente inseguros en su salida HTML.
<?php
use Phalcon\Escaper;
$escaper = new Escaper();
$title = '</title><script>alert(1)</script>';
echo $escaper->escapeHtml($title);
// </title><script>alert(1)</script>
Sintaxis HTML:
<?php echo $this->escaper->escapeHtml($title); ?>
Sintaxis Volt:
{{ title | escape }}
El escape de atributos es diferente del escape de contenido HTML. El escape funciona cambiando cada carácter no alfanumérico a un formato seguro. It uses htmlspecialchars internally. Este tipo de escape está destinado a escapar atributos complejos como href
o url
. Para escapar atributos, puede usar el método escapeHtmlAttr()
<?php
use Phalcon\Escaper;
$escaper = new Escaper();
$attr = '"><h1>Hello</table';
echo $escaper->escapeHtmlAttr($attr);
// "><h1>Hello</table
Sintaxis HTML:
<?php echo $this->escaper->escapeHtmlAttr($attr); ?>
Sintaxis Volt:
{{ attr | escape_attr }}
Se puede usar escapeUrl()
para escapar atributos como href
o url
:
<?php
use Phalcon\Escaper;
$escaper = new Escaper();
$url = '"><script>alert(1)</script><a href="#';
echo $escaper->escapeHtmlAttr($url);
// %22%3E%3Cscript%3Ealert%281%29%3C%2Fscript%3E%3Ca%20href%3D%22%23
Sintaxis HTML:
<?php echo $this->escaper->escapeHtmlAttr($url); ?>
Los Identificadores/valores CSS se pueden escapar usando escapeCss()
:
<?php
use Phalcon\Escaper;
$escaper = new Escaper();
$css = '"><script>alert(1)</script><a href="#';
echo $escaper->escapeCss($css);
// \22 \3e \3c script\3e alert\28 1\29 \3c \2f script\3e \3c a\20 href\3d \22 \23
Sintaxis HTML:
<?php echo $this->escaper->escapeCss($css); ?>
Sintaxis Volt:
{{ css | escape_css }}
El contenido impreso en código javascript debe ser escapado adecuadamente. escapeJs()
ayuda en esta tarea:
<?php
use Phalcon\Escaper;
$escaper = new Escaper();
$js = "'; alert(100); var x='";
echo $escaper->escapeJs($js);
// \x27; alert(100); var x\x3d\x27
Sintaxis HTML:
<?php echo $this->escaper->escapeJs($js); ?>
Sintaxis Volt:
{{ js | escape_js }}
Phalcon\Escape also offers methods regarding the encoding of the text to be escaped.
detectEncoding()
Detecta la codificación de caracteres de una cadena a ser gestionada por un codificador. Special-handling for chr(172)
and chr(128)
to chr(159)
which fail to be detected mb_detect_encoding. El método devuelve string
con la codificación detectada o null
<?php
use Phalcon\Escaper;
$escaper = new Escaper();
echo $escaper->detectEncoding('ḂḃĊċḊḋḞḟĠġṀṁ'); // UTF-8
getEncoding()
Devuelve la codificación interna usada por el escapador
<?php
use Phalcon\Escaper;
$escaper = new Escaper();
echo $escaper->getEncoding();
normalizeEncoding()
Método de utilidad que normaliza la codificación de una cadena a UTF-32.
<?php
use Phalcon\Escaper;
$escaper = new Escaper();
echo $escaper->normalizeEncoding('ḂḃĊċḊḋḞḟĠġṀṁ');
setEncoding()
Configura la codificación a ser usada por el escapador
<?php
use Phalcon\Escaper;
$escaper = new Escaper();
$escaper->setEncoding('utf-8');
echo $escaper->getEncoding(); // 'utf-8'
setDoubleEncode()
Configura el escapador para usar doble codificación o no (por defecto true
)
<?php
use Phalcon\Escaper;
$escaper = new Escaper();
$escaper->setDoubleEncode(false);
setHtmlQuoteType()
Puede configurar el tipo de comillas a usar por el escapador. 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
<?php
use Phalcon\Escaper;
$escaper = new Escaper();
$escaper->setHtmlQuoteType(ENT_XHTML);
Any exceptions thrown in the Escaper component will be of type Phalcon\Escaper\Exception. Se lanza cuando los datos proporcionados al componente no son válidos. Puede usar estas excepciones para capturar selectivamente sólo las excepciones lanzadas desde este componente.
<?php
use Phalcon\Escaper;
use Phalcon\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();
}
}
}
If you use the Phalcon\Di\FactoryDefault container, the Phalcon\Escaper is already registered for you with the name escaper
.
A continuación, un ejemplo de registro del servicio así como de acceso a él:
<?php
use Phalcon\Di;
use Phalcon\Escaper;
$container = new Di();
$container->set(
'escaper',
function () use {
return new Escaper();
}
);
Ahora puede usar el componente en un controlador (o un componente que implemente Phalcon\Di\Injectable
)
<?php
namespace MyApp;
use Phalcon\Escaper;
use Phalcon\Mvc\Controller;
/**
* Invoices controller
*
* @property Escaper $escaper
*/
class InvoicesController extends Controller
{
public function indexAction()
{
}
public function saveAction()
{
echo $this->escaper->escapeHtml('The post was correctly saved!');
}
}
Phalcon also offers the Phalcon\Escaper\EscaperInterface which can be implemented in a custom class. La clase puede ofrecer la funcionalidad de escape que requiera.
<?php
namespace MyApp\Escaper;
use Phalcon\Escaper\EscaperInterface;
class Custom extends EscaperInterface
{
/**
* Escape CSS strings by replacing non-alphanumeric chars by their
* hexadecimal representation
*/
public function escapeCss(string $css): string;
/**
* Escapes a HTML string
*/
public function escapeHtml(string $text): string;
/**
* Escapes a HTML attribute string
*/
public function escapeHtmlAttr(string $text): string;
/**
* Escape Javascript strings by replacing
* non-alphanumeric chars by their hexadecimal
* representation
*/
public function escapeJs(string $js): string;
/**
* Escapes a URL. Internally uses rawurlencode
*/
public function escapeUrl(string $url): string;
/**
* Returns the internal encoding used by the escaper
*/
public function getEncoding(): string;
/**
* Sets the encoding to be used by the escaper
*/
public function setEncoding(string $encoding): void;
/**
* Sets the HTML quoting type for htmlspecialchars
*/
public function setHtmlQuoteType(int $quoteType): void;
}