Pabėgimas nuo specialiųjų simbolių. Pabėgimas nuo vieno veikėjo

Paprastai programavimo kalbos, tekstas komandų sąsajos, teksto žymėjimo kalbos (HTML, TeX, wiki žymėjimas) susijusios su struktūriniu tekstu, kuriame tam tikri simboliai (ir jų deriniai) naudojami kaip vadovai, įskaitant tuos, kurie valdo teksto struktūrą. Esant situacijai, kai reikia naudoti tokį simbolį kaip „įprastos kalbos simbolį“, naudokite ekranavimas.

Tradiciškai ekranavimas gali būti suskirstytas į tris tipus:

  • vieno simbolio pabėgimas
  • pabėgimas iš simbolių grupės naudojant simbolių seką „pradėti pabėgti“, „pabaigti pabėgimą“
  • naudojant komandų seką „start ecaping“ ir „pabėgimo pabaigos“ simbolį, kuris nurodomas prieš pakeičiamo teksto pradžią.
Ekrano trūkumas kaip pažeidžiamumo priežastis

Pabėgę personažai traukia Ypatingas dėmesys, kai struktūrinis tekstas generuojamas automatiškai. Norint įtraukti į tekstą savavališkus eilutės duomenis, jame reikia palikti valdymo simbolius. Tuo pačiu metu labai dažnai tikrose eilutėse nėra tokių simbolių, todėl programuotojas gali visiškai praleisti šią operaciją ir gauti daugiau paprasta programa, kuris tinkamai veikia su „bet kokiais pagrįstais“ eilutės duomenimis. Tačiau toks supaprastintas kodas turi paslėptą pažeidžiamumą, nes trečioji šalis (eilutės duomenų autorius) gauna neleistiną galimybę paveikti struktūra sukurtas tekstas. Pažeidžiamumas tampa rimtas, jei sukurtas tekstas yra kažkieno programa. Tradiciškai sistemos, kuriose naudojamos SQL (žr. SQL įterpimas) ir HTML (žr. Cross Site Scripting) kalbas, yra jautrios tokioms problemoms.

Pavyzdžiai Pabėgimas nuo vieno simbolio
  • C programavimo kalboje simboliai eilutėse yra pakeičiami naudojant simbolį " ", esantį prieš simbolį, kuris yra pašalinamas. (Šiuo atveju simbolis „\“ gali ištrūkti pats, ty kombinacija „\\“ naudojama pasvirajam brūkšniui išvesti), tas pats simbolis naudojamas simboliams pašalinti komandinė eilutė unix.
  • „Microsoft Windows“ komandinėje eilutėje kai kurių simbolių pašalinimas atliekamas naudojant „^“ simbolį, esantį prieš pašalinamąjį simbolį.
Pabėgimas iš veikėjų grupės
  • Python programavimo kalboje simbolių grupės pabėgimas eilutėje atliekamas prieš eilutę nurodant raidę r (iš anglų kalbos raw - neapdorota), t. y. simboliai pašalinami sekomis. r" pabėgimo tekstas "
  • Wiki žymėjime teksto pašalinimas atliekamas naudojant pseudožymes ir . Jei reikia parašyti pačią pseudo žymą, tai daroma naudojant pakaitos simbolius ().
Pabėgimo tekstas su paskutiniu simboliu

Kai tekste yra daug kontrolinių simbolių, bus daug pabėgimo simbolių, tekstas tampa sunkus. Tokiais atvejais naudojamas alternatyvus pabėgimo būdas – su galutiniu tekstu. Tokiu atveju visi valdymo simboliai bus tik simboliai (jie nevykdo valdymo funkcijos), o tekstas baigiasi, kai kompiliatorius aptinka tam tikrą seką – galutinį tekstą.

  • Vertimas
  • Pamoka

SQL injekcijos, kelių svetainių užklausų klastojimas, sugadintas XML... Baisūs, baisūs dalykai, nuo kurių visi norėtume būti apsaugoti, bet tik norime žinoti, kodėl visa tai vyksta. Šiame straipsnyje paaiškinama pagrindinė viso to sąvoka: stygos ir stygų tvarkymas eilutėse.

