As a part of the continual efforts to accelerate the skill quotient of our technical workforce, Singsys has embarked upon a series of ‘Technical Seminars’. Accordingly it’s very first version was conducted successfully enumerating ‘Laravel Security Standards’ by our Laravel Expert, Mr. Prasoon Srivastava, and Mr. Prabal Gupta being the Seminar Chair for this session.
2. ▪ Reduce Laravel Vulnerabilities From CSRF (Cross Site Request
Forgery)
▪ Protection against XSS (Cross Site Scripting)
▪ Prevent SQL injection By Avoiding Raw Queries
▪ Keep app dependencies up to date
▪ Never Display Errors and Exceptions on Production
▪ Do not store Sensitive data in Configuration file
▪ Log All the things
▪ Make Sure Permissions on Filesystem are limited
▪ Force HTTPS if Your Application is Exchanging Sensitive Information
Key Points
3. Reduce Laravel Vulnerabilities From CSRF
(Cross Site Request Forgery)
✓ Cross-site request forgeries are a type of malicious
exploit whereby unauthorized commands are performed
on behalf of an authenticated user.
✓Laravel typically uses CSRF tokens to make sure that
external third parties couldn’t generate fake requests and
should not breach the Laravel security vulnerabilities.
✓Laravel makes it easy to protect your application from
cross-site request forgery (CSRF) attacks.
5. Reduce Laravel Vulnerabilities From
CSRF (Cross Site Request Forgery)
How is a CSRF attack carried out?
Assume you have an application that is used to send money to friends
and for users to send money, they need to be signed in. Assume that the
action to send money is also a simple form
The make-believe form requires the email of the recipient and the amount
to be sent. When the send button is clicked, a POST request is made to
the application server to send the amount to the recipient.
Everything seems okay and during testing, logged in users can send
money to other users, which is what is expected.
6. Reduce Laravel Vulnerabilities From
CSRF (Cross Site Request Forgery)
An attacker who wants to hoodwink the system will very likely study the
application for a while trying to locate vulnerabilities. They note the URL
where the request is sent to and they know it needs to be a POST request
with the email of the recipient and the amount you want to send.
The attacker then creates a program that can be embedded in an image or in
the webpage directly and executed when the image is clicked or executed
when a link is clicked.
When the script is executed, the server sees it as another regular request
made from the logged in user and then processes it. This means that
everyone authenticated to the target site visiting the attacker’s site will be
open to a CSRF attack and may indeed be sending money they didn’t intend
to send.
7. Reduce Laravel Vulnerabilities From
CSRF (Cross Site Request Forgery)
Carrying out your own CSRF attack
Now, let’s look at how to do a simple CSRF attack on an application.
8. Reduce Laravel Vulnerabilities From
CSRF (Cross Site Request Forgery)
Laravel CSRF in Forms
Defining your form fields in view, you should always include hidden CSRF
token form fields to ensure that the CSRF protection middleware can
validate the request by it. Hence by using @csrf in the form fields, Blade
directory generates the secured fields to validate the process.
<form method="POST" action="/employee">
@csrf
...
</form>
9. Reduce Laravel Vulnerabilities From
CSRF (Cross Site Request Forgery)
Laravel CSRF Token Ajax Calls
In Laravel, Middleware handles all the requests and doesn’t allow any POST request without the
right CSRF token verification. Therefore, in order to proceed further, you must input the CSRF
Token while sending the AJAX request.
data: {
"_token": "{!! csrf_token() !!}"
}
$.ajax({
type: "POST",
data: {"_token": "{{ csrf_token() }}","id": id},
url: some_url,
success: function(msg){
// response
}
});
10. Protection against XSS (Cross Site
Scripting)
✓Cross-site scripting (XSS) attacks happen when attackers are able to place
client-side JavaScript code in a page viewed by other users.
✓In our application, assuming that the name of our cat is not escaped, if we
enter the following snippet of code as the value for the name, every visitor
will be greeted with an alert message everywhere the name of our cat is
displayed:
Evil Cat <script>alert('Meow!')</script>
✓While this is a rather harmless script, it would be very easy to insert a
longer script or link to an external script that steals the session or cookie
values.
✓To avoid this kind of attack, you should never trust any user-submitted data
or escape any dangerous characters. You should favor the double-brace
syntax ({{ $value }}) in your Blade templates, and only use the {!! $value !!}
syntax, where you're certain the data is safe to display in its raw format.
12. XSS
I have created a very simple example 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.
// Display All Tasks
Route::get('/', function () {
$tasks = Task::orderBy('created_at', 'asc')->get();
return view('tasks', [
'tasks' => $tasks
]);
});
// Add A New Task
Route::post('/task', function (Request $request) {
$task = new Task;
$task->name = $request->name;
$task->save();
return redirect('/');
});
// Delete An Existing Task
Route::delete('/task/{id}', function ($id) {
Task::findOrFail($id)->delete();
return redirect('/');
});
13. XSS
And the relevant code in the view that shows the tasks:
@foreach ($tasks as $task)
...
<!-- Task Name -->
<td class="table-text">
<div>{{ $task->name }}</div>
</td>
...
14. XSS
Now instead of adding a task like I am supposed to, I am going to insert this:
<script>alert("boom")</script>
17. Prevent SQL injection By Avoiding Raw
Queries
✓An SQL injection vulnerability exists when an application inserts
arbitrary and unfiltered user input in an SQL query. This user input
can come from cookies, server variables, or, most frequently, through
GET or POST input values.
✓These attacks are conducted to access or modify data that is not
normally available and sometimes to disturb the normal functioning of
the application.
✓By default, Laravel will protect you against this type of attack since
both the query builder and Eloquent use PHP Data Objects (PDO)
class behind the scenes. PDO uses prepared statements, which
allows you to safely pass any parameters without having to escape
and sanitize them.
18. Prevent SQL injection By Avoiding Raw
Queries
Consider for instance a form field used to supply an e-
mail address which might be used for searching a user
table. But instead of supplying an e-mail address the user
searches for 'jason@example.com' or 1=1. Left
unsecured, the resulting query might look like this:
SELECT * FROM users WHERE email =
'abc@example.com' or 1=1
it is a simple logic expression that always evaluates to
true, meaning when coupled with or, all records will be
returned from the users table!
19. Prevent SQL injection By Avoiding Raw
Queries
$id = $request->get('id');
// Dangerous:
Here's what we want to avoid:
$result = DB::select( DB::raw("SELECT * FROM users WHERE id = $id") );
// Safe:
$result = DB::table('users')->where('id', $id)->get();
// Even better:
$user = AppUser::find($id);
// Even *better*:
public function myMethod(AppUser $user, Request $request);
20. Keep app dependencies up to date
✓Most PHP code relies on external, third-
party dependencies. However, these need
to be kept up to date, wherever possible, to
ensure that any bug and security fixes are
available to your code.
✓Ensure you’re using Composer as your
dependency manager and keep up to date
with all of your dependencies.
21. Never Display Errors and Exceptions on
Production
✓While errors, warnings, and exceptions are helpful
during development, if displayed in production or
any other public-facing environment, they may
expose sensitive information or intellectual property.
✓Ensure that this information is logged internally, and
not exposed publicly.
22. Never Display Errors and Exceptions on
Production
✓The debug option in your config/app.php configuration file determines how
much information about an error is actually displayed to the user. By
default, this option is set to respect the value of the APP_DEBUG
environment variable, which is stored in your .env file.
✓For local development, you should set the APP_DEBUG environment
variable to true.
APP_DEBUG=true
✓In your production environment, this value should always be false.
APP_DEBUG=false
✓ If the value is set to true in production, you risk exposing sensitive
configuration values to your application's end users.
23. Do not store Sensitive data in
Configuration file
✓Just like you shouldn’t store sensitive data in cache
entries, you also should not store sensitive data in
configuration files.
✓This includes ssh keys, access credentials, and API
tokens. Store them in environment variables
instead.
✓Always store sensitive data in .env file
24. Do not store Sensitive data in
Configuration file
TWILIO_SID=ACc3983b17046121c35104c2bca3dae2ec
TWILIO_TOKEN=cb1bc684feff8ea0c37147dfd0f16c09
TWILIO_FROM=+18577633121
PAYPAL_ENV=sandbox
PAYPAL_USERNAME=xyz.singsys.com
PAYPAL_PASSWORD=VZEQNNPRML6F54CR
PAYPAL_SIGN=AFcWxV21C7fd0v3bYYYRCpSSRl31A.t5R0DSvr2VkN.oaim
U-BG2UthF
PAYPAL_APPID=APP-80W284485P519543T
PAYPAL_SANDBOX_EMAIL=abc-buyer@gmail.com
25. Log All the things
✓Regardless of whether you’re logging failed login attempts, password
resets, or debugging information, make sure that you’re logging, and
with an easy to use, and mature package, such as Monolog.
✓To help you learn more about what's happening within your
application, Laravel provides robust logging services that allow you to
log messages to files, the system error log, and even to Slack to notify
your entire team.
✓Under the hood, Laravel utilizes the Monolog library, which provides
support for a variety of powerful log handlers. Laravel makes it a cinch
to configure these handlers, allowing you to mix and match them to
customize your application's log handling.
26. Log All the things
✓You may write information to the logs using the Log facade.
✓logger provides the eight logging levels defined in the RFC 5424
specification: emergency, alert, critical, error, warning, notice, info and
debug:
✓Log::emergency($message);
✓Log::alert($message);
✓Log::critical($message);
✓Log::error($message);
✓Log::warning($message);
✓Log::notice($message);
✓Log::info($message);
✓Log::debug($message);
public function showProfile($id)
{
Log::info('Showing user profile for user: '.$id);
return view('user.profile', ['user' => User::findOrFail($id)]);
}
27. Make Sure Permissions on Filesystem
are limited
✓PHP scripts should only be able to write in places
you need to upload files of specifically write files.
✓This places should not be anywhere a PHP script
can be executed by the server. Else, it open the way
for an attacker to write a PHP file somewhere and to
run arbitrary PHP code.
28. Force HTTPS if Your Application is
Exchanging Sensitive Information
✓When you deploy your website on HTTP, all the data exchanged including
passwords and others are sent in plain content. Thus could be easily stolen by
anyone in between the transmission. So to keep this information safe, always
deploy your web applications on HTTPS to safeguard its sensitive information.
✓You could simply setup SSL certificate on your website by getting little
assistance from any Laravel developer who will shift your application from
HTTP to HTTPS easily. While to hide certain routes, you could use the below
defined filter which will redirect users to a secured route.
Route::filter('https', function() {
if ( ! Request::secure())
return Redirect::secure(URI::current());
});