Georg Schölly
Georg Schölly

Reputation: 126105

How to conditionally escape values in Slim and Twig?

Code

We have the following Twig HTML template:

<div id="error">{{ flash.error | raw }}</div>

and we flash messages in multiple places, e.g.:

$app->flash('error', "Some error with this $user_supplied string.");
$app->flash('error', "Hello, <b>World</b>!");

Question

This is obviously a security concern, $user_supplied could include javascript. I would like to replace {{ flash.error | raw }} with {{ flash.error }}, while still allowing HTML in some cases.

What I would like to have:

<div id="error">{{ flash.error }}</div>
----
$app->flash('error', "Some error with this $user_supplied string.");
$app->flash('error', HTML("Hello, <b>World</b>!"));

That way all developers realize the dangers. I can probably hack this together, but is there maybe already a built-in way or a better alternative?

Upvotes: 0

Views: 737

Answers (3)

Andrew Smith
Andrew Smith

Reputation: 1841

You can do this in your twig configuration, without knowing much about your project I am going to assume you are using Twig View. At the point of configuring Twig View for your Slim project you can do the following:

$view = new \Slim\Views\Twig('path/to/templates', [
    'cache' => 'path/to/cache',
    'autoescape' => 'js'
]);

That should have it configured globally for JS only escaping. I have not tested this so I am not sure if it works.

Upvotes: 0

Sunil
Sunil

Reputation: 155

Hm, Perhaps you can check the contents of the variable in the PHP code before you pass it to the template. Then use some of PHP's built in string parsing functions to check the variable for the existence of certain tags.

If (for example) script tags are found, you could set the variable to null or false and then handle that value in your template.

Another way I can think of is to use the striptags filter. You define your allowed tags and what isn't defined will be removed. This way you can output what you want and only keep your allowed tags.

https://twig.symfony.com/doc/2.x/filters/striptags.html

{% set some_var = '<b><script>console.log(123)</script></b>' %}

<div id="error">{{ some_var|striptags('<b><strong>')|raw }}</div>

Upvotes: 1

Sanan Guliyev
Sanan Guliyev

Reputation: 761

You can use escape twig variable for specific needs.

{{ flash.error|escape('js') }}

The escape filter supports the following escaping strategies:

html, js, css, url, html_attr

Upvotes: 0

Related Questions