Security in Laravel 5.4

Izvor: SIS Wiki
Skoči na: orijentacija, traži

Izradio: Zoran Hrnčić

Sadržaj

Uvod

Došlo je vrijeme kada se sve zbiva na internetu i sve je postalo nezamislivo bez interneta. Gotovi svi poslovni sustavi su ovisni o računalnoj podršci u obavljanju svakodnevnog posla. U mnogim poduzećima se posao obavlja na više lokacija i potreban im je softver pomoću koji će sve to povezati i uskladiti. Kao najbolje rješenje u sve više situacija je Web aplikacija. Trenutno internet bazirane aplikacije i usluge postaju dominantne među korisnicima. Milijuni korisnika diljem svijeta koriste web aplikacije za kupnju preko interneta, kontaktiranje s prijateljima, plaćanje računa, čitanje novosti itd. Najveći razlog u tome je višestruko povećanje brzine interneta, te značajan skok u performansama računala i veliki napredak u mogućnostima web preglednika. Veliku ulogu u napretku razvojnih tehnologija „igra“ sigurnost podataka, te brzina razvoja same web stranice, odnosno aplikacije.

Ovdje se javlja potreba za dobrim programskim arhitekturama, te razvojnim okvirima poput Laravela (bit će kasnije detaljno objašnjen). Arhitektura Model-View-Controller (MVC) nam pomaže logički odjeliti prava pristupa podatcima. Što je najkorisnije razvojni okviri znatno skraćuju vrijeme potrebno za razvoj određene aplikacije. U ovom radu ćemo detaljno objasniti kako radi framework Laravel 5.4, te kako je kod njega rješeno pitanje sigurnosti podataka. Prikazat ću koji su to najčešći napadi na web aplikacije, te kako nam ovaj predivan framework pomaže u obrani od istih. Potom ću na malenom projektu prikazati kako je jednostavno obaviti sigurnu registraciju i prijavu krisnika, te kasniju autentifikaciju i autorizaciju korinika.

Framework Laravel 5.4.27

Zašto sam odabrao baš ovaj PHP framework? Prvenstveno sam se na to odlučio radi sigurnosti krađe podataka, jednostavnosti izrade i jednostavnosti kasnijeg snalaženja u kodu i nadogradnji.

Laravel je besplatan, objektno orijentirani open-source PHP framework. Napravio ga je Taylor Otwell za izradu web aplikacija sljedeći MVC (model-view-controler) arhitekturu. Uz Symphony ovo je najpopularniji framework za izradu web aplikacija. Omogućava izradu modularnih aplikacija, pojednostavljuje čitav proces izrade i održavanja aplikacija te ima ugrađeni veliki broj metoda i paketa za upravljanje sa bazama i vanjskim resursima.

U nastavku rada ću detaljno opisati framework i njegov način rada te sve to prikazati primjerima na izradi aplikacije.

Laravel je MVC framework. Što to znači? To je arhitektura koja je osmišljena još 80-tih godina najviše zbog razvoja GUI softvera. Organizacija podataka odvija se na relaciji korisnik-sučelje-baza podataka.

MVC arhitektura se sastoji od tri djela:

Routing - unutar svakog projekta postoji app/routes.php datoteka u kojoj definiramo naredbe za upravljanje preusmjeravanja te poziva "Controller" klase prilikom korisnikovog posjeta nekoj stranici unutar naše aplikacije

Kontroler - vrši glavnu ulogu, prima podatke od korisnika i korisnikove naredbe. Vrši obradu podataka i svu potrebnu obradu u programu i kreira pogled

Model - služi za spremanje podataka u bazu podataka i upravljanje istima..

Pogled - je samo prezentacija podataka i prikaz formi korisniku.

Migrations - omogućuju nam jednostavan razvoj i modificiranje naše baze podataka, odnosno tablica i veza među njima.

