Problem
Blade Templates – Escaping text and allowing new lines.
- Need to render text having new line character (\n)
Before getting to the solution, It is important to understand the PHP and Laravel helper function which we are going to use.
Render Text Having “\n” Character
- Problem is that the “\n” character should be encoded into the “br /” tag so all the statements will be displayed in a new line.
nl2br() PHP Function
nl2br() php function is used to convert “\n” (new line character) into “
” tag so the browser can display the next sentence in a new line.
echo nl2br(“This is a sample text.\nIt has multiple lines.\nContains new line characters.”);
Output:
e() Laravel helper function
- e() is a Laravel helper function that runs PHP’s htmlspecialchars() function with double encoding.
- This will work the same as a blade’s {{ }} echo syntax.
What is double encoding?
- Double encoding means whether to encode existing HTML entities or not.
- To enable double_encoding, you need to pass the “double_encode” argument of htmlspecialchars() function as true. Default value is true.
- For example we have a text “The HTML entity for ‘&’ is ‘&’”
- If we pass double_encode option of htmlspecialchars() function as ture the above text will be converted to “The HTML entity for ‘&’ is ‘&”
- The both occurrences of “&” is converted to “&”
- If the double_encode argument value is passed as false then the output will be “The HTML entity for ‘&’ is ‘&’”.
- Here & is considered as a HTML entity and htmlspecialchars() function escapes it because the double_encode option is false. But this changed the entire meaning of the sentence. So to encode special characters specified along with HTML entities we need to pass double_encode argument as true.
- By default in blade and (Laravel’s e() helper function) using htmlspecialchars() function with double_encode argument as true. You can disable double_encode from AppServiceProvider.
Solution
Escaping text and allowing new line
In this topic we will learn how we can use Laravel’s e() (escape helper function) and PHP’s nl2br() function to escape and convert HTML tags into entities to prevent XSS attacks and display sentences in new lines.
{!! nl2br(e($userInput)) !!}
This is how our code will look like. Let’s see the example source code in the next slide.
We are using {!! !!} blade echo syntax because we are already escaping the special characters using e() helper so no need to use.
Example:
<div>
@php
$textClass = "text-blue-100 text-lg";
$userInput = "<script>alert('Hello')</script>\nThis is a sample text.\nIt has multiple lines.\nContains new line characters.";
@endphp
<div class="bg-gray-200 m-5 p-5 rounded-lg">
{{-- Escaping text and display in new line. (We are using {!! !!} syntax because we already escaping special characters using e() helper) --}}
<div class="bg-gray-900 m-5 p-5 rounded-lg">
<p class="{{ $textClass }}">
{!! nl2br(e($userInput)) !!}
</p>
</div>
</div>
</div>
In the example we have an input field in which the user can add “\n” (new line character) and HTML tags as well so we need to display it on the browser accordingly. So in this case an attacker can easily add Javascript to do XSS attack. In our example the user has added Javascript.
<script> alert('Hello') </script>
To prevent this type of insertion we are using e() and to display in a new line we are using nl2br().
Best Approach
- e() function of blade’s {{ }} echo syntax will convert all the tags in HTML entity but sometimes you want to render user input as HTML and also want to prevent XSS attacks.
- In this case it is better to use feature rich editors like CK Editor. Which will not allow users to add Script.
- Another way is you can also parse that HTML on your end from the backend and remove < scrip t> tags and allow only required HTML tags. PHP’s strip_tags() can be useful in this.