Web Security 24x7

Web Security | Web Hacking | Bug Bounty POC | Web Penetration Testing Tools

Sunday, October 30, 2016

XSS Filter in Laravel Framework Part 2

Hello
I am Sajibe Kanti
a Web Security Researcher .

Today I wll Share a  Importance Topic in Laravel

There are two types of XSS Exploits.
In non-persistent mode, the malicious code is not permanent. Imagine a search box that returns results in response to the search query when the user clicks the Search button. If an attacker were to inject code in the search box, it would be executed only once (in response to the process of displaying the search results). A simple page refresh will wipe out the malicious code.
In persistent mode, the Injected malicious code is permanent. Suppose we have a website similar to 4chan, where anyone can create and read posts. An attacker injects the code to initiate the attack. Since the post is saved (so that future visitors can read it), it will be executed every time someone lands on the page with the infected code.

Validation

Validation is defined as the process of ensuring your application is using correct data. For example, if you want to validate age, the field should contain integers only. Likewise, phone numbers should also consist of numbers exclusively. We can also validate by the length of the input. For example it would make sense to limit the age field in an app to 3 digits or Phone Numbers to be between 10-14 digits.

Sanitization

Sanitization is the process of cleaning data to make it safe. By removing any unnecessary characters, we can make sure data is validated and safe for use in the input fields.

Laravel Validation

I have created a very simple to-do app using the Laravel Docs. The user could add and delete  tasks in the app. I will not use controllers for such a small app and instead will create the functions directly in the routes.php file.
Here are the routes:
And the relevant code in the view that shows the tasks:

Now instead of adding a task like I am supposed to, I am going to insert this:
This is an example of a persistent XSS exploit as the task we entered is now saved in the database.
mysql> SELECT names From tasks;
+———————————-+
| names                            |
+———————————-+
| Grocery shopping                 |
| Dry cleaning                     |
| Car wash                         |
| <script>alert(“boom”)</script>   |
+———————————-+
4 rows in set (0.00 sec)
Now anyone who lands on this page is going to see this:
Laravel validation and user input sanitization (3)
Ok, that was mildly uninteresting. But in the hands of a skilled hacker, this can be very dangerous. Fortunately, we can easily prevent this through validation and user input sanitization.
By using the built-in Laravel validators, we can change our “/task” route to:
The important part here is :
regex:[A-Za-z1-9 ]
This prevents the user from inputting any special characters like <>@#$%^&*. Since we’re only inputting tasks (which we know shouldn’t contain any special characters), we can refuse to process the request.
Laravel validation and user input sanitization (1)
There are several valid scenarios where special characters are required. For example:
For emails, use the email validator…
’email’ => ‘required|email’
Or if there is an IP address, use:
For a date:
‘event_date’ => ‘date_format:”d-m-Y”‘ // Ex. validated date = “13-05-2008”
There are validators for numbers, json, images and more.

Laravel Sanitization

Now let’s re-create the same Add Task function, but without any validation. Instead I will sanitize the input by stripping away the script tags using the PHP “strip_tags” function.
Next time we try to inject,
it will strip away all of the tags.
Laravel validation and user input sanitization (5)
Here’s the record in the DB:
mysql> SELECT * FROM tasks;
+—-+——————+———————+———————+
| id | names            | created_at          | updated_at          |
+—-+——————+———————+———————+
|  7 | Grocery shopping | 2016-05-12 06:18:46 | 2016-05-12 06:18:46 |
|  8 | Dry cleaning     | 2016-05-12 06:18:52 | 2016-05-12 06:18:52 |
| 13 | Car wash         | 2016-05-12 09:51:01 | 2016-05-12 09:51:01 |
| 19 |    alert(“boom”) | 2016-05-30 06:56:21 | 2016-05-30 06:56:21 |
+—-+——————+———————+———————+
Using this function, the user will not see the annoying BOOM popup.

Finalizing the Validation and Sanitization

In the previous example, although we managed to prevent the popup from appearing, the user still managed to input a string  that may cause the app to appear comprised. Thus, it is generally a good idea to use both techniques simultaneously.
In this example below, the validator alone is sufficient and makes the input sanitization redundant. However, there is no reason why a real world app could not use both validation and input sanitization in something like the following:
input: “$350,250.000”
validation: Only valid characters? Check
after sanitization: “350250.00”

Escaping Strings

It’s also possible to escape strings just before output. This will prevent any malicious code from executing and instead display the tags as if they were meant to be displayed. In Laravel versions greater than 5.1, this is done by default when using double braces in the templates.
Needless to say the XSS vulnerability in the example app will only be reproducible if you’re using Laravel version 5 or less. If you’re really curious and want to test the vulnerability, it’s possible to tell Laravel not to escape the output:

Best Practices

Here are some key takeaways for best application of this procedure.
  • Add layers of protection. Redundancy improves security. By adding more layers, you give yourself more chances to catch malicious input that might slip through  initial security.
  • Do not overlook client-side validation. This  tutorial was focused on backend validation, but you could easily add a new layer of front-end protection using HTML/JS. For example, I can limit the input length through HTML:
  • Alternatively, I could have used a JS function to validate/sanitize the input.
  • Encoding URLs so as to deny access to the Get parameters.
  • By using an Auto-Escaping Template System such as Laravel Blade Templates.