Relacija među njima je sljedeća; Model prima informacije samo iz Kontrolera, dok drugi korisnik ili računalo može komunicirati direktno sa kontrolerom i pogledom. Sljedeća slika najbolje prikazuje ovu arhitekturu.

 Alt text


Kreiranje projekta

Za izradu Web aplikacije koristeći Laravel framework nam je pored XAMPP servera potreban i sam razvojni okvir. Ja sam izabrao Laravel 5.4 MVC razvojni okvir. Za korištenje Laravel razvojnog okvira, prvo moramo imati instaliran Composer. Na Windows 10 OS-u dovoljno je preuzeti Composer instalacijski paket te ga instalirati.

Laravel možemo instalirati preko komandne linije koristimo create-project naredbu:

composer create-project –prefer-dist laravel/laravel #naziv_aplikacije

#naziv_aplikacije Composer koristi kao referencu preko koje stvara direktorij pod istim imenom unutar putanje komandne linije. Za pokretanje servera je dovoljno se pozicionirati se unutar mape projekta i pozvati naredbu:

php artisan serve 

Ova naredba pokreće lokalni server na adresi http://localhost:8000. Iz servera se izlazi kombinacijom CTRL + c tipki na tastaturi. Laravel također koristi Homestead/Vagrant virtualno okruženje koje se preporuča za razvoj kompleksnijih aplikacija. Za izradu projekta ja koristim razvojno okruženje NetBeans IDE 8.2.

Prvi koraci u izradi aplikacije

Prije početka razvoja aplikacije potrebno je napraviti bazu podataka u MySQL sustavu za upravljanje bazom podataka. Moja, već izrađena, baza podataka se zove „ISS“, no prije nego ju popunimo tablicama, trebamo upisati u Laravel ime baze i podatke za pristup bazi. U Laravelu 5.4 to se radi upisivanjem podataka u .env datoteku koja se nalazi u početnom direktoriju. Konfiguracija ove datoteke izgleda ovako:

APP_NAME=Laravel
APP_ENV=local   
APP_KEY=base64:0e7dXELU0PEooARW3CICZigEez7GHlvlKaRyGIoNZKY=
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=iss
DB_USERNAME=iss
DB_PASSWORD=iss_password

BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=sis.projekt.laravel@gmail.com
MAIL_PASSWORD="************"
MAIL_ENCRYPTION=tls


PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=

Tablice možemo izraditi i preko phpMyAdmin sučelja, no u Laravelu se preporuča korištenje artisan naredbi u konzoli , pa ću tako i ja koristiti. Artisan sučelje komandne linije dolazi u paketu sa razvojnim okvirom, te jedna od vrlo korisnih mogućnosti artisana je automatsko generiranje tzv. Migracija. U nastavku više o tome. Sada kada smo uspješno povezani sa bazom podataka, možemo krenuti sa izradom aplikacije.

Model (eng. Model)

Modeli su kopije relacija iz baze podataka te se sva logika za rad s bazom podataka se izvršava korištenjem modela. Unutar njih se nalaze i pravila za validaciju podataka koji se spremaju u bazu podataka. Glavni posao modela je dohvaćanje podataka iz baze podataka i spremanje u odgovarajuće objekte i potom izvršavanje svih potrebnih operacija nad podatcima u bazi. Svi se modeli nalaze u direktoriju „./app“ i nasljeđuju Laravel klasu Model. Drugačiji je jedino model User koji se koristi za pohranjivanje korisnika aplikacije i njihovu autentikaciju. Ovaj model nasljeđuje klasu Authenticatable. Metode modela mogu biti različitog tipa ovisno o tome koja im je svrha te prema tome razlikujemo:


Kontroler (eng. Controller)

Kontroler se ponaša kao poveznica između modela i pogleda, pripada u sloj poslovne logike. Obrađuje sve zahtjeve korisnika aplikacije. Kontroler zaprima korisnikove zahtjeve, izvrši potrebne akcije te vraća odgovarajući odgovor pogledu. U njemu se izvršava sva logika aplikacije kao na primjer:

