Vienkāršs PHP un AJAX izmantošanas piemērs. Kontaktformas izveide, izmantojot Bootstrap, PHP un AJAX vispārējo entītijas paplašinājumu

04.09.2024

Desmit izplatītāko uzbrukumu veidu sarakstā saskaņā ar OWASP pirmās divas vietas ieņem koda ievadīšanas un XSS (cross-site scripting) uzbrukumi. Tie iet roku rokā, jo XSS, tāpat kā vairāki citi uzbrukumu veidi, ir atkarīgs no injekcijas uzbrukumu panākumiem. Šis nosaukums slēpj veselu uzbrukumu klasi, kuros dati tiek ievadīti tīmekļa lietojumprogrammā, lai piespiestu to izpildīt vai interpretēt ļaunprātīgu kodu tā, kā uzbrucējs vēlas. Šie uzbrukumi ietver, piemēram, XSS, SQL injekciju, galvenes ievadīšanu, koda ievadīšanu un pilna ceļa atklāšanu. Un šī ir tikai neliela daļa.


Injekcijas uzbrukumi ir šausmu stāsts visiem programmētājiem. Tie ir visizplatītākie un veiksmīgākie daudzveidības, mēroga un (dažkārt) aizsardzības grūtību dēļ pret tiem. Visām lietojumprogrammām ir jāiegūst dati no kaut kurienes. XSS un UI Redress ir īpaši izplatīti, tāpēc es tiem veltīju atsevišķas nodaļas un atdalīju no vispārējās klases.


OWASP piedāvā šādu injekcijas uzbrukumu definīciju:


Injekcijas iespējas, piemēram, SQL, OS un LDAP, rodas, kad tulks komandas pieprasījuma ietvaros saņem neuzticamus datus. Ļaunprātīgi dati var pievilt tulkam izpildīt noteiktas komandas vai piekļūt nesankcionētiem datiem.

SQL injekcija

SQL injekcija ir visizplatītākais un ārkārtīgi bīstamākais injekcijas uzbrukuma veids. Šo draudu nopietnību ir grūti pārvērtēt, tāpēc ir ārkārtīgi svarīgi saprast, kas ietekmē uzbrukumu panākumus un kā pret tiem aizsargāties.


Tātad dati tiek ievadīti tīmekļa lietojumprogrammā un pēc tam tiek izmantoti SQL vaicājumos. Tie parasti nāk no neuzticamiem ievades avotiem, piemēram, tīmekļa veidlapām. Tomēr injekciju var veikt arī no citām vietām, piemēram, no pašas datu bāzes. Programmētāji bieži tic savas datu bāzes pilnīgai drošībai, neapzinoties, ka, ja tā bija droša vienā gadījumā, tas nebūt nenozīmē, ka tā būs droša arī turpmāk. Dati no datu bāzes jāuzskata par neuzticamiem, kamēr nav pierādīts pretējais, tas ir, kamēr tie nav pārbaudīti.


Ja uzbrukums ir veiksmīgs, uzbrucējs var manipulēt ar SQL vaicājumu, lai tas datu bāzē veiktu darbības, kuras nav paredzējuši izstrādātāji.


Apskatiet šo vaicājumu:


$db = jauns mysqli ("localhost", "lietotājvārds", "parole", "storedb"); $result = $db->query("SELECT * FROM transakcijām WHERE user_id = " . $_POST["lietotāja_id"]);

Šeit ir vairākas aplodas. Pirmkārt, mēs nepārbaudījām POST datu saturu, lai pārliecinātos, ka user_id ir pareizs. Otrkārt, mēs ļaujam neuzticamam avotam norādīt, kuru user_id izmantot: uzbrucējs var ievadīt jebkuru derīgu user_id. Iespējams, tas bija ietverts slēptā laukā veidlapā, kuru uzskatījām par drošu, jo to nevarēja rediģēt (aizmirstot, ka uzbrucēji var ievadīt jebkādus datus). Treškārt, mēs neizvairāmies no lietotāja_id un nenodevām to vaicājumā kā saistītu parametru, kas arī ļauj uzbrucējam ievadīt patvaļīgas virknes, kas manipulēs ar SQL vaicājumu, ņemot vērā, ka mēs nevarējām to pārbaudīt.


Šie trīs izlaidumi tīmekļa lietojumprogrammās ir ļoti izplatīti.


Attiecībā uz datu bāzes uzticamību iedomājieties, ka transakcijas meklējām, izmantojot lauku user_name. Nosaukumi ir plaši un var saturēt pēdiņas. Pieņemsim, ka uzbrucējs vienā no lietotājvārdiem saglabā ievadīto virknes vērtību. Kad mēs šo vērtību atkal izmantosim kādā no tālāk norādītajiem vaicājumiem, tā manipulēs ar vaicājuma virkni, jo mēs uzskatījām, ka datu bāze ir uzticams avots un neizolējām vai neierobežojām apdraudēto vaicājumu.


