On Laravel 5.8 I can use double curly braces to escape a string {{ "<script>alert('does not work');</script>" }}
or a variable {{ $comment }}
However, if I use LaravelCollective/html package to create html elements, double curly braces doesn't escape anything. {{ Form::input('edit', 'test') }}
creates an input.
How does LaravelCollective/html achieve this or is this an exception in Blade syntax itself? Is {{ }}
a secure way to escape anything if it's sometimes escaped and sometimes not? Could I make a custom class to fool Laravel into thinking I'm using LaravelCollective/html and get unescaped content printed with the custom class/object with {{ }}
?
It seems LaravelCollective/html achieves this by registering a custom handler with BladeCompiler::directive()
, so it's an extension feature provided by Blade. As such it's safe to use {{ }}
for both escaping and creating html elements with LaravelCollective.
For reference, here's a snippet from HtmlServiceProvider.php in LaravelCollective/Html for how it's done.
/**
* Register Blade directives.
*
* @return void
*/
protected function registerBladeDirectives()
{
$this->app->afterResolving('blade.compiler', function (BladeCompiler $bladeCompiler) {
$namespaces = [
'Html' => get_class_methods(HtmlBuilder::class),
'Form' => get_class_methods(FormBuilder::class),
];
foreach ($namespaces as $namespace => $methods) {
foreach ($methods as $method) {
if (in_array($method, $this->directives)) {
$snakeMethod = Str::snake($method);
$directive = strtolower($namespace).'_'.$snakeMethod;
$bladeCompiler->directive($directive, function ($expression) use ($namespace, $method) {
return "<?php echo $namespace::$method($expression); ?>";
});
}
}
}
});
}