Svi kontroleri su smješteni u direktoriju "/app/Http/Controllers/", a sva logika obrade HTTP zahtjeva nalazi se u "/app/Http/" .

Unutar kontrolera odvija se proces validacije podataka. Validacija se može izvršiti na dva načina:

Ispod ovog teksta možemo vidjeti jednu metodu kontrolera koja je zadužena za spremanje novog zapisa za izvršeno mjerenje krvnog tlaka. Prilikom poziva funkcije njoj se prosljeđuje objekt korisnik (osoba smještena u domu) kojem je izvršeno mjerenje. Najprije su u jedno polje upisani Hrvatski prijevodi poruka za greške u validaciji podataka. Pozivom funkcije „validate(request)“ se vrši validacija primljenih podataka iz popunjene forme.

Ako je validacija uspješna poziva se statička metoda modela KrvniTlak, metoda novoMjerenje. Metodi se prosljeđuju podatci za pohranu. Na kraju se funkcijom back() vraća korisnika na stranicu iz koje je poslan zahtjev.

Ako je validacija neuspješna korisnika se vraća na stranicu iz koje je poslan zahtjev i šalje se popis grašaka.

    public function spremiIzmjereniTlak(\App\Korisnici $korisnik) {
        
          $messages = [
            'date' => 'Datum nije pravilnog oblika',
            'numeric' => 'Polje mora sadržavati samo brojeve.',
            'alpha' => 'Polje smije sadržavati samo slova.',
            'required' => 'Nešto mora biti odabrano.',
            'min' => 'Polje mora sadržavati minimalno :min znakaova.',
        ];



        $this->validate(request(), [
            'sistoličkiTlak' => 'required|numeric',
              'dijastolickiTlak' => 'required|numeric'
                ], $messages);


     
        \App\KrvniTlak::novoMjerenje(
                request('sistoličkiTlak'),
                request('dijastolickiTlak'),
                request('napomena'), 
                $korisnik, 
                auth()->id());
        
       

         
        return back();
    }

Middleware

Uloga middlewarea u model-view-controller arhitekturi bi bio jednostavnim riječima „kontroler kontrolera“. On kontrolira dozvole pristupa određenom sadržaju, štiti od neovlaštenog pristupa sadržaju web aplikacije. Koristi se za autentikaciju i autorizaciju pristupa sadržaju. Ispod teksta je prikazano korištenje middleware klase za provjeru autentifikacije korisnika. Provjera se izvršava pri svakom pozivu bilo koje funkcije iz te klase, točnije u ovom slučaju čim se zatraži prikaz stranice za prijavu korisnika. Ukoliko je korisnik već prijavljen njega se automatski preusmjerava na početnu stranicu i ne dozvoljava mu prikaz stranice za prijavu.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\LogSustava;
use Illuminate\Support\Facades\Route;
class KrvniTlakController extends Controller
{
    //
     public function __construct() {
         
        //provjera da li je korisnik prijavljen
         //prilikom poziva bilo koje metode iz ove klase. najprije se provjerava dali je korisnik prijavljen
        $this->middleware('auth');
    }

Svaka metoda kontrolera se poziva na jedan zatraženi URL. Oni su povezani preko skripte /routes/web.php. Unutar tog dokumenta mogu se pronaći svi dostupni URL-ovi te imena kontrolera i metoda koji se pozivaju traženjem određenog URL-a. Tu se definiraju i podatci koji se prenose unutar URL linka, te naziv za ovu rutu.

<?php

Route::get('/','HomeController@index')->name('home'); //prikaz svih postova

Route::get('/posts/create','PostsController@create')->name('postCreate'); //stranica za izradu novog posta

Route::post('/posts','PostsController@store')->name('postShow'); //stranica za pohranu novog posta

Route::get('/posts/{post}','PostsController@show'); //prikaz posta sa komentarima

Route::post('/posts/{post}/comments','CommentsController@store'); //dodavanje komentara na post


Route::get('/register', 'RegistrationController@create'); //prikaz forme za registraciju

Route::post('/register', 'RegistrationController@store'); //izvršavanje registracije

Artisan konzola

Artisan je komandno sučelje uključeno u samo Laravel projekt. Omogućuje nam mnoštvo korisnih naredbi koje nam uveliko pomažu tijekom razvoja aplikacije. Korištenje sučelja je vrlo jednostavno. Potrebno se je pozicionirati u root folder projekta i pozvati naredbu oblika:

php artisan „ime naredbe“ 

Na slici ispod je prikazan poziv naredbe koja će nam ispisati listu svih mogućih naredbi:

