pasé algún tiempo en este problema recientemente. Aquí está el esquema de mi solución.
he creado una nueva clase llamada HtmlSafe que contiene cadenas de caracteres que se pueden escribir de forma segura al cliente WWW sin una vulnerabilidad de seguridad. La idea era que las funciones que generan etiquetas HTML devuelvan objetos HtmlSafe, y las variables listas para usar no son HtmlSafe. Lo que crea un HtmlSafe también ha avalado la seguridad de la cadena en cuestión. Concatenar una cadena que no sea segura para HTML con una cadena segura para HTML hace que la cadena que no sea segura para HTML se escape mediante CGI :: escapeHTML y luego se una a la cadena segura para HTML. Concatenando otra instancia de HtmlSafe a HtmlSafe solo une las cadenas en cuestión sin escapar. Terminé usando una sobrecarga para poder redefinir el. operador para la clase HtmlSafe.
Armado con esta cosa, me dio a> $ proceso en plantillas() Función de una variable de salida $ que era en realidad un sub que invocó una concatenación con HtmlSafe, así:
my $output = HtmlSafe->new("");
$template->process($vars, sub { $output .= $_[0]; });
return $output->unwrap(); # remove HtmlSafe and return underlying string
Estamos casi listos con el HtmlSafe TT2. El gran cambio que tuve que hacer realmente fue cambiar la función textblock() en Template :: Directive, que es utilizada por el Template :: Parser para generar instancias HtmlSafe de cualquier bloque de texto que intente emitir. Estos parecen corresponder con los nodos de texto de la plantilla analizada, por lo que acaba de hacer
package MyDirective;
use base "Template::Directive";
sub textblock { my $self = shift; return "$Template::Directive::OUTPUT HtmlSafe->new(" . $self->text(@_) . ")"; }
que di a parser de este modo:
my $parser = Template::Parser->new({
FACTORY => "MyDirective",
});
Además de esto, he definido un filtro "ninguna" para TT2 que simplemente envuelve lo que se define como HtmlSafe, por lo que puede generar HTML sin procesar si es necesario. Esto evita escapar cosas. El filtro predeterminado "html" no es operativo, ya que cualquier elemento concatenado con HtmlSafe se escapó de todos modos.
Una plantilla personalizada :: Stash probablemente no sería lo suficientemente bueno.Tanto '[% x%]' como '[% y = x%]' llamarían al método 'get()' del escondite para buscar 'x', pero solo el primero producirá, el alijo probablemente no sea capaz de di la diferencia entre "obtener e imprimir" y simplemente "obtener" para que termines con mucho doble/triple/... cosas codificadas en HTML. Probablemente es mejor no molestarse. –
La filosofía de diseño de TT es permitir ataques de secuencias de comandos entre sitios de forma predeterminada y solo permite la seguridad mediante grandes cantidades de afeitado de yak. – geira
Sí, eso sería demasiado conveniente para encajar en la filosofía TT. – jeje