Pagrindinė problema – tik tekstas. Taip, tik tekstas – tai pagrindinė problema. Beveik viskas kompiuterinėje sistemoje yra pavaizduota tekstu (kuris savo ruožtu pavaizduotas baitais). Ar gali būti, kad vieni tekstai skirti kompiuteriams, o kiti – žmonėms. Tačiau abu jie vis tiek lieka tekstu. Kad suprastumėte, apie ką kalbu, pateikiame nedidelį pavyzdį:
Homo Sapiens Tarkime, yra angliškas tekstas, kurio aš nenoriu versti į rusų kalbą
Nepatikėsite: tai tekstas. Kai kurie žmonės tai vadina XML, bet tai tik tekstas. Jis gali būti netinkamas parodyti mokytojui. angliškai, bet tai vis tiek tik tekstas. Gali atsispausdinti ant plakato ir eiti su juo į mitingus, gali parašyti laiške mamai... tai tekstas.

Tačiau norime, kad tam tikros šio teksto dalys turėtų kokią nors reikšmę mūsų kompiuteriui. Norime, kad kompiuteris galėtų atskirai išgauti teksto autorių ir patį tekstą, kad galėtume su juo ką nors padaryti. Pavyzdžiui, konvertuokite aukščiau pateiktą informaciją į tai:
Tarkime, yra angliškas tekstas, kurio nenoriu išversti į rusų kalbą Homo Sapiens
Kaip kompiuteris žino, kaip tai padaryti? Na, nes tam tikras teksto dalis labai patogiai apvyniojome specialiais žodžiais juokinguose skliausteliuose, patinka ir. Kadangi tai padarėme, galime parašyti programą, kuri ieško šių konkrečių dalių, ištraukia tekstą ir naudoja jį savo išradimams.

Kitaip tariant, savo tekste naudojome tam tikras taisykles, kad nurodytume kokią nors ypatingą reikšmę, kurią galėtų naudoti kažkas kitas, laikydamasis tų pačių taisyklių.
Gerai, tai nėra taip sunku suprasti. Ką daryti, jei norime naudoti šiuos juokingus skliaustus, kurie turi ypatingą reikšmę mūsų tekste, bet nenaudodami šios reikšmės?.. Kažkas panašaus:
Homo sapiens< n and y >
„“ simboliai nėra ypatingi. Jie gali būti teisėtai naudojami bet kur, bet kokiame tekste, kaip nurodyta aukščiau pateiktame pavyzdyje. Bet kaip su mūsų idėja apie ypatingus žodžius? Ar tai reiškia, kad tai taip pat tam tikras raktinis žodis? XML – galbūt taip. O gal ir ne. Tai dviprasmiška. Kadangi kompiuteriai nelabai sugeba susidoroti su dviprasmybėmis, kažkas gali duoti netikėtą rezultatą, jei patys nepažymėsime i ir neišspręsime neaiškumų.
Šią dilemą galima išspręsti dviprasmiškus simbolius pakeitus kažkuo nedviprasmišku.
„Homo Sapiens“ pagrindinė matematika sako, kad jei x< n and y >n, x negali būti didesnis už y.
Dabar tekstas turėtų tapti visiškai nedviprasmiškas. "".
Techninis apibrėžimas tai - ekranavimas, išvengiame specialių simbolių, kai nenorime, kad jie turėtų savo ypatingą reikšmę.
pabėgti |iˈskāp| [nėra obj. ] išsilaisvinti [ su obj. ] nepastebėti / neprisiminti [...] [ su obj. ] IT: priežastis interpretuoti kitaip [...]
Jei tam tikri simboliai ar simbolių sekos tekste turi specialias reikšmes, tuomet turi būti taisyklės, nurodančios, kaip elgtis situacijose, kai tie simboliai turi būti naudojami nesikreipiant į jų specialią reikšmę. Arba, kitaip tariant, pabėgimas atsako į klausimą: „Jei šie simboliai tokie ypatingi, kaip galiu juos panaudoti savo tekste?.
Kaip matote anksčiau pateiktame pavyzdyje, ampersandas (&) taip pat yra specialus simbolis. Bet kas, jei norime rašyti "


Jei jūsų vartotojai yra geri ir malonūs, jie paskelbs senų filosofų citatas, o pranešimai atrodys maždaug taip:

Platonas paskelbė sausio 2 d., 15:31

Sakoma, kad esu pasakęs: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nipsucommodout conqualitt."


Jei vartotojai yra protingi, jie tikriausiai kalbės apie matematiką, o pranešimai bus tokie:

Paskalis paskelbė lapkričio 23 d., 04:12

Pagrindinė matematika mums sako, kad jei x< n and y >n, x negali būti didesnis už y.


Hmm... Vėl šitie mūsų skliaustų išniekėjai. Na, su techninis punktas Vizualiai jie gali būti dviprasmiški, bet naršyklė mums tai atleis, tiesa?