 Alt text

Autentifkacija

Laravel nam omogućuje izradu kompletnog sustava za autentifikaciju pozivom samo dvije jednostavne artisan naredbe:

	php artisan make:auth 
	php artisan migrate

Pozivom iznad nevedenih naredbi kreirat će se sve rute, pogledi, modeli i svi potrebni kontroleri koji omogućuju sljedeće:

Izgled sućelja za prijavu sada izgleda ovako:

 Alt text

Za izradu mnogih klasićnih web aplikacija više neće biti potrebno dodatno dograđivati kontrolere i samu logiku autentifikacije. Naravno izgled se može vrlo jednostavno promjeniti i prolagoditi vlastitim željama i potrebama.

Sustav je sada spreman za registraciju novog korisnika i prijavu istog u sustav, te je osiguran od Broken Authentication and Session Management napada.


Guards

Autentifikacija kod Laravela je izrađena pomoću dvije važne stavke. To su „Gurads“ i „Providers“.

Guards nam definira kako će biti korisnici autentificirani kod svakog zahtjeva. Kod laravela je već ugrađen Guard za sesije koje kontrolira jeli korisnik prijavljen koristeći pohranu sesije i kolačića u pregledniku. Naravno, vrlo jedostavno se može dodati novi guard.

Providers

Provideri definiraju kako će postojeći korisnici biti dohvaćeni iz baze podataka ili neke druge trajne pohrane gdje se čuvaju njihovi podatci. Laravel ima ugrađenu podršku za dohvaćanje korisnika iz baze podataka koristeći Eloquent i database query builder. Isto kao i u prethodnom slučaju, jednostavno se može dodati vlastiti provider.

Dohvaćanje prijavljenog korisnika

Nakon uspješne prijave korisnika u sustav, njegovi podatci uvijek mogu biti jednostavno dohvaćeni pozivom jedne od sljedeće dvije naredbe:

    //dohvaćanje ID-a trenutno prijavljenog korisnika
    auth()->id();
    
    //dohvaćanje trenutno prijavljenog korisnika
    auth()->user();

Isto tako na vrlo jednostavan način se uvijek može provjeriti je li trenutni korisnik prijavljen u sustav:


  if (Auth:check()) {
//Trenutni korisnik je prijavljen u sustav

}

Zaštita ruta

U skripti web.php su nam pohranjene sve dostupne rute za našu aplikaciju, odnosno svi mogući „URL linkovi“. Već ovdje možemo uraditi zaštitu koristeći middleware i omogućiti da samo prijavljeni korisnici mogu pristupiti određenim rutama.


Route::get('/iss', 'HomeController@iss_home')->name('iss_home')->middleware('auth');

Login Throttling

Login kontroler ima automatski uključeni throttling koji po defaultnim postavkama onemogućuje prijavu korisniku ukoliko se više puta uzastopno pokuša prijaviti sa pogrešnim podatcima. Throttling je ograničen na način da se korisnik smatra jedinstvenim ako pokuša prijavu sa jednakim korisničkim imenom/email-adresom sa jednake IP adrese.

Pohrana lozinki / hashing

Laravel nam nudi sigurnu pohranu lozinki koristeći Bcrypt hashing. Ako koristimo automatski generirane kontrolere za prijavu i registraciju, oni već imaju građene sve potrebne metode za provjeru lozinke.

Bcrypt

Bcrypt je trenutno najbolji način za izradu hash sažetka lozinke. Glavni razlog je taj što je njegov „work factor“ podesiv, što znaći da se vrijeme za generiranej sažetka povećava usporedno sa povećanjem snage hardwera.

Ručno spremanje lozinki / hashing

Ukoliko ručno radimo sustav za autentifikaciju, ili nam je iz nekog razloga potrebno napraviti sažetak lozinke možemo koristiti metode iz klase Hash. Kreiranje sažetka lozinke možemo izraditi na način prikazan ispod:

