PHP is a flexible and convenient language to build web applications. This convenience comes as a double-edged sword because the features that allow you to quickly build your software also can lead to creating vulnerabilities and backdoors.
Fortunately, Laravel is a great tool to build reliable and secure web applications. In this article, we will learn about the most common security vulnerabilities that many web applications deal with, and how Laravel can help us to prevent them.
Laravel has a release supporting policy where it describes general releases and long term support (LTS) releases. When building large applications it is suggested to use the LTS release, which provides security fixes for three years, and bug fixes for two years.
What are the most critical security risks to web applications?
The Open Web Application Security Project (OWASP) creates tools and documentation that help developers build secure and reliable web applications. The OWASP Top 10 is a standard awareness document on web application security, listing the most common web vulnerabilities. Getting to know them and how to protect your software is the start of the process of minimizing your risks.
Sanitizing User Inputs
User’s data is core to web applications but it needs to be verified to prevent exploits of vulnerabilities. Particularly dangerous are inputs used to query databases and to manage files. To protect your user’s data, you’ll have to pay special attention to validate the information that enters your system.
The best practices for filtering user input are:
- Allow only expected input, use an allow list approach whenever it’s possible. It means that you have a list of approved data that you can compare with the user input, data is invalid unless it can be proved to be valid.
- Never correct invalid data.
- Check data type, length and format.
Laravel provides validators for different types of data that we can easily use in our project.
$validatedData = $request->validate([ 'title' => 'required|unique:posts|max:255', 'body' => 'required', ]);
Protecting Against SQL Injection
When constructing SQL queries to retrieve data from databases, we often use the information provided by the user. This can be a door to vulnerabilities since the user can send a carefully constructed value that will get interpreted by the database and potentially expose sensitive information.
$name = $_POST['name']; $passwod = $_POST['password']; // Vulnerable to SQL injection $query = " SELECT * FROM employee WHERE name='$name' and password='$password'";
The problem here is that the $name
and $password
are not sanitized and validated, so its value can be manipulated to format a malicious SQL query. An attacker could insert John’ --
and that would result in the database never checking the password before granting user access.
SELECT * FROM employee WHERE name=‘John’ — and password=‘$password’
SQL injection can also allow the attacker to execute arbitrary queries on your database, which can lead to data loss.
Laravel query builder and its ORM (Eloquent) both protect your application against SQL Injection. This can be used to safely perform most database operations and works well on all supported database systems. You won’t be automatically protected if you construct raw SQL statements using raw expressions (which is useful when you need to build complex queries, joining multiple tables for example), in which case you’ll need to sanitize your bindings.
Internally, it uses PDO prepared statements to protect against SQL injection attacks.
$name = "John"; $employee = Employee: :where('name', $name)->firstOrFail();
Cross-Site Request Forgery (CSRF) Protection
This type of attack exploits the trust that a site has in the user’s browser. An authenticated user can be triggered to make requests without even realizing it, and it may cause actions to be performed on the website on the user’s behalf. The victim can be attacked by simply accessing an email or forum message with a malicious CSRF link, while logged at the attacked website.
To understand this vulnerability, let’s imagine a vulnerable social media app example.com
. An attacker could email you a carefully crafted image that would trigger an action to be executed on your behalf – with your user’s credentials with an image linked with a url similar to https://www.example.com/password?newPassword=123456.
This would get triggered by opening that email message while logged into a vulnerable example.com
website.
To prevent this Laravel automatically generates a CSRF token for each active user session. This is used to verify that the authenticated user is the one doing the requests. Whenever you use an HTML form on your Laravel application, you must use a CSRF token field, and the CSRF middleware will be able to validate your request. Using Blade @csrf directive to achieve this protection.
Protecting Against Cross-Site Scripting (XSS)
Cross-site scripting attacks typically involve inserting malicious JavaScript on an unprotected area on your application. The script gets executed on the victim’s browser where it can execute malicious actions, such as:
- Redirecting to a malicious URL;
- Rendering a form to steal private data;
- Modifying links or any part of the DOM;
- Stealing cookie information.
To prevent XSS attacks, you must use validators to stop a malicious user from inserting XSS attacks on your forms and using htmlspecialchars to escape your output. Laravel Blade templating system automatically does this for you using the {{ }}
statements.
Hello, {{ $userProvidedData }}
Hashing Passwords
A hash function generates a unique value from a given input, and it’s impossible to manipulate the hash value to retrieve the original form. It’s also called one-way encryption and it’s used to store and verify sensitive data like a user’s password.
Protecting user passwords is essential to any application. Laravel has built-in hashing functions to protect sensitive data. Use Bcrypt or Argon2 algorithms to generate strong hashes. The usage is very simple since Laravel provides a Hash facade.
use Illuminate\Support\Faces\Hash; public function update(Request $request) { request -> user()->fill([ 'password' => Hash: :make($request->newPassword) ])->save(); } public function verify(Request $request) { If (Hash: :check('plain-text', $hashedPassword)) { return True; } }
Conclusion
- Never trust input, always filter input data (for example forms, filenames, HTTP parameters, etc.).
- Escape output in a context-aware manner.
- Hash your passwords using strong algorithms. Never write your own encryption algorithm.
- Use standard and well tested cryptographic implementations.
- Peer review is critical to security.
Modus Create provides application security consulting, designed to enumerate threats, vulnerabilities, and risks. The results of this engagement are presented from a tactical and strategic perspective. With these findings, you can then take the next step in improving your application’s security posture.
The security of your web application is determined by the code you write. To be a good developer and avoid a lot of headaches, you must always embrace security when designing your web application. Know your tools to build a more secure and reliable code!
This post was published under the Laravel Community of Experts. Communities of Experts are specialized groups at Modus that consolidate knowledge, document standards, reduce delivery times for clients, and open up growth opportunities for team members. Learn more about the Modus Community of Experts program in the article Building a Community of Experts.
References
- Why Laravel is the Recommended Framework for Secure, Mission-Critical Applications
- The Laravel Security Checklist
- Laravel 8 Docs – Security
- OWASP Top Ten Web Application Security Risks
- Programming PHP, 4th Edition, by Kevin Tatroe and Peter MacIntyre
- Pro PHP Security, 2nd Edition, by Chris Snyder, Thomas Myer, and Michael Southwell
Guido Percú
Related Posts
-
The 15 Best New Features in Laravel 8
Laravel 8 released on September 8th and brought many new features that improve the Laravel…
-
How to Build a Serverless Application Using Laravel and Bref
Since the release of AWS Lambda, serverless architecture has grown more popular within the software…