Gerai, STOP, kas po velnių? Kažkoks pokštininkas jūsų forume pristatė javascript žymas? Visi, kurie žiūri į šį pranešimą jūsų svetainėje, dabar atsisiunčia ir vykdo scenarijus jūsų svetainės kontekste, kurie gali ką nors žinoti. Ir tai nėra gerai.

Nereikia suprasti pažodžiui Aukščiau nurodytais atvejais norime kažkaip pasakyti savo DB ar naršyklei, kad tai tik tekstas, nieko su juo nedarykite! Kitaip tariant, norime „ištrinti“ ypatingos reikšmės Visi specialieji simboliai ir raktažodžius iš bet kokios vartotojo pateiktos informacijos, nes juo nepasitikime. Ką daryti?

Ką? Ką tu sakai, berniuk? O, jūs sakote, „ekranavimas“? Ir tu visiškai teisus, imk sausainį!
Jei naudotojo duomenims taikysime pabėgimą prieš sujungdami juos su užklausa, tada problema išspręsta. Mūsų duomenų bazės užklausoms tai būtų kažkas panašaus:
$vardas = $_POST["vardas"]; $vardas = mysql_real_escape_string($vardas); $query = "PASIRINKITE telefono_numerį FROM vartotojų WHERE vardas = "$vardas""; $rezultatas = mysql_query($klausa);
Tik viena kodo eilutė, bet dabar niekas nebegali „nulaužti“ į mūsų duomenų bazę. Dar kartą pažiūrėkime, kaip atrodys SQL užklausos, priklausomai nuo vartotojo įvesties:
Aleksas
SELECT telefono_numeris FROM naudotojai WHERE vardas = "Aleksas"
Mc Donalds
SELECT telefono_numeris FROM naudotojai WHERE name = "Mc\"Donalds"
Joe“; DROP TABLE naudotojai; --
SELECT telefono_numeris FROM vartotojų WHERE vardas = "Joe\"; DROP TABLE vartotojai; --"
mysql_real_escape_string beatodairiškai deda pasvirąjį brūkšnį prieš viską, kas gali turėti kokią nors ypatingą reikšmę.


Prieš išvesdami visus vartotojo duomenis, pritaikome funkciją htmlspecialchars. Dabar kenkėjo pranešimas atrodo taip:

JackTR paskelbė liepos 18 d., 12:56


Atminkite, kad iš vartotojų gautos vertės iš tikrųjų nėra „sugadintos“. Bet kuri naršyklė išanalizuos tai kaip HTML ir viską parodys ekrane tinkama forma.

Tai sugrąžina mus prie... Visa tai, kas išdėstyta pirmiau, parodo daugeliui sistemų būdingą problemą: tekste esantis tekstas turi būti pašalintas, jei manoma, kad jame nėra specialiųjų simbolių. Pateikiant teksto reikšmes į SQL, jos turi būti pašalintos pagal SQL taisykles. Pateikiant teksto reikšmes į HTML, jos turi būti pašalintos pagal HTML taisykles. Pateikiant teksto reikšmes (technologijos pavadinimas), jos turi būti pašalintos pagal (technologijos pavadinimo) taisykles. Tai viskas. Be abejo, yra ir kitų būdų, kaip elgtis su vartotojo įvestimi, kurioje gali būti arba nebūti specialiųjų simbolių.
  • Patvirtinimas
    Galite patikrinti, ar vartotojo įvestis atitinka tam tikras nurodytas specifikacijas. Jei reikia įvesti numerį, o vartotojas įveda ką nors kita, programa turi informuoti vartotoją ir atšaukti įvestį. Jei visa tai sutvarkyta teisingai, tada nėra pavojaus sugauti „DROP TABLE vartotojus“, kur vartotojas turėjo įvesti „42“. Tai nėra labai praktiška norint išvengti HTML/SQL injekcijų, nes... Dažnai reikia priimti laisvo formato tekstą, kuriame gali būti gudrybių. Paprastai patvirtinimas naudojamas kartu su kitomis priemonėmis.
  • Dezinfekavimas
    Taip pat galite „tyliai“ pašalinti visus simbolius, kuriuos laikote pavojingais. Pavyzdžiui, tiesiog pašalinkite viską, kas atrodo kaip HTML žyma, kad nebūtų įtraukta į forumą. Problema ta, kad galite pašalinti visiškai legalias teksto dalis.
    Parengti SQL sakiniai
    Yra specialios funkcijos, kurios daro tai, ko norėjome: leidžia duomenų bazei suprasti skirtumus tarp pačios SQL užklausos ir vartotojų pateiktos informacijos. PHP jie atrodo maždaug taip:
    $stmt = $pdo->prepare("SELECT telefono_numeris FROM vartotojai WHERE vardas =?"); $stmt->vykdyti($_POST["vardas"]);
    Šiuo atveju siuntimas vyksta dviem etapais, aiškiai atskiriant užklausą ir kintamuosius. Duomenų bazė turi galimybę pirmiausia suprasti užklausos struktūrą ir tada užpildyti ją reikšmėmis.

  • Realiame pasaulyje jie visi naudojami kartu skirtingiems apsaugos lygiams. Visada turėtumėte naudoti patvirtinimą, kad įsitikintumėte, jog vartotojas įveda teisingus duomenis. Tada galite (bet neprivalote) nuskaityti įvestus duomenis. Jei vartotojas aiškiai bando jums parduoti kokį nors scenarijų, galite jį tiesiog ištrinti. Tada visada turėtumėte pabėgti nuo vartotojo duomenų prieš įdėdami juos į SQL užklausą (tas pats pasakytina ir apie HTML).