        echo '<br><h1>HASH:</h1>';

        echo (Hash::make("ZOKY"));

Ispis prethodnog koda izgleda ovako:

 Alt text


Ručna usporedba lozinke sa spremljenim sažetkom

Check metoda iz klase Hash omogućuje nam da provjerimo dal nam čist tekst (lozinka) odgovara pohranjenom sažetku. Provjera sažetka se obavlja na sljedeći način:

        $hash = Hash::make("ZOKY");

        if (Hash::check("ZOKY", $hash)) {
            echo 'The passwords match..';
        } else {
            echo 'Passwords does not match..';
        }

Provjera da li je potrebno ponovno napraviti sažetak lozinke

Metoda needsRehash iz klase Hash nam omogućuje da utvrdimo jeli se možda od kreiranja sažetka lozinke,pa do danas promjenio "work factor" od hasher-a. U slučaju da se je faktor promjenio, potrebno se pohraniti novi sažetak lozinke.

        echo '<br><h1>REHASH:</h1>';
        $hashed = Hash::make("ZOKY");

        if (Hash::needsRehash($hashed)) {
            $hashed = Hash::make('plain-text');

            echo '<br>' . $hashed;
        }

Autorizacija

Uz pružanje autentifikacije, Laravel također nudi jednostavan način za autorizaciju korisničkih akcija nad nekim objektima, odnosno resursima. Pristup autorizaciji je poprilično jednostavan. U ovom slučaju također imamo dva načina autorizacije aktivnosti:

Korištenjem ovakvih načina autorizacije smo osigurani od Missing Function Level Access Control i Insecure Direct Object References napada.

Vrata (eng. Gates) i politike (eng. Policies) su, moglo bi se reći, ekvivalentni pojmovima rute i kontroleri. Vrata omogućuju jednostavan pristup autorizaciji, a politike, poput kontrolera, vrše svu logiku pristupa određenom modelu ili resursu.

Vrata (eng. Gates)

Vrata nam blokiraju, odnosno dopuštaju pristup nekom objektu, ovisno o politici koja „leži“ iza njih. Vrata uvijek primaju prvi argument instancu objekta User, a ostale mogu biti bilo koji objekti modela. Ispod je prikazana definicija vrata:


/**
 * Register any authentication / authorization services.
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();

    Gate::define('update-post', function ($user, $post) {
        return $user->id == $post->user_id;
    });
}

Politike (eng. Policies)

Politike su klase koje organiziraju logiku autorizacije akcija nad određenim modelima. Na primjer u ovoj klasi možemo definirati pod kojim uvjetima trenutni korisnik može uređivati ili brisati neki model. Primjer klase policies klase:

<?php

namespace App\Policies;

use App\User;
use App\Post;

class PostPolicy
{
    /**
     * Determine if the given post can be updated by the user.
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return bool
     */
    public function update(User $user, Post $post)
    {
        return $user->id === $post->user_id;
    }
}

Autorizacija akcija

