Шта је СКЛ ињекција и како спречити у ПХП апликацијама?

Дакле, мислите да је ваша СКЛ база података ефикасна и сигурна од тренутног уништења? Па, СКЛ Ињецтион се не слаже!

Да, говоримо о тренутном уништењу, јер не желим да отварам овај чланак уобичајеном јадном терминологијом „пооштравања безбедности“ и „спречавања злонамерног приступа“. СКЛ Ињекција је тако стари трик у књизи да сви, сваки програмер, знају за то веома добро и добро знају како да то спрече. Осим оног једног чудног пута када им измакну, а резултати могу бити ништа друго него катастрофални.

Ако већ знате шта је СКЛ ињекција, слободно пређите на другу половину чланка. Али за оне који тек долазе у област веб развоја и сањају о преузимању виших улога, неки увод је на реду.

Шта је СКЛ ињекција?

Кључ за разумевање СКЛ ињекције је у њеном имену: СКЛ + Ињецтион. Реч „ињекција“ овде нема никакве медицинске конотације, већ је реч о употреби глагола „убризгати“. Заједно, ове две речи преносе идеју постављања СКЛ-а у веб апликацију.

Стављање СКЛ-а у веб апликацију. . . хммм . . . Зар то ионако не радимо? Да, али не желимо да нападач управља нашом базом података. Хајде да то схватимо уз помоћ примера.

Рецимо да правите типичну ПХП веб локацију за локалну продавницу е-трговине, па сте одлучили да додате образац за контакт попут овог:

<form action="record_message.php" method="POST">
  <label>Your name</label>
  <input type="text" name="name">
  
  <label>Your message</label>
  <textarea name="message" rows="5"></textarea>
  
  <input type="submit" value="Send">
</form>

Претпоставимо да датотека сенд_мессаге.пхп чува све у бази података тако да власници продавница могу касније да читају поруке корисника. Можда има неки код попут овога:

<?php

$name = $_POST['name'];
$message = $_POST['message'];

// check if this user already has a message
mysqli_query($conn, "SELECT * from messages where name = $name");

// Other code here

Дакле, прво покушавате да видите да ли овај корисник већ има непрочитану поруку. Упит СЕЛЕЦТ * из порука у којима име = $наме изгледа довољно једноставно, зар не?

ПОГРЕШНО!

У нашој невиности, отворили смо врата тренутном уништењу наше базе података. Да би се то десило, нападач мора да испуни следеће услове:

  • Апликација ради на СКЛ бази података (данас је скоро свака апликација)
  • Тренутна веза са базом података има дозволе за „уређивање“ и „брисање“ у бази података
  • Називи важних табела се могу погодити
  Можете ли креирати Инстаграм без Фејсбука?

Трећа тачка значи да сада када нападач зна да имате продавницу за е-трговину, врло вероватно складиштите податке о поруџбини у табели поруџбина. Наоружан са свим овим, све што нападач треба да уради је да наведе ово као своје име:

Јое; скраћи наређења;? Да господине! Хајде да видимо шта ће упит постати када га ПХП скрипта изврши:

СЕЛЕЦТ * ФРОМ мессагес ВХЕРЕ наме = Јое; трунцате ордерс;

У реду, први део упита има синтаксичку грешку (без наводника око „Јое“), али тачка-зарез приморава МиСКЛ машину да почне да тумачи нову: скраћи налоге. Само тако, једним потезом, цела историја поруџбина је нестала!