3.1 Pabėgimas nuo specialiųjų simbolių

Prieš perduodant formos kintamųjų reikšmes į SQL užklausas, turite specialiai pašalinti kai kuriuos jose esančius simbolius (ypač apostrofą), pavyzdžiui, prieš juos įdėti pasvirąjį brūkšnį. Įterpimo funkcija yra tokia:

mysql_escape_string()

eilutė mysql_escape_string(eilutė $str)

Funkcija panaši į kitą addslashes() funkciją, tačiau ji prideda pasviruosius brūkšnius prieš išsamesnį specialiųjų simbolių rinkinį. Praktika rodo, kad tekstiniams duomenims galite naudoti funkciją addslashes() vietoj mysql_escape_string(). Tai daroma daugelyje scenarijų.

Pagal MySQL standartą simboliai, kurie PHP parašyti taip: "\x00", "\n", "\r", "\\", """, "" ir "\x1A" yra pabėgę.

Šis skaičius apima simbolį, kurio ASCII kodas yra nulis, todėl mysql_escape_string() gali būti naudojamas ne tik tekstui, bet ir dvejetainiams duomenims. Pavyzdžiui, galite perskaityti GIF vaizdą į kintamąjį (funkcija file_get_contents()) ir įterpti jį į duomenų bazę, prieš tai pašalinę visus specialiuosius simbolius. Ištraukus vaizdas bus rodomas tokia pačia forma, kokia buvo iš pradžių.

Pabėgimas nuo simbolių yra tik būdas parašyti teisingas SQL išraiškas, nieko daugiau. Duomenims nieko nenutinka, o jie saugomi duomenų bazėje be papildomų pasvirųjų brūkšnių – taip, kaip atrodė iš pradžių, net prieš pabėgant.

Naudojant mysql_escape_string(), ankstesnis užklausos kodas atrodo taip:

"DELETE FROM FROM table WHERE name="".mysql_escape_string($vardas).""");

Jis ilgas, gremėzdiškas ir bjaurus.


3.2 Užklausų šablonai ir rezervuotos vietos

Apsvarstykime kitą sprendimą.

Užuot aiškiai pašalinus ir įterpus kintamuosius į užklausą, jų vietoje dedami specialūs žymekliai (vietų žymekliai), paprastai atrodo kaip ?.

Tos pačios vertės, kurios bus pakeistos jas, perduodamos atskirai, papildomų parametrų.

Naudojant hipotetinę funkciją mysql_qwo, kurios kodas bus pateiktas žemiau, ankstesnę užklausą galima perrašyti taip:

mysql_qw("TRINTI IŠ lentelės WHERE vardas=?", $vardas);

Užklausa tapo trumpesnė ir geriau apsaugota: dabar, rašydami kodą, negalėsime netyčia praleisti mysql_escape_string() funkcijos iškvietimo ir tokiu būdu užklupti įsilaužėlių triuką. Visos transformacijos vyksta automatiškai, funkcijos viduje.

lib_mysql_qw.php sąraše yra paprasčiausias įgyvendinimas mysql_qw() funkcijos (qw - iš anglų kalbos užklausos įvynioklis, "query wrapper").

Taip pat yra biblioteka lib/Placeholder.php, kuri teikia daug galingesnį vietos žymenų kalbos palaikymą: http://dklab.ru/chicken/30.html.

Daugeliu atvejų pakanka funkcijos mysql_qw() teikiamų galimybių.

Sąrašas lib_mysql_qw.php

mob_info