Kako bi za autorizaciju koristili vrata moramo koristiti metode allows i denies. Naravno, "u vrata" ne trebamo proslijediti trenutno prijavljenog korisnika, jer njega se dohvaća automatski iz sesije. Kao drugo argument može se proslijediti bilo koji objekt modela. Ispod je prikazan je primjer korištenja vrata:

if (Gate::allows('update-post', $post)) {
    // The current user can update the post...
}

if (Gate::denies('update-post', $post)) {
    // The current user can't update the post...
}

Enkripcija

Laravel enkriptor koristi OpenSSL kako bi omogućio AES-256 i AES-128 enkripciju.

Preporučeno je koristiti već ugrađene algoritme za šifriranje, i nikako se ne preporuča izrada vlastitih algoritama za šifriranje. Sve Laravelove šifrirane poruke su potpisane pomoću koda za autentifikaciju poruka MAC (eng. Message authentication code) koji nam osigurava na šifrirani sadržaj ne može biti izmijenjen nakon šifriranja.

Konfiguracija

Prije korištenja enkriptora potrebno je podesiti key option u konfiguracijskoj datoteci (config/app.php). Za generiranje ključevai prethodno podešavanje potrebno je pozvati sljedeću artisan naredbu:

php artisan key:generate

Šifriranje i dešifriranje koristeću encryptor

Poruke se mogu šifrirati koristeći helper encrypt koji šifrira koristeći OpenSSL i AES-256-CBC, te sve vrijednosti potpisuje MAC kodom za otkrivanje promjena. Korištenje kriptiranja i dekriptiranja poruka je prikazano je ispod:

        echo '<br><h1>KRIPTIRANO:</h1>';
       
        echo (encrypt("ZOKY"));
     
        $a = encrypt("ZOKY");


        echo '<br><h1>DEKRIPTIRANO:</h1>';
       
        echo (decrypt($a));


Šifriranje i dešifriranje bez serijalizacije

Šifriranje koristeći encryptor provodi sve vrijednosti serijalizaciju što nam omogućuje šifriranje objekta i polja. Dakle, klijenti koji ne koriste PHP programski jezik neće moći dešifrirati ovakve poruke. Zbog toga nam Laravel omogućuje i šifriranje stringova bez serijalizacije koristeći sljedeće metode klase Crypt; encryptString, decryptString

        echo (Crypt::encryptString("ZOKY"));

        echo (Crypt::decryptString(Crypt::encryptString("ZOKY")));

SQL injection

Za sprijećavanje ove vrte napada Laravel koristi The Eloquent ORM koji omogućuje sigurno i jednostavno upravljanje sa bilo kojom vrstom baze podataka. Svaka tablica iz baze ima svoju pripadajuću klasu (Model) pomoću koje se izvršavaju sve interakcije sa dotičnom tablicom.

Ukoliko korisitmo Eloquent model za dohavaćanje podataka iz baze, onda smo osigurni od sql injection napada.

Svi upiti se kriraju koristeći Laravel query builder koji u pozadini koristi PDO povezivanje parametara i na taj način štiti od napada ovakve vrste.