Pievērsiet uzmanību arī citam SQL ieviešanas faktoram: pastāvīgā krātuve ne vienmēr ir jāuzglabā serverī. HTML 5 atbalsta klienta puses datu bāzes izmantošanu, kurā varat nosūtīt vaicājumus, izmantojot SQL un JavaScript. Šim nolūkam ir divas API: WebSQL un IndexedDB. 2010. gadā W3C neieteica izvēlēties WebSQL; to atbalsta WebKit pārlūkprogrammas, kurās kā aizmugursistēma tiek izmantota SQLite. Visticamāk, atbalsts paliks atpakaļsaderības labad, pat neskatoties uz W3C ieteikumu. Kā norāda nosaukums, šī API pieņem SQL vaicājumus, kas nozīmē, ka tā var būt injekcijas uzbrukumu mērķis. IndexedDB ir jaunāka alternatīva, NoSQL datu bāze (nav nepieciešams izmantot SQL vaicājumus).

SQL injekcijas piemēri

Manipulēšanai ar SQL vaicājumiem var būt šādi mērķi:

  • Datu noplūde.
  • Uzglabātās informācijas izpaušana.
  • Manipulācija ar saglabāto informāciju.
  • Autorizācijas apiešana.
  • Klienta puses SQL injekcija.
  • SQL injekcijas aizsardzība

    Aizsardzība pret SQL ievadīšanu balstās uz ešelonēšanas principu. Pirms datu izmantošanas vaicājumā ir jāpārbauda, ​​vai tā forma ir pareiza. Tāpat ir nepieciešams izolēt datus pirms to iekļaušanas pieprasījumā vai iekļaut tos kā pārejas parametru.

    Pārbaude

    Es to atkārtoju: visi dati, kas nav tieši izveidoti pašreizējā pieprasījuma PHP avota kodā, ir neuzticami. Stingri pārbaudiet tos un noraidiet visu, kas neiztur pārbaudes. Nemēģiniet "labot" datus, var veikt tikai nelielas, kosmētiskas izmaiņas formātā.


    Bieži pieļautās kļūdas ir datu validēšana pastāvīgai lietošanai (piemēram, displejs vai aprēķini) un datubāzes lauku neapstiprināšana, kurā informācija tiks saglabāta.

    Ekranēšana

    Izmantojot mysqli paplašinājumu, varat izolēt visus SQL vaicājumā iekļautos datus. Funkcija mysqli_real_escape_string() to dara. PostgresSQL pgsql paplašinājums piedāvā funkcijas pg_escape_bytea() , pg_escape_identifier() , pg_escape_literal() un pg_escape_string(). Mssql paplašinājumam (Microsoft SQL Server) nav izolēšanas funkciju, un addslashes() pieeja ir neefektīva - jums būs nepieciešama pielāgota funkcija.


    Lai padarītu jūsu dzīvi vēl grūtāku, teikšu, ka jums nav tiesību kļūdīties, izolējot pieprasījumā ievadītos datus. Viens garām, un jūs esat neaizsargāts pret uzbrukumu.


    Apkoposim. Ekranēšana nav labākā aizsardzības iespēja. Tas jāizmanto kā pēdējais līdzeklis. Tas var būt nepieciešams, ja datu bāzes bibliotēka, kuru izmantojat abstrakcijai, ļauj konfigurēt tukšus SQL vaicājumus vai vaicājuma daļas, nepiespiežot parametrus saistīt. Citos gadījumos labāk izvairīties no izolācijas vispār. Šī pieeja ir sarežģīta, tajā ir daudz kļūdu, un tā atšķiras atkarībā no datu bāzes paplašinājuma.

    Parametrizēti vaicājumi (sagatavotas izteiksmes)

    Parametrēšana jeb parametru saistīšana ir ieteicamais veids, kā izveidot SQL vaicājumus. Visas labās datu bāzes bibliotēkas to izmanto pēc noklusējuma. Šeit ir ACVN paplašinājuma izmantošanas piemērs PHP:


    if(ctype_digit($_POST["id"]) && is_int($_POST["id"])) ($validatedId = $_POST["id"]; $pdo = new ACVN("mysql:store.db") $stmt = $pdo->prepare("SELECT * FROM transakcijas WHERE user_id = :id" $stmt->bindParam(":id", $validatedId, PDO::PARAM_INT ); id vērtību un ziņot lietotājam par kļūdu)

    BindParam() metode, kas ir pieejama ACVN izteiksmēm, ļauj saistīt parametrus ar “vietturiem”, kas sniegti iepriekš sagatavotā izteiksmē. Šī metode pieņem pamata datu tipu parametrus, piemēram, PDO::PARAM_INT , PDO::PARAM_BOOL , PDO::PARAM_LOB un PDO::PARAM_STR . Šī ir noklusējuma vērtība ACVN::PARAM_STR, ja nav norādīts citādi, tāpēc atcerieties arī citas vērtības!


    Atšķirībā no manuālās izolācijas, parametru saistīšana (vai jebkura metode, ko izmanto jūsu datu bāzes bibliotēka) pareizi izolēs automātiski saistītos datus, tāpēc jums nav jāatceras, kuru funkciju izmantot. Turklāt konsekventa parametru saistīšana ir daudz uzticamāka nekā mēģinājums atcerēties, ka jums viss ir jāizolē manuāli.

    Vismazāko privilēģiju principa īstenošana

    Veiksmīgas SQL injekcijas pārtraukšana ir tikpat svarīga kā tās pilnīga novēršana. Kad uzbrucējs iegūst iespēju izpildīt SQL vaicājumus, viņš to darīs kā noteikts datu bāzes lietotājs. Mazāko privilēģiju princips var nodrošināt, ka visiem lietotājiem ir tikai tās privilēģijas, kas ir absolūti nepieciešamas viņu uzdevumu veikšanai.


    Ja lietotājam ir augstas privilēģijas, uzbrucējs var nomest tabulas un mainīt citu lietotāju privilēģijas, veicot jaunas SQL injekcijas viņu vārdā. Lai tas nenotiktu, nekad nepiekļūstiet datubāzei no tīmekļa lietojumprogrammas kā root, administrators vai cits lietotājs ar augstām privilēģijām.


    Vēl viens principa pielietojums ir datu nolasīšanas un ierakstīšanas datu bāzē lomu nodalīšana. Atlasiet vienu lietotāju ar tikai rakstīšanas atļaujām un otru ar tikai lasīšanas atļaujām. Ja uzbrukums ir vērsts uz “lasošo” lietotāju, tad uzbrucējs nevarēs manipulēt ar tabulā esošajiem datiem vai tos ierakstīt. Varat ierobežot piekļuvi vēl šaurāk, tādējādi samazinot veiksmīgu SQL injekcijas uzbrukumu ietekmi.


    Daudzas tīmekļa lietojumprogrammas, īpaši atvērtā pirmkoda lietojumprogrammas, ir paredzētas tikai vienam datu bāzes lietotājam, kura privilēģiju līmenis gandrīz noteikti nekad netiek pārbaudīts. Tāpēc neaizmirstiet par šo punktu un nemēģiniet palaist lietojumprogrammas ar administratora kontu.

    Koda ievadīšana (pazīstama kā attālā faila iekļaušana)

    Koda ievadīšana ir jebkura metode, kas ļauj uzbrucējam pievienot avota kodu tīmekļa lietojumprogrammai ar iespēju to interpretēt un izpildīt. Šajā gadījumā mēs nerunājam par koda ieviešanu klienta daļā, piemēram, JavaScript šeit jau tiek izmantoti XSS uzbrukumi.


    Varat ievadīt pirmkodu tieši no neuzticama ievades avota vai piespiest tīmekļa lietojumprogrammu to ielādēt no vietējās failu sistēmas vai ārēja resursa, piemēram, URL. Ja kods tiek ievadīts ārējā avota iekļaušanas rezultātā, to parasti sauc par attālo failu iekļaušanu (RFI), lai gan pats RFI vienmēr ir paredzēts koda ievadīšanai.


    Galvenie koda ieviešanas iemesli:

    • apejot ievades datu pārbaudi,
    • neuzticamas ievades ievadīšana jebkurā kontekstā, kur tā tiktu uzskatīta par PHP kodu,
    • pirmkoda krātuvju drošības uzlaušana,
    • atspējot brīdinājumus par trešo pušu bibliotēku ielādi,
    • servera pārkonfigurēšana, lai tas PHP tulkam nodotu failus, kas nav PHP.

    Pievērsiet īpašu uzmanību pēdējam punktam: šajā gadījumā neuzticami lietotāji var augšupielādēt jebkurus failus serverī.

    Koda ievadīšanas piemēri

    PHP ir daudz koda ievadīšanas mērķu, tāpēc šāda veida uzbrukumi ir jebkura programmētāja skatīšanās saraksta augšgalā.

    Ieskaitot failu

    Acīmredzamākie koda ievadīšanas mērķi ir funkcijas include() , include_once() , request() un request_once() . Ja neuzticami ievades dati ļauj noteikt šīm funkcijām nodoto ceļa parametru, varat attālināti kontrolēt, kuru failu iekļaut. Jāņem vērā, ka iekļautajam failam nav jābūt reālam PHP failam, var izmantot jebkuru failu formātu, kas spēj glabāt teksta datus (t.i., gandrīz bez ierobežojumiem).


    Ceļa parametrs var būt arī neaizsargāts pret direktoriju iziešanas vai attālās failu iekļaušanas uzbrukumiem. Izmantojot ../ vai... rakstzīmju kombinācijas ceļā, uzbrucējs var pāriet uz gandrīz jebkuru failu, kuram ir piekļuve PHP procesam. Tajā pašā laikā noklusējuma PHP konfigurācijā iepriekš minētās funkcijas pieņem URL, ja vien nav atspējots atļauts_url_include.

    Pārbaude

    PHP eval() funkcija izpildei pieņem PHP koda rindu.

    Regulāro izteiksmju ieviešana

    PCRE (Perl Compatible Regular Expression) funkcija preg_replace() PHP ļauj izmantot modifikatoru e (PREG_REPLACE_EVAL). Tas nozīmē nomaiņas virkni, kas pēc aizstāšanas tiks uzskatīta par PHP kodu. Un, ja šajā rindā ir neuzticama ievade, viņi varēs ievadīt izpildāmu PHP kodu.

    Bojāta failu iekļaušanas loģika

    Tīmekļa lietojumprogrammās pēc definīcijas ir iekļauti faili, kas nepieciešami, lai apkalpotu jebkuru pieprasījumu. Ja izmantojat maršrutēšanas loģikas, atkarības pārvaldības, automātiskās ielādes un citu procesu defektus, manipulējot ar pieprasījuma ceļu vai tā parametriem, serveris būs jāiekļauj konkrēti lokālie faili. Tā kā tīmekļa lietojumprogramma nav paredzēta šādu manipulāciju veikšanai, sekas var būt neparedzamas. Piemēram, lietojumprogramma neapzināti atklās maršrutus, kas paredzēti lietošanai tikai komandrindā. Vai arī tiks atklātas citas klases, kuru konstruktori veic uzdevumus (labāk klases neveidot šādā veidā, bet tas joprojām notiek). Jebkurš no šiem scenārijiem var traucēt lietojumprogrammas aizmugursistēmas darbības, ļaujot manipulēt ar datiem vai veikt DOS uzbrukumus resursietilpīgām darbībām, kas neietver tiešu piekļuvi.

    Kodu ievadīšanas izaicinājumi

    Uzdevumu klāsts ir ārkārtīgi plašs, jo šāda veida uzbrukumi ļauj izpildīt jebkuru PHP kodu pēc uzbrucēja izvēles.

    Aizsardzība pret koda ievadīšanuCommand InjectionCommand InjectionpiemēriAizsardzība pret Command InjectionLog Injection (pazīstama kā žurnālfaila ievadīšana)

    Daudzas lietojumprogrammas apkopo žurnālus, un autorizētie lietotāji bieži tos apskata, izmantojot HTML saskarni. Tāpēc žurnāli ir viens no galvenajiem uzbrucēju mērķiem, kuri vēlas slēpt citus uzbrukumus, maldināt tos, kuri skatās žurnālus, un pēc tam pat uzbrūk tās uzraudzības lietojumprogrammas lietotājiem, ar kuru žurnāli tiek lasīti un analizēti.


    Žurnālu ievainojamība ir atkarīga no žurnālu ierakstīšanas kontroles mehānismiem, kā arī no tā, ka žurnāla dati tiek uzskatīti par neuzticamu avotu, skatot un analizējot žurnālus.


    Vienkārša reģistrēšanas sistēma var ierakstīt teksta virknes failā, izmantojot file_put_contents() . Piemēram, programmētājs neveiksmīgos autorizācijas mēģinājumus reģistrē kā šāda formāta virknes:


    sprintf("Neveiksmīgs pieteikšanās mēģinājums %s", $lietotājvārds);

    Ko darīt, ja uzbrucējs veidlapā izmanto nosaukumu “AdminnSuccessful login by Adminn”?


    Ja šī rinda tiek ievietota žurnālā no neuzticamiem ievades datiem, uzbrucējs veiksmīgi slēps neveiksmīgo autorizācijas mēģinājumu, izmantojot nevainīgu administratora paroles ievadīšanas kļūdu. Ja pievienosit veiksmīgu autorizācijas mēģinājumu, datu aizdomīgums tiks samazināts vēl vairāk.


    Viss šeit ir tāds, ka uzbrucējs var pievienot žurnālam visa veida ierakstus. Varat arī ievadīt XSS vektorus un pat rakstzīmes, kas padara žurnāla ierakstus grūti nolasāmus konsolē.

    Baļķu injekcijas uzdevumi

    Viens no ieviešanas mērķiem ir log formāta tulki. Ja analīzes rīks izmanto regulāras izteiksmes, lai parsētu žurnāla ierakstus un sadalītu tos dažādos laukos, tad ir iespējams izveidot un ievadīt virkni, kas liek regulārajai izteiksmei atlasīt ievadītos laukus, nevis pareizos. Piemēram, šis ieraksts var radīt vairākas problēmas:


    $username = "iamnothacker! at Mon Jan 01 00:00:00 +1000 2009"; sprintf ("Neveiksmīgs pieteikšanās mēģinājums %s, %s", $lietotājvārds,)

    Sarežģītāki žurnālu ievadīšanas uzbrukumi balstās uz direktoriju šķērsošanas uzbrukumiem, lai parādītu žurnālu pārlūkprogrammā. Pareizos apstākļos PHP koda ievadīšana žurnāla ziņojumā un žurnāla faila atvēršana pārlūkprogrammā nodrošinās veiksmīgu koda ievadīšanu, kas tiks pareizi formatēta un izpildīta pēc uzbrucēja pieprasījuma. Un, ja runa ir par ļaunprātīgas PHP izpildi serverī, tad atliek cerēt uz aizsardzības slāņojuma efektivitāti, kas var samazināt bojājumus.

    Baļķu iesmidzināšanas aizsardzība

    Vienkāršākais veids, kā filtrēt visus ārējos žurnāla ziņojumus, ir izmantot balto sarakstu. Pieņemsim, ka rakstzīmju kopu ierobežo tikai cipari, burti un atstarpes. Ziņojumi, kas satur neatļautas rakstzīmes, tiek uzskatīti par bojātiem. Pēc tam žurnālā tiek parādīts ieraksts par iespējamu mēģinājumu ievadīt žurnāla failu. Šī ir vienkārša drošības metode vienkāršiem teksta žurnāliem, kuros nevar izvairīties no neuzticamu ievades datu iekļaušanas ziņojumos.


    Otrā aizsardzības metode ir neuzticamu ievades datu gabalu konvertēšana, izmantojot tādu sistēmu kā base64, kas atbalsta ierobežotu rakstzīmju kopu, vienlaikus ļaujot teksta formā saglabāt dažādu informāciju.

    Ceļa iziešana (pazīstama kā direktorija iziešana)

    Ceļa šķērsošanas uzbrukumi ir mēģinājumi ietekmēt failu lasīšanas vai rakstīšanas darbības tīmekļa lietojumprogrammas aizmugurē. Tas tiek darīts, ieviešot parametrus, kas ļauj manipulēt ar aizmugursistēmas operācijās iesaistīto failu ceļiem. Tādējādi šāda veida uzbrukumi atvieglo informācijas izpaušanu un lokālo/attālo failu ievadīšanu.


    Mēs izskatīsim šādus uzbrukumus atsevišķi, taču to panākumu pamatā ir tieši ceļa šķērsošana. Tā kā tālāk aprakstītās funkcijas ir specifiskas failu ceļu manipulēšanai, ir jēga pieminēt, ka daudzas PHP funkcijas nepieņem failu ceļus šī vārda parastajā nozīmē. Tā vietā tādas funkcijas kā include() vai file() pieņem URI.


    Tas izskatās pilnīgi nedabiski. Bet tas nozīmē, ka šādi divi funkciju izsaukumi ir līdzvērtīgi, kas izmanto absolūtos ceļus (piemēram, nepaļaujoties uz relatīvo ceļu automātisko ielādi).


    include('/var/www/vendor/library/Class.php'); include('file:///var/www/vendor/library/Class.php');

    Lieta ir tāda, ka relatīvais ceļš tiek apstrādāts sānos (include_path iestatījums php.ini un pieejamie autoloaders). Šādos gadījumos PHP funkcijas ir īpaši neaizsargātas pret daudziem parametru manipulācijas veidiem, tostarp failu URI shēmas aizstāšanu, kur uzbrucējs var ievadīt HTTP vai FTP URI, ja faila ceļa sākumā ir iegulti neuzticami dati. Sīkāk par to runāsim sadaļā par attāliem failu iekļaušanas uzbrukumiem, bet pagaidām koncentrēsimies uz failu sistēmas ceļu apiešanu.


    Šī ievainojamība ietver ceļa maiņu, lai piekļūtu citam failam. To parasti panāk, argumentā ievadot virkni ../ secību, kas pēc tam tiek pievienotas funkcijām vai pilnībā ievietotas funkcijās, piemēram, include() , request() , file_get_contents() un vēl mazāk aizdomīgās (dažām) funkcijās. piemēram, DOMDocument: :load() .


    Izmantojot secību ../, uzbrucējs piespiež sistēmu atgriezties vecākdirektorijā. Tātad ceļš /var/www/public/../vendor faktiski dodas uz /var/www/vendor. Secība ../ pēc /public aizved mūs atpakaļ uz vecākdirektoriju, t.i., /var/www. Tas ļauj uzbrucējam piekļūt failiem, kas atrodas ārpus /publiskā direktorija, kam var piekļūt no tīmekļa servera.


    Protams, ceļa šķērsošana neaprobežojas tikai ar atgriešanos. Varat ieviest jaunus ceļa elementus, lai piekļūtu pakārtotajiem direktorijiem, kas nav pieejami no pārlūkprogrammas .htaccess ierobežojumu iestatījumu dēļ. PHP failu sistēmas darbības nerūpējas par piekļuves kontroles konfigurāciju nepubliskiem failiem un direktorijiem tīmekļa serverī.

    Path TraversalAizsardzības pret Path TraversalXML injekciju piemēri

    Neskatoties uz JSON ieviešanu kā vieglu datu pārsūtīšanas līdzekli starp serveri un klientu, XML joprojām ir populāra alternatīva, un tīmekļa pakalpojumu API bieži to atbalsta paralēli JSON. XML tiek izmantots arī datu apmaiņai, izmantojot XML shēmas: RSS, Atom, SOAP un RDF utt.


    XML ir visuresošs: to var atrast tīmekļa lietojumprogrammu serveros, pārlūkprogrammās (kā vēlamais formāts XMLHttpRequest pieprasījumiem un atbildēm) un pārlūkprogrammas paplašinājumos. Ņemot vērā tā izplatību un noklusējuma apstrādi ar populāriem parsētājiem, piemēram, libxml2, ko PHP izmanto DOM un SimpleXML un XMLReader paplašinājumos, XML ir kļuvis par injekcijas uzbrukumu mērķi. Pārlūkprogrammai aktīvi iesaistoties XML apmaiņā, jāņem vērā, ka caur XSS autorizētie lietotāji var pārsūtīt XML pieprasījumus, kurus faktiski ir izveidojuši uzbrucēji.

    XML ārējās entītijas iegulšana (XXE)

    Šie uzbrukumi pastāv, jo XML parsēšanas bibliotēkas bieži atbalsta pielāgotu entītiju atsauču izmantošanu. Jūs uzzināsit par standarta XML entītiju pabeigšanu, kas tiek izmantota, lai attēlotu īpašas iezīmēšanas rakstzīmes, piemēram, > , < ; un '. XML ļauj paplašināt standarta entītiju kopu, definējot pielāgotas entītijas, izmantojot pašu XML dokumentu. Tos var definēt, tieši iekļaujot tos izvēles DOCTYPE. To pārstāvētā paplašinātā vērtība var attiekties uz ārēju resursu, kas būtu jāiekļauj. XXE uzbrukumi kļuva populāri tieši pateicoties parastā XML spējai saglabāt pielāgotas saites, kuras var paplašināt ārējo resursu satura dēļ. Normālos apstākļos neuzticamas ievades nekad nedrīkst neparedzētā veidā mijiedarboties ar mūsu sistēmu. Un lielākā daļa XXE programmētāju gandrīz noteikti neparedz XXE uzbrukumus, kas rada īpašas bažas.


    Piemēram, definēsim jaunu pielāgotu entītiju, kas ir nekaitīga:



    XML dokuments ar šo definīciju tagad var atsaukties uz entītiju visur, kur parasti ir atļautas entītijas:


    Šis rezultāts ir

    Kad XML parsētājs, piemēram, PHP DOM, interpretē šo XML, tas apstrādās šo pielāgoto entītiju, tiklīdz dokuments tiks ielādēts. Tāpēc, pieprasot atbilstošo tekstu, tas atgriezīs šo:


    Šis rezultāts ir pilnīgi nekaitīgs


    Acīmredzot pielāgoto entītiju priekšrocība ir atkārtota teksta un XML attēlošana ar īsākiem entītiju nosaukumiem. Bieži vien XML ir jāievēro noteikta gramatika, un pielāgotās entītijas atvieglo rediģēšanu. Tomēr, ņemot vērā mūsu neuzticību ārējai ievadei, mums jābūt ļoti uzmanīgiem ar jebkuru XML, ko patērē mūsu lietojumprogramma. Piemēram, šī šķirne vispār nav droša:


    &harmless;

    Atkarībā no pieprasītā lokālā faila satura datus var izmantot, paplašinot entītiju. Pēc tam izvērsto saturu var iegūt no XML parsētāja un iekļaut tīmekļa lietojumprogrammas izejošajos datos, lai uzbrucējs veiktu analīzi. Piemēram, lai atklātu informāciju. Izvilktais fails tiks interpretēts kā XML, lai gan nav īpašu rakstzīmju, kas aktivizētu šo interpretāciju. Tas ierobežo lokālā faila satura eksponēšanas apjomu. Ja fails tiek interpretēts kā XML, bet tajā nav derīga XML, visticamāk, mēs saņemsim kļūdu, kas neļaus saturu atklāt. Tomēr PHP ir pieejams gudrs triks, lai apietu tvēruma ierobežojumu, lai attālie HTTP pieprasījumi ietekmētu tīmekļa lietojumprogrammu pat tad, ja atgriezto atbildi nevar nosūtīt atpakaļ uzbrucējam.


    Ir trīs plaši izmantotas metodes XML parsēšanai un lietošanai PHP: PHP DOM, SimpleXML un XMLReader. Tie visi izmanto paplašinājumu libxml2, un ārējo entītiju atbalsts ir iespējots pēc noklusējuma. Līdz ar to PHP pēc noklusējuma ir neaizsargāta pret XXE uzbrukumiem, ko ir ļoti viegli nepamanīt, ņemot vērā tīmekļa lietojumprogrammas vai bibliotēkas drošību, kas izmanto XML.


    Neaizmirstiet arī, ka XHTML un HTML 5 var serializēt kā derīgu XML. Tas nozīmē, ka dažas XHTML lapas vai XML serializētu HTML 5 var parsēt kā XML, izmantojot DOMDocument::loadXML(), nevis DOMDocument::loadHTML() . Šī XML parsētāja izmantošana ir arī neaizsargāta pret ārējo XML entītiju ievadīšanu. Atcerieties, ka libxml2 vēl pat neatpazīst HTML 5 DOCTYPE, tāpēc nevar to apstiprināt kā XHTML DOCTYPES.

    Ārējo XML entītiju ieviešanas piemēri Faila saturs un atklāšana

    Iepriekš aplūkojām informācijas izpaušanas piemēru, norādot, ka pielāgota XML entītija var atsaukties uz ārēju failu.


    &harmless;

    Šajā gadījumā pielāgotā entītija tiks paplašināta ar failu saturu. Tā kā visi šādi pieprasījumi tiek izpildīti lokāli, tas ļauj atklāt visu to failu saturu, kurus lietojumprogramma var nolasīt. Tas ir, kad paplašinātā entītija ir iekļauta lietojumprogrammas izejošajos datos, uzbrucējs varēs pārbaudīt failus, kas nav pieejami. Tomēr šajā gadījumā pastāv nopietns ierobežojums: failiem jābūt vai nu XML formātā, vai tādā formātā, kas neizraisīs XML parsētāja kļūdu. Bet būtība ir tāda, ka PHP šo ierobežojumu var pilnībā ignorēt:


    &harmless;

    PHP nodrošina piekļuvi iesaiņojumam kā URI, kas ir viens no protokoliem, ko pieņem standarta failu sistēmas funkcijas: file_get_contents(), request(), request_once(), file(), copy() un daudzi citi. PHP iesaiņotājs atbalsta vairākus filtrus, kurus var lietot konkrētam resursam, lai rezultāti tiktu atgriezti, izsaucot funkciju. Iepriekš minētajā piemērā mēs izmantojam convert.base-64-encode filtru mērķa failam, kuru vēlamies lasīt.


    Tas nozīmē, ka uzbrucējs var lasīt jebkuru PHP pieejamo failu neatkarīgi no teksta formāta. Pietiek vienkārši atšifrēt datus, kas nāk no lietojumprogrammas, un pēc tam tos nesodīti sadalīt. Lai gan tas tieši nekaitē galalietotājiem vai lietojumprogrammas aizmugursistēmai, tas ļauj uzbrucējiem rūpīgi izpētīt lietojumprogrammas struktūru, mēģinot atrast citas ievainojamības. Turklāt risks, ka uzbrucēji tiks atklāti, ir minimāls.

    Piekļuves kontroles apvedceļš

    Piekļuve tiek kontrolēta dažādos veidos. Tā kā XXE uzbrukumi tiek veikti tīmekļa lietojumprogrammas aizmugurē, pašreizējā lietotāja sesiju nevarēs izmantot. Taču uzbrucējs joprojām var apiet piekļuves kontroli aizmugursistēmai, izmantojot pieprasījumus no vietējā servera. Apsveriet šo primitīvo piekļuves kontroli:


    if (isset($_SERVER["HTTP_CLIENT_IP"]) || isset($_SERVER["HTTP_X_FORWARDED_FOR"]) || !in_array(@$_SERVER["REMOTE_ADDR"], array("127.0.0.1", "::1 ",))) ( header("HTTP/1.0 403 Forbidden"); exit("Jums nav atļauts piekļūt šim failam."); )

    Šis PHP gabals, tāpat kā neskaitāmi citi līdzīgi, ierobežo piekļuvi noteiktiem PHP failiem vietējā serverī, t.i., localhost. Tomēr XXE uzbrukums lietojumprogrammas priekšpusē uzbrucējam sniedz precīzus akreditācijas datus, kas nepieciešami, lai apietu šīs piekļuves vadīklas, jo visi HTTP pieprasījumi XML parsētājam tiks veikti no localhost.


    &harmless;

    Pat ja žurnālu skatīšana būtu ierobežota ar vietējiem pieprasījumiem, uzbrucējs joprojām varētu iegūt žurnālus. Tas pats attiecas uz uzturēšanas vai administrēšanas saskarnēm, kurām piekļuve šādā veidā ir ierobežota.

    DOS uzbrukumi

    Gandrīz viss, kas nosaka servera resursu patēriņu, var tikt izmantots DOS uzbrukumiem. Ievadot ārēju XML entītiju, uzbrucējs var veikt patvaļīgus HTTP pieprasījumus, kas atbilstošos apstākļos iztukšo servera resursus.


    Mēs vēlāk runāsim par citiem iespējamiem XXE uzbrukumu DOS lietojumiem saistībā ar XML entītiju paplašināšanu.

    Aizsardzība pret ārējo XML entītiju ievadīšanu

    Šie uzbrukumi ir ļoti populāri, tāpēc jūs būsiet pārsteigti, cik viegli ir pret tiem aizsargāties. Tā kā DOM, SimpleXML un XMLReader paļaujas uz libxml2, varat vienkārši izmantot funkciju libxml_disable_entity_loader(), lai atspējotu ārējo entītiju izmantošanu. Tomēr tas neatspējos pielāgotās entītijas, kas ir iepriekš definētas DOCTYPE, jo tās neizmanto ārējos resursus, kuriem nepieciešams HTTP pieprasījums vai failu sistēmas darbība.


    $oldValue = libxml_disable_entity_loader(true); $dom = jauns DOMDocument(); $dom->loadXML($xml); libxml_disable_entity_loader($oldValue);

    Tas ir jādara visām darbībām, kas saistītas ar XML ielādi no virknēm, failiem vai attāliem URI.


    Ja lietojumprogrammai nekad nav nepieciešamas ārējas entītijas un lielākajai daļai tās pieprasījumu, ārējo resursu ielādi var vispār atspējot globālākā līmenī. Vairumā gadījumu tas ir daudz vēlams, lai definētu visus XML ielādes punktus, ņemot vērā, ka daudzām bibliotēkām ir raksturīgas ievainojamības pret XXE uzbrukumiem:


    libxml_disable_entity_loader(true);

    Vienkārši neaizmirstiet atgriezt TRUE pēc katras īslaicīgas ārējo resursu ielādes iespējotas. Tas var būt nepieciešams tik nekaitīgam darbam kā Docbook XML konvertēšana uz HTML, kur XSL stilu pielietojums ir atkarīgs no ārējām entītijām.


    Tomēr libxml2 atspējošanas funkcija nav panaceja. Analizējiet citus paplašinājumus un PHP bibliotēkas, kas parsē vai citādi apstrādā XML, lai atrastu savus "slēdžus" ārējo entītiju lietošanai.


    Ja tas nav iespējams, papildus pārbaudiet, vai XML dokumentā ir deklarēts DOCTYPE. Ja tā ir un ja ārējās entītijas ir atspējotas, vienkārši izmetiet XML dokumentu, liedzot neuzticamu XML piekļuvi potenciāli neaizsargātajam parsētājam un reģistrējot to kā iespējamu uzbrukumu. Tas ir nepieciešams solis, jo nebūs citu pazīmju – ne kļūdu, ne izņēmumu. Iekļaujiet šo pārbaudi parastajā ievades validācijā. Bet šī metode ir tālu no ideāla, tāpēc ir ļoti ieteicams fundamentāli atrisināt ārējo vienību problēmu.


    /** * Mēģiniet ātri noteikt */ $collapsedXML = preg_replace("/[:space:]/", "", $xml); if(preg_match("/