Сада када знате како СКЛ Ињецтион функционише, време је да погледате како да га зауставите. Два услова која треба да буду испуњена за успешно СКЛ ињекцију су:

  • ПХП скрипта треба да има привилегије за измену/брисање базе података. Мислим да ово важи за све апликације и да нећете моћи да своје апликације учините само за читање. 🙂 И погодите шта, чак и ако уклонимо све привилегије за измену, СКЛ ињекција и даље може дозволити некоме да покрене СЕЛЕЦТ упите и прегледа сву базу података, укључујући осетљиве податке. Другим речима, смањење нивоа приступа бази података не функционише, а вашој апликацији то ионако треба.
  • Кориснички унос се обрађује. Једини начин на који СКЛ ињекција може да функционише је када прихватате податке од корисника. Још једном, није практично зауставити све уносе за своју апликацију само зато што сте забринути за СКЛ ињекцију.
  • Спречавање СКЛ ињекције у ПХП-у

    Сада, с обзиром на то да су везе базе података, упити и кориснички улази део живота, како да спречимо СКЛ ињекцију? Срећом, прилично је једноставно и постоје два начина да се то уради: 1) дезинфиковати кориснички унос и 2) користити припремљене изјаве.

    Санитирајте унос корисника

    Ако користите старију верзију ПХП-а (5.5 или старију, а ово се често дешава на дељеном хостингу), паметно је да покренете сав кориснички унос кроз функцију која се зове мискл_реал_есцапе_стринг(). У суштини, оно што ради уклања све специјалне знакове у низу тако да губе своје значење када их користи база података.

    На пример, ако имате стринг као што је И’м стринг, нападач може користити знак једноструког наводника (‘) да манипулише упитом базе података који се креира и изазове СКЛ ињекцију. Покретање кроз мискл_реал_есцапе_стринг() производи И’м стринг, који додаје обрнуту косу црту појединачном наводнику, избегавајући га. Као резултат, цео стринг се сада прослеђује као безопасан стринг бази података, уместо да може да учествује у манипулацији упитима.

      Прилагођене иконе апликација успорите свој иПхоне

    Постоји један недостатак овог приступа: то је заиста, заиста стара техника која иде уз старије облике приступа бази података у ПХП-у. Од ПХП 7 ова функција више чак и не постоји, што нас доводи до нашег следећег решења.

    Користите припремљене изјаве

    Припремљене изјаве су начин да се упити базе података постану сигурнији и поузданији. Идеја је да уместо слања необрађеног упита бази података, прво кажемо бази података структуру упита који ћемо послати. То је оно што подразумевамо под „припремањем“ изјаве. Када је изјава припремљена, информације прослеђујемо као параметризоване улазе тако да база података може да „попуни празнине“ тако што ће уносе укључити у структуру упита коју смо раније послали. Ово одузима сваку посебну моћ коју улазни подаци могу имати, што доводи до тога да се они третирају као пуке променљиве (или корисни терет, ако хоћете) у целом процесу. Ево како изгледају припремљене изјаве:

    <?php
    $servername = "localhost";
    $username = "username";
    $password = "password";
    $dbname = "myDB";
    
    // Create connection
    $conn = new mysqli($servername, $username, $password, $dbname);
    
    // Check connection
    if ($conn->connect_error) {
        die("Connection failed: " . $conn->connect_error);
    }
    
    // prepare and bind
    $stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
    $stmt->bind_param("sss", $firstname, $lastname, $email);
    
    // set parameters and execute
    $firstname = "John";
    $lastname = "Doe";
    $email = "[email protected]";
    $stmt->execute();
    
    $firstname = "Mary";
    $lastname = "Moe";
    $email = "[email protected]";
    $stmt->execute();
    
    $firstname = "Julie";
    $lastname = "Dooley";
    $email = "[email protected]";
    $stmt->execute();
    
    echo "New records created successfully";
    
    $stmt->close();
    $conn->close();
    ?>

    Знам да процес звучи непотребно сложено ако сте нови у припремљеним изјавама, али концепт је итекако вредан труда. Ево леп увод у то.

    За оне који су већ упознати са ПХП екстензијом ПДО и користе је за креирање припремљених изјава, имам мали савет.

    Упозорење: Будите пажљиви када постављате ПДО

    Када користимо ПДО за приступ бази података, можемо бити увучени у лажни осећај сигурности. „Ах, па, ја користим ПДО. Сада не треба да размишљам ни о чему другом” — овако углавном иде наше размишљање. Истина је да је ПДО (или МиСКЛи припремљене изјаве) довољан да спречи све врсте напада СКЛ ињекцијом, али морате бити пажљиви када га подешавате. Уобичајено је само копирати и налепити код из туторијала или из ваших ранијих пројеката и наставити даље, али ово подешавање може да поништи све:

    $dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);

    Оно што ова поставка ради је да каже ПДО-у да емулира припремљене изјаве, а не да заправо користи функцију припремљених изјава базе података. Сходно томе, ПХП шаље једноставне стрингове упита бази података чак и ако ваш код изгледа као да креира припремљене изјаве и поставља параметре и све то. Другим речима, ви сте рањиви на СКЛ ињекцију као и раније. 🙂

      Како емитовати Нетфлик на Дисцорд-у

    Решење је једноставно: уверите се да је ова емулација подешена на фалсе.

    $dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

    Сада је ПХП скрипта принуђена да користи припремљене изјаве на нивоу базе података, спречавајући све врсте СКЛ ињекција.

    Спречавање коришћења ВАФ-а

    Да ли знате да такође можете заштитити веб апликације од СКЛ ињекције помоћу ВАФ-а (заштитног зида за веб апликације)?

    Па, не само СКЛ ињекција, већ и многе друге рањивости слоја 7 као што су скриптовање на више локација, покварена аутентификација, фалсификовање на више локација, изложеност података, итд. Можете користити само-хостоване као што је Мод Сецурити или базиране на облаку као што следи.

    СКЛ ињекција и савремени ПХП оквири

    СКЛ ињекција је толико уобичајена, тако лака, толико фрустрирајућа и толико опасна да сви модерни ПХП веб оквири долазе уграђени са противмерама. У ВордПресс-у, на пример, имамо функцију $впдб->препаре(), док ако користите МВЦ оквир, он ради сав прљав посао уместо вас и не морате чак ни да размишљате о спречавању СКЛ ињекције. Мало је неугодно што у ВордПресс-у морате експлицитно да припремате изјаве, али хеј, говоримо о ВордПресс-у. 🙂

    У сваком случају, моја поента је да модерна врста веб програмера не мора да размишља о СКЛ ињекцији, и као резултат тога, они нису ни свесни могућности. Као такав, чак и ако оставе отворен један бацкдоор у својој апликацији (можда је то параметар упита $_ГЕТ и старе навике покретања прљавог упита), резултати могу бити катастрофални. Зато је увек боље одвојити време да зароните дубље у темеље.

    Закључак

    СКЛ Ињецтион је веома гадан напад на веб апликацију, али се лако избегава. Као што смо видели у овом чланку, опрез при обради корисничког уноса (успут, СКЛ Ињецтион није једина претња коју руковање корисничким уносом доноси) и испитивање базе података је све што је ту. Уз то, не радимо увек на безбедности веб оквира, па је боље да будемо свесни ове врсте напада и не наседамо на њега.