Ispod možemo vidjeti izgled klase modela koja predstavlja tablicu, iz baze podataka, „Houses“; naziva modela ove tablice je House (jednina od naziva tablice)

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class House extends Model
{
    //
    
      public function photos()
    {
        return $this->belongsToMany('App\Photo','photo_phototype_houses','house_id','photo_id');
    }
    
        public function photoType()
    {
        return $this->belongsToMany('App\PhotoType','photo_phototype_houses','house_id','photo_type_id');
    }
    
    public function address()
{
        
    return $this->belongsTo('App\Address', 'address_id');
    
}

    public static function addNewHouse($streetName,$streetNumber,$place,Post $post,$longitude,$latitude, $name_owner,$surname_owner, $number_of_tenants, $number_of_floors, $list_of_floors, $number_of_children, $year_children, $number_of_adults, $years_adults, $number_of_powerless_and_elders, $years_powerless_elders, $disability_person, $power_supply, $gas_connection, $type_of_heating, $number_of_gas_bottle, $type_of_roof, $hydrant_distance, $high_risk_object, $HRO_type_of_roof, $HRO_power_supply, $HRO_content,$HRO_animals, $telNumber, $mobNumber) {

       // $date = Carbon::createFromFormat('Y-m-d H:i', $date . ' ' . $time);
       
       $address = Address::addAddress($streetName, $streetNumber, $place, $post, $longitude, $latitude);
      
       $house = new House();
   $house ->address_id = $address->id;
        $house -> name_owner = $name_owner;
        $house -> surname_owner = $surname_owner;
        $house -> number_of_tenants = $number_of_tenants;
        $house -> number_of_floors = $number_of_floors;
        $house -> list_of_floors = $list_of_floors;
        $house -> number_of_children = $number_of_children;
        $house -> year_children = $year_children;
        $house -> number_of_adults = $number_of_adults;
        $house -> years_adults = $years_adults;
        $house -> number_of_powerless_and_elders = $number_of_powerless_and_elders;
        $house -> years_powerless_elders = $years_powerless_elders;
        $house -> disability_person = $disability_person;
        $house -> power_supply = $power_supply;
        $house -> gas_connection = $gas_connection;
        $house -> type_of_heating = $type_of_heating;
        $house -> number_of_gas_bottle = $number_of_gas_bottle;
        $house -> type_of_roof = $type_of_roof;
        $house -> hydrant_distance = $hydrant_distance;
        $house -> high_risk_object = $high_risk_object;
        $house -> HRO_type_of_roof = $HRO_type_of_roof;
        $house -> HRO_power_supply= $HRO_power_supply;
        $house -> HRO_content = $HRO_content;
        $house -> HRO_animals = $HRO_animals;
        $house -> telNumber = $telNumber;
        $house -> mobNumber = $mobNumber;
        $house -> save();
        
        
        return $house;
     
    }

Iapod je prikazan pravilan, siguran upit kriran koristeći Eloquent ORM model i query builder, i ovakav upit je siguran on SQL injection napada.

$user = DB::table('users')->where('name', "zoky001")->first();

I još jedan primjer kako se u laravelu mogu pisati klasični SQL upiti koji su ranjivi na ovakvu vrstu napada.

Nikako nije preporučeno pisati upite na ovakav način!!!

        $someVariable = " ' OR '1'='1 ";

        $user = DB::select(DB::raw("SELECT * FROM users WHERE name = '$someVariable'"));

        
        if ($user != null) {

            echo "<br> IME KORISNIKA: " . $user[0]->name . "<br>";
            echo "E-mail KORISNIKA: " . $user[0]->email;
        } else {

            echo "NE postoji korisnik: ";
        }

Rezultat gore navedenog koda je sljedeći:

 Alt text

Drugi oblik zaštite od napade ovakve vrste je da posebno definiramo za svaki model/tablicu koje podatke je moguće promijaneiti. U sljedećem primjeru je moguće izmjeniti samo:

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
}

Cross site scripting

U laravelu se ovakve vrste napada sprječavaju, gotovo automatski. Prilikom svakog ispisa u pogledu stavljamo sve varijable u dvostruke vitičaste zagrade. Na taj način se automatski sav sadržaj filtrira i ispisuje kao čisti tekst. Ispod je primjer klasičnog/sigurnog ispisa u laravelu:

                        <div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
                            <label for="name" class="col-md-4 control-label">Name</label>

                            <div class="col-md-6">
                                <input id="name" type="text" class="form-control" name="name" value="{{ old('name') }}" required autofocus>

                                @if ($errors->has('name'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('name') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>

I ovdje primjer ispisa bez filtriranja specijalnih znakova, ako baš želimo ili ima neka potreba, može se koristiti ovaj način ispisa bez filtriranja.

                       <!-- ovakav ispis ne vrši filtriranje znakova i omogućuje Cross site scripting napad-->
                       

                       {!! old('name') !!}
                        
                        
                        
                        <div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
                            <label for="name" class="col-md-4 control-label">Name</label>

                            <div class="col-md-6">
                                <input id="name" type="text" class="form-control" name="name" value="{{ old('name') }}" required autofocus>

                                @if ($errors->has('name'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('name') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>

Ispis gore napisanog koda sada izgleda ovako:

 Alt text

Cross site request forgery

Obrana protiv ove vrste napada je također automatizirana u Laravel-u. Za svaku aktivnu sesiju se krira CRSF token. Ovaj token se koristi za verifikaciju trenutnog korisnika. Unutar svake forme je potrebno dodati polje koje sadrži ovaj token, kako bi se onda prilikom slanja forme na server, koristeči ovaj token, u middleware-u mogla obaviti validacija korisnika.


                        <form class="form-horizontal" method="POST" action="{{ route('register') }}">
                       

                        <!-- ovdje se kreira skriveno polje koje sadrži token-->
                
                        {{ csrf_field() }}
                     
                        <div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
                            <label for="name" class="col-md-4 control-label">Name</label>

                            <div class="col-md-6">
                                <input id="name" type="text" class="form-control" name="name" value="{{ old('name') }}" required autofocus>

                                @if ($errors->has('name'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('name') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>

                     ...


 Alt text

Security Misconfiguration

Nakon uspješne izrade aplikacije i puštanje trenutne verzije u produkciju na produkcijski server potrebno je onemogućiti korisnicima ispis neočekivano nastalih grešaka. Te opisa istih pogrešaka. Ove pogreške bi napadač mogao iskoristi u svoju koristi i naštetiti sustavu. Za sprječavanje takve vrste napada, potrebno je prilikom deploymenta izmjeni samo dvije stvari u .env datoteci projekta.


/*ukoliko razvijamo aplikaciju na lokalnom serveru i želimo ispis grešaka*/
APP_ENV=local   
APP_DEBUG=true

/*kada je aplikaciju u produkciji i ne želimo ispis grešaka*/
APP_ENV=release
APP_DEBUG=false

Aplikacija

Na sljedećem linku je moguće preuzeti aplikaciju izrađenu u Laravelu 5.4 sa prikazom implementacije sigurne obrane od različitih vrsta napad na web aplikacije. Prikazano je i na koji način je moguće učiniti ranjivu na prijetnje, te je potrebno ovakve načine programiranja izbjegavati.
Link na projekt: https://github.com/zoky001/ISS


Zaključak

Upoznavajući se sa svim prijetnjama koje postoje prema web aplikacijama vrlo je bitno pravilno se osigurati odnosno preventivno obraniti od istih. Milijuni korisnika svakodnevno koristi web aplikacije za posao, kupovinu i zabavu. Kako bi zaštitili njihovu privatnost i osigurali im sigurnost, korištenjem naše aplikacije, preporuča se korištenje provjerenih i sigurnim framework-a za razvoj aplikacije. Laravel je predivan framework i stvarno omogućuje na elegantan način izraditi sve što je potrebno jednoj suvremenoj web aplikaciji. Ima automatski ugrađene mehanizme za obranu od mnogih vrsta napada, tako da programer uopće ne mora voditi brigu o tome. Moja preporuka je koristiti ga, jer tko jednom savlada ovaj predivan framework, teško se od njega odvaja.

Literatura

1. Laravel Framework - documentation - https://laravel.com/docs/5.4 23.01.2017
2. Laracast - https://laracasts.com/ 23.01.2017
3. Stack Overflow - http://stackoverflow.com/ 23.01.2017
4. PHP documentation - http://php.net/docs.php 23.01.2017
5. Architecture of Laravel - http://www.sinisalekovic.com/blog/architecture-of-laravel-5-2-applications

Osobni alati
Imenski prostori
Inačice
Radnje
Orijentacija
Traka s alatima