Testaa menestystä php. Testitehtävä PHP-kehittäjälle koeajalla. js-skriptin luominen

Tämä on edullinen ja turvallinen tapa maksaa tavaroista ja palveluista verkossa. Lisää tämän järjestelmän prosessori verkkokauppaasi ja hyväksy maksut viipymättä.

Päivitetyn Yandex.Money 3.0 -protokollan avulla voit käyttää erilaisia ​​maksutyyppejä:

  • Itse asiassa Yandex rahaa;
  • Pankkikortit;
  • Maksut päätteiden kautta;
  • Mobiilimaksut.
Lisäksi menettely alustalle luotujen myymälöiden yhdistämiseksi 1C-Bitrix: Sivustonhallinta, Yanedexille. Rahaa on yksinkertaistettu huomattavasti. Sinun on jätettävä pyyntö Yandex.Money-verkkosivustolle (ilmoita kommentissa, että verkkosivustosi on päällä protokollaversiolla 3.0.) ja täytä yksinkertaistettu lomake (joka koostuu vain kolmesta kentästä).

Uuden Yandex.Money-protokollan yhdistämiseksi verkkokauppaan 1C-Bitrix-alustalla sinun on luotava uusi maksujärjestelmä ja valittava prosessori

Tarkista, onko sivustosi responsiivinen https-protokollan avulla. Tämä on edellytys Yanedex.Money 3.0 -protokollaa käyttävien maksujen hyväksymiselle.

Voit käyttää itse allekirjoitettua SSL-varmennetta tai Virtuaalikonetta, jossa kaikki on jo määritetty.

Osoita seuraavaksi Kaupan tunnus keskuskäsittelykeskuksessa, Näytön ikkunanumero keskuskäsittelykeskuksessa, joka sinun on saatava Yandexiltä sopimusta tehdessäsi, ja Kaupan salasana (shopPassword) myymälän Yandex-profiilista.

Jokaiselle maksutyypille on luotava oma prosessori ja valittava vaadittu maksutyyppi.

Testaaksesi maksua sinun on laitettava arvo "Y" kenttään Testitila. Kun lähetät hakemuksen liittyäksesi Yandex.Money 3.0 -protokollaan, saat erityisen linkin, jonka avulla voit täydentää lompakkosi saldoa testiä varten 1000 ruplalla.

Verkkokauppa-moduulin asetuksissa voit määrittää uudelleen polut sivuille, joilla on viesti onnistuneesta maksusta tai virheestä.

Kaikki. Asennus on valmis

Asiakkaiden, jotka ovat yhdistäneet edellisen Yandex.Money-version (1.6), ei tarvitse päivittää versioon 3.0. Nuo. molempia versioita tukevat sekä Yandex.Money että 1C-Bitrix: Site Management. MUTTA versio 1.6 ei lisää mahdollisuutta käyttää muita maksuja kuin Yandex.Money. Tämän maksujärjestelmän uudet asiakkaat yhdistetään protokollalla 3.0.

Tuotteiden toimituksessa 1C-Bitrix: Sivuston hallinta Yandex.Money-prosessori (3.0) julkaistaan ​​verkkokaupan (alennus) -moduulin versiossa 14.0.0. Ennen kuin tämä päivitys julkaistaan ​​(oletamme sen julkaistavan alfaversiona kuun lopussa), käsittelijää voidaan pyytää teknisen tuen kautta.

Nykyaikaisella web-aikakaudella useimmat verkkosivustot ovat yhä interaktiivisempia. Jos aiemmin päivitettyjen tietojen vastaanottamiseksi piti päivittää koko sivu, niin nyt on ilmestynyt teknologioita, joiden avulla emme lataa koko sivua, vaan vain yksittäisen osan siitä. Tämä puolestaan ​​tarjoaa mukavuutta sekä käyttäjille että palvelimen omistajille, koska sivu latautuu nopeammin käyttäjälle, koska vain erillinen osa sivusta latautuu, eikä palvelimen tarvitse luoda sivua joka kerta ja antaa sitä käyttäjä. Nämä ominaisuudet on helppo ottaa käyttöön php:n ja ajaxin avulla.

Tänään tarkastelemme pientä esimerkkiä ymmärtääksemme paremmin, kuinka AJAX-konsepti toimii. Joskus aloittelijan on vaikea ymmärtää, kuinka php ja ajax toimivat keskenään, monet ihmiset etsivät esimerkkejä siitä, kuinka lomakkeita voidaan vahvistaa ilman koko sivua. Näytän lyhyesti, kuinka tämä tehdään, jotta ymmärrät perusasiat ja periaatteet, joiden avulla voit nopeammin hallita muita työkaluja ja kirjoittaa omia skriptejäsi tulevaisuudessa.

Keksitään itselle pieni tehtävä, tarkistamme sähköpostiosoitteen olemassaolon tietokannassa lataamatta sivua uudelleen php:n ja ajaxin avulla. Tämä esimerkki osoittaa hyvin, kuinka voimme olla vuorovaikutuksessa palvelimen kanssa lataamatta sivua uudelleen selaimeen, ja tätä käytetään usein myös erilaisiin käyttäjälomakkeiden tarkistuksiin. Luomme juurihakemistoon 3 tiedostoa nimeltä index.php, email.php, validite.js.

Sivun luominen

Luodaan yksinkertainen sivu yhdellä lomakkeella, joka sisältää vain yhden kentän sähköpostin kirjoittamista varten.
Index.php-tiedoston syntaksi

AJAX opetusohjelma

Helpoin tapa työskennellä AJAXin kanssa on yhdistää jQuery-kehys, kuten tein. jQuery tarjoaa meille helposti ymmärrettävän ja helppokäyttöisen syntaksin AJAX-pyyntöjen lähettämiseen, joten miksi et hyödyntäisi sitä?

js-skriptin luominen

Valite.js-tiedoston syntaksi

$(dokumentti).ready(function())( var email = ""; $("#email").keyup(function())( var value = $(this).val(); $.ajax(() type: "POST", url:"email.php", data:"email="+value, success:function(msg)( if(msg == "valid")( $("#message").html( "Tätä sähköpostia voidaan käyttää. Tämä sähköposti on jo varattu." ) ) )); $("#submit"). "Ole hyvä ja laita tiedot kaikkiin sähköpostiin")else( $.ajax(( type: "POST", url:"email.php", data:"add_email="+email, success:function(msg)( $) ("#viesti" ).html(msg ) ));

PHP-käsittelijä

Tämä komentosarja vastaanottaa POST-pyynnön asiakkaalta, käsittelee sen ja palauttaa tuloksen. AJAX lukee tuloksen ja tekee päätöksen sen perusteella.
Email.php-tiedoston syntaksi

$yhteys = mysqli_connect("localhost","sähköposti","sähköposti","sähköposti"); if(isset($_POST["sähköposti"]) && $_POST["sähköposti"] != "")( $sähköposti = $_POST["sähköposti"]; $sähköposti = mysqli_real_escape_string($yhteys,$sähköposti); if (!filter_var($sähköposti, FILTER_VALIDATE_EMAIL))( echo "virheellinen"; )else( $sql = "VALITSE ID sähköpostiSTA WHERE email="$sähköposti""; $tulos = mysqli_query($yhteys,$sql); if( mysqli_num_rows($result) == 1)( echo "invalid"; )else( echo "valid"; ) ) ) if(isset($_POST["lisää_sähköposti"]) && $_POST["lisää_sähköposti"] != "" )( $sähköposti = mysqli_real_escape_string($yhteys,$_POST["lisää_sähköposti"]); $sql = "LISÄÄ sähköpostiin(sähköpostiin) VALUES("$sähköposti")"; if(mysqli_query($yhteys,$sql))( echo Success"; )else( echo "Error"; ) )

PHP-skriptissämme yleisin koodi, joka käsittelee julkaisupyynnön ja tulostaa tietyn tekstin sivulle. Tämän seurauksena AJAX lähettää pyynnön php-skriptille, komentosarja käsittelee sen ja tuottaa tuloksen, AJAX lukee tuloksen ja muuttaa sivua reaaliajassa.

AJAX lähettää POST-pyynnön komentosarjalle käyttämällä tätä koodinpätkää:

$.ajax(( type:"POST", url:"email.php", data:"email="+arvo, menestys:funktio(msg)( if(msg == "kelvollinen")( $("#viesti ").html("Tätä sähköpostia voidaan käyttää."); email = value; )else( $("#message").html("Tämä sähköposti on jo varattu."); ) ) ));

tyyppi - Pyynnön tyyppi, POST tai GET. Meidän tapauksessamme POST;
url - sen komentosarjan osoite, johon pyyntö lähetetään;
tiedot - tiedot, jotka lähetetään pyynnössä;
menestys - mitä tehdä onnistuneen pyynnön suorittamisen seurauksena. Meidän tapauksessamme funktiota kutsutaan;

Itse skriptissä sähköpostin läsnäolo tietokannassa tarkistetaan aina, kun sähköpostikenttään syötetään merkki. Skriptissä osio $("#email").keyup(function()()); , joka tarkistaa näppäimen painalluksen kentässä, jossa on id = "email" .
Kuten näette, koodi on melko yksinkertainen eikä vaadi erityisen suuria taitoja ymmärtääkseen, kaikki on sidottu tapahtumien käsittelyyn keyup() - näppäimen painallus, click() - hiiren klikkaus elementillä. Tätä seuraa AJAX-pyyntö ja vastaus komentosarjasta. Siten käyttämällä php:tä ja ajaxia saat lähes rajattomat mahdollisuudet luoda interaktiivisia sivuja.
Tämä koodi ei väitä olevan korkealaatuista, mutta jos kehität sen, lisäät oikeat validoinnit asiakas- ja palvelintasolla ja otat käyttöön css:n, niin sitä voidaan käyttää projekteissasi.
Jos sinulla on kysyttävää, älä epäröi kirjoittaa kommentteja.
Toivotan sinulle mukavaa päivää ja nähdään pian :)

7.4K
Tässä artikkelissa kuvailen AJAX-lomakkeen luomista ja lähettämistä. Tämän jälkeen voimme tarkastella animaation toteuttamista animate.css:llä ja tietojen validointia JavaScriptillä.

Tätä artikkelia kirjoitettaessa Bootstrap 3.3.5 on kehyksen nykyinen versio. Tässä artikkelissa käytämme oletusarvoista Bootstrap-koontiversiota (12 saraketta). Kun suoritat tämän artikkelin tehtäviä, muista käyttää uusimpia katkelmia ja koodirakennetta, jotka on kuvattu Bootstrap-dokumentaatiossa.

Tiedosto- ja kansiorakenne

Luomme juurihakemiston ja lisäämme siihen seuraavat tiedostot ja kansiot:

Bootstrap-lomake:


Meidän on yhdistettävä joitain käyttöliittymäkirjastoja:
  • Bootstrap ;
  • jQuery.

Kun nämä kirjastot otetaan huomioon, tiedostorakenne näyttää tältä:

Bootstrap-lomake:

Lomakkeen luominen

Avaa index.html-tiedostosi ja kopioi siihen seuraava AJAX-yhteyslomakkeen perusrakenne:

Yhteydenottolomake Bootstrap 3.3.4:llä " Lähetä minulle viesti

Tämä on HTML-perusmalli, johon lisäämme lomakkeen sisällön. Olemme sisällyttäneet kaikki tarvittavat CSS- ja JavaScript-tiedostot. Huomaa, että tässä esimerkissä emme tarvitse bootstrap.js-tiedostoa.

Olemme sisällyttäneet Bootstrapiin näkymän sisällönkuvauskentän mediakyselyille. JavaScript sijoitettiin tiedoston alaosaan niin, että pääkoodi käsiteltiin ensin.

Olemme sisällyttäneet body-tunnisteeseen div, jonka luokka on col-sm-6 col-sm-offset-3 . Tämä tarkoittaa, että haluamme näyttää 50 % leveän sarakkeen (pienen) näkymäikkunan sisällä ja päällä (enintään 12 saraketta). Luokka col-sm-offset-3 asettaa vasemman poikkeaman arvoon 25 %.

Tämä luo asettelun, joka vie puolet käytettävissä olevasta tilasta ja on vaakasuoraan keskitetty. Sen jälkeen sisällytimme h3:n ja seuraavaksi tulee lomakkeen pohja. Varmista, että käytät lomakkeeseen tunnuksen, jotta voit myöhemmin liittää siihen AJAX JQuery -lomakkeen lähetystapahtuman:

Ilman taistelua ei ole voittoa

Nimi Sähköposti Viesti Lähetä Viesti lähetetty!

Nämä ovat kaikki syöttökentät ja painikkeet, joita käyttäjä voi käyttää. Ensimmäinen div, johon on määritetty riviluokka, on klassinen Bootstrap-syntaksi, joka edustaa col-elementtien vaakasuoraa ryhmittelyä. Bootstrapin sarakkeet luovat täyttöjä tai välilyöntejä. Poistamalla ne voit varmistaa, että siima sopii tasaisesti säiliöön.

Loimme kaksi saraketta luokalla col-sm-6 (50%), joita käytämme lomakkeen yläosan erottamiseen. Ensimmäiseen sarakkeeseen col-sm-6 olemme luoneet tunnisteen ja kentät nimelle ja sähköpostiosoitteelle. Jokainen niistä sisältää tunnisteen, jossa on vastaava for-attribuutti, joten tunniste liittyy vastaavaan kenttään.

Jokainen näistä sarakkeista sisältää lomakeryhmän, joka ryhmittelee tunnisteet semanttisesti luomalla pienen täytteen alareunaan:

Typografia

Bootstrapin avulla voit käyttää luokkia H1-H6. Niiden avulla voit muotoilla upotettuja elementtejä lisäämättä kenttiä tai luomatta super-AJAX-yhteyslomakkeen elementtilohkoja. Käytimme H4-luokkaa tarrojen muotoiluun ja suureksi tekemiseen.

Form-control-luokkaa sovelletaan jokaiseen syöttöelementtiin siten, että se täyttää säiliön koko leveyden (100 % leveys). Tämä luokka lisää myös erilaisia ​​tyylejä, joiden avulla voit luoda helposti luettavan lomakeelementin (iso koko, selkeät reunat jne.).

Näiden sarakkeiden jälkeen lisäämme viestin tekstiosan. Käärimme sen lomakeryhmään ja käytämme samoja tyylejä kuin tarroissa ja tekstikentissä.

Kehotus toimintaan

Luodaan lähetyspainike. Bootstrap sisältää luokat eri painikkeille ja niiden tiloille. Päätimme käyttää onnistumispainiketta (btn-success), joka on oletuksena vihreä.

Sinun on myös käytettävä btn-perusluokkaa nollataksesi painikkeen perusparametrit (reuna, täyttö, tekstin tasaus, kirjasinkoko). Olemme käyttäneet btn-lg-luokkaa, joka luo suuren painikkeen, ja sitten vedä oikealle -luokkaa, joka saa painikkeen kietomaan vasemmalle.

Painikkeen jälkeen lisäsimme div-tunnuksen #msgSubmit ja käytimme seuraavat luokat: "h3 text-center piilotettu". H3-luokka auttaa luomaan suuremman otsikon, tekstikeskus asettaa tekstin tasauksen keskelle ja piilotetut joukot näyttävät: ei mitään ja näkyvät: piilotettu:

Lisätään toimintoja tietojen lähettämiseen

Olemme luoneet Bootstrap JQuery AJAX -peruslomakkeen, mutta se ei tee vielä mitään. Seuraava askel on luoda funktio, joka ottaa käyttäjän syötteen ja lähettää sen asynkronisesti PHP:lle.

Avaa scripts.js-tiedosto ja kopioi siihen seuraava koodi:

$("#contactForm").submit(function(event)( // peruuttaa lomaketietojen toimituksen event.preventDefault(); submitForm(); ));

Tämä on osa JQuery-koodia, joka kuuntelee #contactForm-tietojen lähetystoimintoja (kuten aiemmin mainittiin). Ennen tätä funktiota käsittelemme tapahtumamuuttujan, joka tallentaa funktion lomakkeen lähetystoiminnon.

event.preventDeafult() lopettaa lomaketietojen lähettämisen, kun sivu päivitetään valitsematta lomakkeelle toimintoa. Ja lopussa tämä koodi pyytää funktiota submitForm(); :

funktio submitForm())( // Aloita muuttuja lomakkeen var name = $("#name").val(); var email = $("#email").val(); var message = $("#message ").val(); $.ajax(( tyyppi: "POST", url: "php/form-process.php", data: "name=" + nimi + "&email=" + sähköposti + "&message=" + viesti, menestys: function(teksti)( if (teksti == "menestys")( formSuccess(); ) ) ) funktio formSuccess())( $("#msgSubmit").removeClass("piilotettu ");)

Kolme kutsuttua muuttujaa keräävät kunkin lomakkeen syöttökentän arvot ja välittävät ne JavaScript-muuttujalle myöhempää käyttöä varten.

Aloitamme AJAX-objektin JQueryn sisällä ja asetamme parametrit postille, PHP-tiedoston sijainnin, lähetettävän datan ja takaisinsoittotoiminnon. Tiedot sisältävät kaikki kolme muuttujaa vastaavalla tunnuksella. Takaisinsoittotoiminto kutsutaan, kun AJAX-objekti on onnistuneesti vastaanottanut tiedot PHP-skriptistä. Funktio nappaa palautetun tekstin ja tarkistaa, onko se yhtä suuri kuin merkkijono "onnistuminen". Jos kyllä, lopullinen formSuccess-funktio suoritetaan.

Se poistaa piilotetun luokan #msgSubmit DIV -elementistä, jota käytimme aiemmin, ja tulostaa näin tekstin.

Yhdistetään PHP Mail -toimintoon

Nyt sinun on kirjoitettava komentosarja, joka vastaanottaa tiedot AJAX-lomakkeesta ja lähetettävä sisältö PHP Mail -toiminnon kautta. Avaa process.php-tiedosto ja lisää siihen seuraava koodi:

Meidän on tallennettava muuttujat, joita haluamme käyttää. Postitoiminnosta saat kolme syöttömuuttujaa ja anna niille samat nimet PHP:ssä. $EmailTo-muuttuja on sähköpostiosoite, joka voidaan asettaa komentosarjassa. $Subject on merkkijono, joka kuvaa sähköpostin aihetta.

Kirjeen runko luodaan satunnaisesti lisäämällä kolme luotua muuttujaa. Ensin asetetaan kuvausteksti, esimerkiksi "Nimi:", sitten tulee muuttuja ja sitten rivinvaihto (/n). Toistamme samat vaiheet sitomalla kaikki tiedot $body-muuttujaan.

Sähköpostin lähettämistä varten liitämme sen sähköpostitoimintoon. Määrittämällä arvon $success-muuttujalle määritämme sähköpostiosoitteen, johon sähköposti lähetetään, sähköpostin aiheen, tekstin ja lähettäjän sähköpostiosoitteen.

Sähköpostin lähetysprosessin aloittamiseksi sinun on kutsuttava se if-lausekkeessa. Näin voit tarkistaa, onko lomaketietojen lähetys onnistunut vai ei. Jos Mail-funktio palauttaa "true", komentosarja palauttaa "success", jos funktio antaa virheen, palautetaan "invalid".

Tämä tulos palautetaan AJAX-objektiin ja käsitellään asiakaspuolella. AJAXin etuna on, että se kaikki tehdään asynkronisesti asiakaspuolella. Näin käyttäjä voi jatkaa vuorovaikutusta sivuston kanssa, kun AJAX-lomake lähettää tietoja:

Loistakaamme

Keskitymme nyt antamaan käyttäjille palautetta useiden lisäominaisuuksien avulla, jotka voidaan ottaa käyttöön. Tarkastelemme erityisesti lomakepalautetta virheenkäsittelyä käyttäen sekä asiakas- että palvelinpuolella.

Käytämme myös joitain työkaluja lomakkeen vahvistamiseen:

  • Animate.css: ;
  • Bootstrap Validator.

Lisää ne projektiisi kuten teimme aiemmin Bootstrapin ja JQueryn kanssa. Nämä työkalut auttavat antamaan palautetta käyttäjälle tietojen lähettämisen jälkeen.

Projektin rakenteen pitäisi nyt näyttää tältä:

Lomakkeen validointi

Aloitetaan asentamalla validaattori AJAX PHP -yhteyslomakkeen tietojen syöttämisen jälkeen. Siirry scripts.js-tiedostoon ja muokkaa ensimmäistä koodinpätkää, joka kutsuu SubmitForm()-funktiota lomaketietojen lähettämisen jälkeen.
Se on muutettava seuraavasti:

$("#contactForm").validator().on("submit", function (event) ( if (event.isDefaultPrevented()) ( // käsittele lomakevirhettä... ) else ( // kaikki on kunnossa! tapahtuma .preventDefault();

Tämä uusi koodinpätkä tarkistaa, onko Bootstrap Validator löytänyt ongelmia ja pysäyttänyt koodin suorittamisen. Jos ei, jatkamme normaalisti. Meidän on silti suljettava pois oletustoiminto (sivun lataaminen uudelleen täyttämättä lomaketta) lomakkeen tietojen lähetysskriptistä.

Jos nyt napsautamme lähetä lomake -painiketta täyttämättä kaikkia kenttiä, tyhjät korostetaan punaisella:


Poistimme alkuperäisen HTML5-tarkistuksen käytöstä vahvistuksen lisäämisen aikana. Voit lisätä vahvistukseen lisäkontekstia lisäämällä virheilmoituksia. Bootstrap Validatorissa on kätevä ominaisuus, jonka avulla voit näyttää virheilmoitukset jokaiselle kentälle. Jotta voit lisätä ne, sinun on suoritettava HTML-merkintä.

Jokaisen lomakeryhmän sisällä, tietojen syöttökentän alle, sinun on sijoitettava seuraava HTML-koodi:

Esimerkkinä alla on ylimääräinen div lisätty nimi- ja sähköpostikenttiin:

Nimi Sähköposti

Nyt kun lähetät AJAX JQuery -lomaketietoja uudelleen, näyttöön tulee virheilmoitus, jos lomakkeen kenttiä ei ole täytetty: "Täytä tämä kenttä. " Lisäämällä syötetietoihin data-attribuutin nimeltä "data-error", voit sisällyttää mukautetun virheilmoituksen.

Esimerkiksi:

Palaute-animaatioiden lisääminen

Olemme lisänneet toimintoja tyhjien lomakekenttien ilmaisemiseen. Mutta olisi mukavaa lisätä lomakkeeseen ylimääräistä animaatiota ja viestejä, jotka kertovat käyttäjälle, mitä tapahtuu. Tällä hetkellä, kun lomakkeen tiedot on lähetetty onnistuneesti, viesti "Viesti lähetetty! "mutta entä virheet?

Jotta voimme hyödyntää olemassa olevaa koodia, muokkaamme olemassa olevaa tietojen toimittamisen onnistumisviestiä. Ensinnäkin poistetaan teksti "Viesti lähetetty! " HTML-merkinnöistä ja jätä div tyhjäksi:

Nyt meidän on luotava uusi toiminto käsittelemään viestin tilaa. Lisää tämä toiminto scripts.js-tiedoston alaosaan:

function submitMSG(valid, msg)( var msgClasses; if(valid)( msgClasses = "h3 text-center tada animated text-success"; ) else ( msgClasses = "h3 text-center text-vaara"; ) $("# msgSubmit").removeClass().addClass(msgClasses).text(msg); )

Tämä funktio ottaa kaksi argumenttia. valid on looginen muuttuja: jos sen arvo on tosi, näyttöön tulee viesti, joka ilmoittaa, että tiedot on lähetetty onnistuneesti. Jos epätosi, tulostetaan virheilmoitus. msg on viesti, jonka näytämme div-lohkossa.

Tämä toiminto tarkistaa, onko kyseessä ilmoitus onnistuneesta tiedonsiirrosta vai virheilmoitus. Tämä tehdään tarkistamalla muuttujan valid arvo. Joka tapauksessa se asettaa muuttujan sopivilla CSS-luokilla (meidän on sisällytettävä h3 ja text-center uudelleen, koska poistamme ne).

Huomautus: Menestysviestiluokassa käytämme joitain animate.css-luokkia. Kun AJAX JQuery -yhteyslomakkeen tiedot on lähetetty onnistuneesti, toistetaan tada-animaatio.

Lopuksi funktio poistaa kaikki luokat #msgSubmitista (luokkien päällekkäisyyden välttämiseksi) ja asettaa sitten prioriteettiluokat ja lisää viestin tekstin div-kenttään.

Päivitämme tämän osion alussa olevan validaattorin alustuksen sisällä koodin lisäämään kutsun seuraavaan funktioon if-lauseen sisällä, kun sen arvo on tosi:

sendMSG(false, "Täytitkö lomakkeen oikein?");

Jos et ole nyt täyttänyt kaikkia kenttiä, saat virheilmoituksen ”Täytitkö lomakkeen oikein? »

Tämän uuden submitMSG-toiminnon viimeinen vaihe on kutsua sitä, kun lomaketiedot on lähetetty onnistuneesti. Päivitä formSuccess()-funktio seuraavasti:

$("#contactForm").reset(); sendMSG(true, "Viesti lähetetty!")

Haluamme nollata lomakkeen ja tyhjentää arvot, kun kutsumme submitMSG-toimintoa, kuten yllä on ilmoitettu onnistuneen lähetyksen viestissä. Nyt, kun lomaketiedot on lähetetty onnistuneesti, vastaava viesti, jossa on animaatio.css tada -animaatio, pitäisi näkyä:

Ravistellaan itseämme

Lisätään koko lomakkeeseen bugi-animaatio, yleisen "ravistelevan" animaation pitäisi tehdä temppu!

Luo uusi funktio heti formSuccess() jälkeen ja kutsu sitä formError() :

function formError())( $("#contactForm").removeClass().addClass("shake animated").one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend", function())( $(this).removeClass(); )) ;)

Tämä toiminto käyttää animate.css-esittelysivulla kuvattua lähestymistapaa, jonka avulla voit lisätä elementtiin animaation ja kutsua sen sitten uudelleen.

CSS-animaatiossa on valitettava ominaisuus: sitä ei voida toistaa uudelleen, vaikka luokka poistetaan ja lisätään uudelleen. Tämä toiminto auttaa nollaamaan animaation lopun luokat, jotta voit lisätä ne uudelleen. Kun käyttäjä napsauttaa "Lähetä"-painiketta täyttämättä kaikkia AJAX-palautelomakkeen kenttiä, toistamme tärinäanimaatiota. Ja jos se ei täytä kaikkia kenttiä uudelleen, sinun on toistettava tämä animaatio uudelleen.

Voit kutsua tätä formError()-funktiota sen submitMSG()-funktion yläpuolella, jonka loimme ilmoittamaan virheestä. Esimerkiksi näin:

formError(); sendMSG(false, "Täytitkö lomakkeen oikein?");

Nyt, kun käyttäjä yrittää lähettää lomakkeen tiedot täyttämättä kaikkia kenttiä, se tärisee ilmoittaen hänelle, että jotain on vialla.

Lisää validointia

Asiakaspuolen validointi on hyvä, mutta kuka tahansa käyttäjä voi poistaa sen käytöstä ja lähettää tyhjät kentät sisältävän lomakkeen muokkaamalla koodia selaimessa. Palvelinpuolelle on luotava validointipalvelu.

Meidän on avattava process.php-tiedosto ja tehtävä tarvittavat muutokset varmistaaksemme, että kaikki kentät on tarkistettu. Luomme $errorMSG-muuttujan virheilmoitusten havaitsemiseksi ja otamme sitten käyttöön ylimääräisen $_POST-tarkistuksen:

Tämä PHP-koodi tarkistaa, onko tyhjiä AJAX-lomakekenttiä olemassa, ennen kuin niiden tiedot asetetaan vastaaviksi muuttujiksi (korvataan olemassa olevat koodilla määritetyt muuttujat $_POST:sta). Jos kentät ovat tyhjiä, määritämme yleisen viestin, joka lähetetään takaisin asiakkaalle.

Vastauksena alkuperäiseen AJAX-kutsuun meidän on lähetettävä virheviesti, joka näkyy selaimessa. Voit tehdä tämän muokkaamalla aiemmin luomaamme if-lausetta PHP-koodin alareunassa:

Tarkistamme if-lauseen avulla, onko $errorMSG-muuttuja tyhjä (“”), sekä $success-muuttujalle käyttämämme sisäänrakennetun sähköpostitoiminnon tilan. Muuhun ehtoon olemme lisänneet lisätarkistuksen nähdäksemme, johtuuko virhe epäonnistumisesta $success. Jos kyllä, lähetämme takaisin viestin "Jotain meni pieleen: ". Muussa tapauksessa näytämme viestin, joka käännettiin, kun tarkistimme tyhjiä kenttiä.

Ja viimeinen vaihe on hyväksyä uusi viesti AJAXissa ja näyttää se lomakkeessa. Meidän on päivitettävä AJAX-objekti scripts.js-tiedostossa seuraavasti:

$.ajax(( type: "POST", url: "php/form-process.php", data: "name=" + nimi + "&email=" + email + "&message=" + viesti, menestys: function( teksti)( if (teksti == "menestys")( muotoSuccess(); ) else ( formError(); lähetäMSG(false,text; ) ) ));

Olemme juuri päivittäneet else-ehdon, joka tarkistaa tekstin == onnistumisen. Toisessa kutsumme formError()-funktiota, joka käyttää tärinäanimaatiota ja pyytää submitMSG()-funktiota PHP:stä palautetun tekstin.

Johtopäätös

Siirry Githubiin nähdäksesi koko koodi. Nyt AJAX PHP -palautelomake antaa käyttäjälle tietoja siitä, mitä kenttiä hän ei ole täyttänyt. Tulostamme kontekstuaaliset viestit tilan ja PHP:stä palautetun viestin perusteella. Otimme myös käyttöön lisätason palvelinpuolen vahvistusta niille käyttäjille, jotka yrittävät ohittaa käyttöliittymän vahvistuksen.

Toivottavasti pidit tästä artikkelista. Jätä kysymyksesi ja palautteesi kommentteihin.

Tämä julkaisu on käännös artikkelista "Building a Bootstrap Contact Form using PHP and AJAX", jonka on laatinut ystävällinen projektitiimi


OWASP:n kymmenen yleisimmän hyökkäystyypin luettelossa kahdella ensimmäisellä sijalla ovat koodin lisäys- ja XSS-hyökkäykset (cross-site scripting). Ne kulkevat käsi kädessä, koska XSS, kuten monet muutkin hyökkäykset, riippuu injektiohyökkäysten onnistumisesta. Tämä nimi kätkee joukon hyökkäyksiä, joissa tietoja syötetään verkkosovellukseen pakottaakseen sen suorittamaan tai tulkitsemaan haitallista koodia hyökkääjän haluamalla tavalla. Näitä hyökkäyksiä ovat esimerkiksi XSS, SQL-injektio, otsikon lisäys, koodin lisäys ja Full Path Disclosure. Ja tämä on vain pieni osa.


Injektiohyökkäykset ovat kauhutarina kaikille ohjelmoijille. Ne ovat yleisimpiä ja menestyneimpiä niiden monimuotoisuuden, mittakaavan ja (joskus) suojaamisen vaikeuden vuoksi. Kaikkien sovellusten on saatava tiedot jostain. XSS ja UI Redress ovat erityisen yleisiä, joten omistin niille erilliset luvut ja erotin ne yleisestä luokasta.


OWASP tarjoaa seuraavan määritelmän injektiohyökkäykselle:


Injektiomahdollisuudet - kuten SQL, OS ja LDAP - tapahtuvat, kun tulkki vastaanottaa epäluotettavaa dataa osana komentopyyntöä. Haitalliset tiedot voivat huijata tulkin suorittamaan tiettyjä komentoja tai pääsemään luvattomiin tietoihin.

SQL-injektio

SQL-injektio on yleisin ja erittäin vaarallinen injektiohyökkäyksen muoto. Tämän uhan vakavuutta on vaikea yliarvioida, joten on erittäin tärkeää ymmärtää, mikä vaikuttaa hyökkäysten onnistumiseen ja miten niiltä suojaudutaan.


Joten tiedot ruiskutetaan verkkosovellukseen ja käytetään sitten SQL-kyselyissä. Ne tulevat tyypillisesti epäluotettavista syöttölähteistä, kuten verkkolomakkeista. Injektio voidaan kuitenkin tehdä myös muualta, vaikkapa itse tietokannasta. Ohjelmoijat uskovat usein tietokantansa täydelliseen turvallisuuteen ymmärtämättä, että jos se oli turvallista yhdessä tapauksessa, tämä ei tarkoita ollenkaan, että se olisi turvallista tulevaisuudessa. Tietokannan tietoja tulee pitää epäluotettavina, kunnes toisin todistetaan, eli kunnes ne on varmennettu.


Jos hyökkäys onnistuu, hyökkääjä voi manipuloida SQL-kyselyä niin, että se suorittaa tietokannassa toimintoja, joita kehittäjät eivät ole tarkoineet.


Katso tämä kysely:


$db = uusi mysqli("localhost", "käyttäjänimi", "salasana", "tallennettu b"); $tulos = $db->query("SELECT * FROM tapahtumista WHERE user_id = " . $_POST["käyttäjätunnus"]);

Täällä on useita jambeja. Ensinnäkin emme tarkistaneet POST-tietojen sisältöä varmistaaksemme, että user_id on oikea. Toiseksi, annamme epäluotettavan lähteen kertoa meille, mitä user_id-tunnusta käytetään: hyökkääjä voi luistaa minkä tahansa kelvollisen user_id-tunnuksen. Se on saatettu sisältyä piilotettuun kenttään lomakkeella, jota pidimme turvallisena, koska sitä ei voitu muokata (unohtamatta, että hyökkääjät voivat syöttää mitä tahansa tietoja). Kolmanneksi emme välttäneet user_id:tä emmekä välittäneet sitä pyyntöön sidottuina parametrina, mikä antaa hyökkääjälle myös mahdollisuuden syöttää mielivaltaisia ​​merkkijonoja, jotka manipuloivat SQL-kyselyä, koska emme voineet tarkistaa sitä alun perin. .


Nämä kolme puutetta ovat hyvin yleisiä verkkosovelluksissa.


Mitä tulee tietokantaan, kuvittele, että etsimme tapahtumia käyttäjän_nimi-kentän avulla. Nimet ovat laajoja ja voivat sisältää lainausmerkkejä. Oletetaan, että hyökkääjä on tallentanut syötetyn merkkijonoarvon johonkin käyttäjätunnukseen. Kun käytämme tätä arvoa uudelleen jossakin seuraavista kyselyistä, se manipuloi kyselymerkkijonoa, koska pidimme tietokantaa luotettavana lähteenä emmekä eristäneet tai rajoittaneet vaarantunutta kyselyä.


Kiinnitä huomiota myös toiseen SQL-toteutuksen tekijään: jatkuvaa tallennusta ei aina tarvitse säilyttää palvelimella. HTML 5 tukee asiakaspuolen tietokannan käyttöä, jossa voit lähettää kyselyitä SQL:n ja JavaScriptin avulla. Tätä varten on kaksi API:ta: WebSQL ja IndexedDB. Vuonna 2010 W3C ei suositellut WebSQL:n valitsemista; sitä tukevat WebKit-selaimet, jotka käyttävät SQLitea taustaohjelmana. Todennäköisesti tuki säilyy taaksepäin yhteensopivuuden vuoksi W3C:n suosituksesta huolimatta. Kuten nimestä voi päätellä, tämä API hyväksyy SQL-kyselyt, mikä tarkoittaa, että se voi olla injektiohyökkäysten kohde. IndexedDB on uudempi vaihtoehto, NoSQL-tietokanta (ei vaadi SQL-kyselyjen käyttöä).

Esimerkkejä SQL-injektiosta

SQL-kyselyiden käsittelyllä voi olla seuraavat tavoitteet:

  • Tietovuotoja.
  • Tallennettujen tietojen paljastaminen.
  • Tallennettujen tietojen manipulointi.
  • Valtuutuksen ohitus.
  • Asiakaspuolen SQL-injektio.
  • SQL-injektio suojaus

    Suojaus SQL-injektiota vastaan ​​perustuu echeloning-periaatteeseen. Ennen kuin käytät tietoja kyselyssä, sinun on tarkistettava, että sen muoto on oikea. Tiedot on myös eristettävä ennen kuin ne sisällytetään pyyntöön tai sisällytetään siirtymäparametriksi.

    Tutkimus

    Toistan sitä jatkuvasti: kaikki tiedot, joita ei ole nimenomaisesti luotu nykyisen pyynnön PHP-lähdekoodiin, ovat epäluotettavia. Tarkista ne tarkasti ja hylkää kaikki, jotka eivät läpäise tarkastuksia. Älä yritä "korjata" tietoja, vain pieniä, kosmeettisia muutoksia voidaan tehdä.


    Yleisiä virheitä ovat tietojen validointi jatkuvaa jatkuvaa käyttöä varten (kuten näyttö tai laskelmat) ja tietokannan kenttiä, joihin tiedot tallennetaan, validoimatta jättäminen.

    Suojaus

    Mysqli-laajennuksen avulla voit eristää kaikki SQL-kyselyyn sisältyvät tiedot. Mysqli_real_escape_string()-funktio tekee tämän. PostgresSQL:n pgsql-laajennus tarjoaa funktiot pg_escape_bytea() , pg_escape_identifier() , pg_escape_literal() ja pg_escape_string(). Mssql-laajennuksessa (Microsoft SQL Server) ei ole eristäviä toimintoja, ja addslashes()-lähestymistapa on tehoton - tarvitset mukautetun funktion.


    Vaikeuttaakseni elämääsi vieläkin, sanon, että sinulla ei ole oikeutta tehdä virhettä eristäessäsi pyyntöön syötettyjä tietoja. Yksi ohitus ja olet alttiina hyökkäyksille.


    Tee yhteenveto. Suojaus ei ole paras suojavaihtoehto. Sitä tulisi käyttää viimeisenä keinona. Sitä voidaan tarvita, jos abstraktioon käyttämäsi tietokantakirjasto mahdollistaa paljaiden SQL-kyselyjen tai kyselyn osien määrittämisen ilman, että parametreja on pakko sitoa. Muissa tapauksissa on parempi välttää eristäytymistä kokonaan. Tämä lähestymistapa on monimutkainen, virhealtis ja vaihtelee tietokantalaajennuksesta riippuen.

    Parametriset kyselyt (valmiit lausekkeet)

    Parametrisointi tai parametrien sidonta on suositeltava tapa luoda SQL-kyselyitä. Kaikki hyvät tietokantakirjastot käyttävät sitä oletuksena. Tässä on esimerkki PHP:n PDO-laajennuksen käytöstä:


    if(ctype_digit($_POST["id"]) && is_int($_POST["id"])) ( $validatedId = $_POST["id"]; $pdo = new PDO("mysql:store.db") $stmt = $pdo->prepare("SELECT * FROM tapahtumat WHERE user_id = :id" $stmt->bindParam(":id", $stmt->execute() ); // hylkää id-arvo ja ilmoita virheestä käyttäjälle )

    BindParam()-menetelmä, joka on käytettävissä PDO-lausekkeille, mahdollistaa parametrien sitomisen aiemmin valmistetun lausekkeen "paikkamerkkeihin". Tämä menetelmä hyväksyy perustietotyyppien parametrit, kuten PDO::PARAM_INT , PDO::PARAM_BOOL , PDO::PARAM_LOB ja PDO::PARAM_STR . Tämä on oletusarvo PDO::PARAM_STR:lle, ellei toisin mainita, joten muista myös muut arvot!


    Toisin kuin manuaalinen eristäminen, parametrien sidonta (tai mikä tahansa tietokantakirjastosi käyttämä menetelmä) eristää automaattisesti sidotut tiedot oikein, joten sinun ei tarvitse muistaa, mitä toimintoa käyttää. Myös johdonmukainen parametrien sidonta on paljon luotettavampaa kuin yrittää muistaa, että sinun on eristettävä kaikki manuaalisesti.

    Vähiten etuoikeuksien periaatteen täytäntöönpano

    Onnistuneen SQL-injektion lopettaminen on yhtä tärkeää kuin sen estäminen kokonaan. Kun hyökkääjä saa kyvyn suorittaa SQL-kyselyitä, hän tekee sen tietyn tietokannan käyttäjänä. Vähiten etuoikeuksien periaate voi varmistaa, että kaikilla käyttäjillä on vain ne oikeudet, jotka ovat ehdottoman välttämättömiä heidän tehtäviensä suorittamiseksi.


    Jos käyttäjällä on korkeat oikeudet, hyökkääjä voi pudottaa taulukoita ja muuttaa muiden käyttäjien oikeuksia suorittamalla uusia SQL-lisäyksiä heidän puolestaan. Jotta näin ei tapahdu, älä koskaan käytä tietokantaa verkkosovelluksesta pääkäyttäjänä, järjestelmänvalvojana tai muuna käyttäjänä, jolla on korkeat oikeudet.


    Toinen periaatteen sovellus on tietojen lukemisen ja tietokantaan kirjoittamisen roolien erottaminen. Valitse yksi käyttäjä, jolla on vain kirjoitusoikeudet, ja toinen, jolla on vain lukuoikeudet. Jos hyökkäys kohdistuu "lukevaan" käyttäjään, hyökkääjä ei voi käsitellä taulukon tietoja tai kirjoittaa niitä. Voit rajoittaa käyttöä vielä suppeammin, mikä vähentää onnistuneiden SQL-injektiohyökkäysten vaikutusta.


    Monet verkkosovellukset, erityisesti avoimen lähdekoodin sovellukset, on suunniteltu käyttämään vain yhtä tietokannan käyttäjää, jonka käyttöoikeustasoa ei läheskään varmasti koskaan tarkisteta. Joten älä unohda tätä kohtaa äläkä yritä suorittaa sovelluksia järjestelmänvalvojan tilillä.

    Koodin lisäys (tunnetaan nimellä Remote File Inclusion)

    Koodin lisäys on mikä tahansa tekniikka, jonka avulla hyökkääjä voi lisätä lähdekoodia verkkosovellukseen tulkitsemalla ja suorittamalla sitä. Tässä tapauksessa emme puhu koodin tuomisesta asiakasosaan, esimerkiksi JavaScriptissä täällä käytetään jo XSS-hyökkäyksiä.


    Voit syöttää lähdekoodin suoraan epäluotettavasta syöttölähteestä tai pakottaa verkkosovelluksen lataamaan sen paikallisesta tiedostojärjestelmästä tai ulkoisesta resurssista, kuten URL-osoitteesta. Kun koodia syötetään ulkoisen lähteen sisällyttämisen seurauksena, sitä kutsutaan yleisesti etätiedostojen sisällyttämiseksi (RFI), vaikka itse RFI on aina tarkoitettu syöttämään koodia.


    Tärkeimmät syyt koodin käyttöönotolle:

    • syötetietojen tarkistuksen ohittaminen,
    • epäluotettava syöte mihin tahansa kontekstiin, jossa sitä käsitellään PHP-koodina,
    • lähdekoodivarastojen tietoturvan hakkerointi,
    • poistaa käytöstä varoitukset kolmannen osapuolen kirjastojen lataamisesta,
    • palvelimen konfigurointi uudelleen siten, että se välittää ei-PHP-tiedostot PHP-tulkkiin.

    Kiinnitä erityistä huomiota viimeiseen kohtaan: tässä tapauksessa epäluotettavat käyttäjät voivat ladata mitä tahansa tiedostoja palvelimelle.

    Esimerkkejä koodin lisäämisestä

    PHP:llä on monia koodinsyöttökohteita, joten tämäntyyppiset hyökkäykset ovat kaikkien ohjelmoijien tarkkailulistan kärjessä.

    Sisältää tiedoston

    Ilmeisimpiä koodin lisäyksen kohteita ovat include() , include_once() , request() ja request_once() funktiot. Jos epäluotettavien syöttötietojen avulla voit määrittää näille funktioille välitetyn polkuparametrin, voit etäohjata sisällytettävän tiedoston. On huomattava, että mukana tulevan tiedoston ei tarvitse olla oikea PHP-tiedosto, jota voidaan käyttää (eli melkein ilman rajoituksia).


    Polku-parametri voi myös olla alttiina hakemiston läpikulku- tai etätiedostojen sisällyttämishyökkäyksille. Käyttämällä ../ tai... merkkiyhdistelmiä polussa hyökkääjä voi navigoida melkein mihin tahansa tiedostoon, johon PHP-prosessilla on pääsy. Samanaikaisesti PHP-oletuskokoonpanossa yllä olevat funktiot hyväksyvät URL-osoitteen, ellei allow_url_include ole poistettu käytöstä.

    Tutkimus

    PHP eval()-funktio hyväksyy suoritettavaksi rivin PHP-koodia.

    Säännöllisten lausekkeiden käyttöönotto

    PCRE (Perl Compatible Regular Expression) -funktio preg_replace() PHP:ssä hyväksyy e-muuntimen (PREG_REPLACE_EVAL). Tämä tarkoittaa korvaavaa merkkijonoa, jota vaihtamisen jälkeen pidetään PHP-koodina. Ja jos tällä rivillä on epäluotettava syöttö, he voivat syöttää suoritettavan PHP-koodin.

    Viallinen tiedostojen sisällyttämislogiikka

    Verkkosovellukset sisältävät määritelmän mukaan tiedostot, joita tarvitaan pyyntöjen palvelemiseen. Jos hyödynnät reitityslogiikan, riippuvuuden hallinnan, automaattisen lataamisen ja muiden prosessien vikoja, pyyntöpolun tai sen parametrien manipulointi pakottaa palvelimen sisällyttämään tiettyjä paikallisia tiedostoja. Koska verkkosovellusta ei ole suunniteltu käsittelemään tällaisia ​​manipulaatioita, seuraukset voivat olla arvaamattomia. Sovellus esimerkiksi paljastaa tahattomasti reitit, jotka on tarkoitettu käytettäväksi vain komentorivillä. Tai se paljastaa muita luokkia, joiden rakentajat suorittavat tehtäviä (luokkia on parempi olla suunnittelematta tällä tavalla, mutta näin tapahtuu silti). Mikä tahansa näistä skenaarioista saattaa häiritä sovelluksen taustatoimintoja, mikä mahdollistaa tietojen manipuloinnin tai DOS-hyökkäykset resurssiintensiivisiin toimiin, joihin ei liity suoraa pääsyä.

    Koodin lisäämisen haasteet

    Tehtävien valikoima on erittäin laaja, koska tämäntyyppinen hyökkäys mahdollistaa minkä tahansa hyökkääjän valitseman PHP-koodin suorittamisen.

    Suojaukset koodin injektiota vastaanCommand InjectionEsimerkkejä Command Injection -suojauksista Command InjectionLog Injection -syötöstä (tunnetaan nimellä lokitiedostojen lisäys)

    Monet sovellukset keräävät lokeja, ja valtuutetut käyttäjät tarkastelevat niitä usein HTML-käyttöliittymän kautta. Siksi lokit ovat yksi hyökkääjien tärkeimmistä kohteista, jotka haluavat peittää muita hyökkäyksiä, pettää niitä, jotka tarkastelevat lokeja, ja sitten jopa hyökätä sen valvontasovelluksen käyttäjiin, jolla lokit luetaan ja analysoidaan.


    Lokien haavoittuvuus riippuu lokin tallennuksen ohjausmekanismeista sekä lokitietojen käsittelystä epäluotettavana lähteenä lokeja tarkasteltaessa ja analysoitaessa.


    Yksinkertainen lokijärjestelmä voi kirjoittaa tekstiä tiedostoon käyttämällä file_put_contents() -funktiota. Esimerkiksi ohjelmoija kirjaa epäonnistuneet valtuutusyritykset seuraavan muotoisena merkkijonoina:


    sprintf("Epäonnistui %s:n kirjautumisyritys", $käyttäjänimi);

    Entä jos hyökkääjä käyttää lomakkeessa nimeä "AdminnSuccessful login by Adminn"?


    Jos tämä rivi lisätään lokiin epäluotettavista syöttötiedoista, hyökkääjä naamioi epäonnistuneen valtuutusyrityksen viattomalla epäonnistumisella järjestelmänvalvojan salasanan syöttämisessä. Tietojen epäluuloisuus vähenee entisestään, jos lisäät onnistuneen valtuutusyrityksen.


    Koko pointti tässä on, että hyökkääjä pystyy lisäämään lokiin kaikenlaisia ​​merkintöjä. Voit myös lisätä XSS-vektoreita ja jopa merkkejä, jotka vaikeuttavat lokimerkintöjen lukemista konsolissa.

    Lokin injektiotehtävät

    Yksi toteutuksen tavoitteista on lokimuotojen tulkit. Jos analyysityökalu käyttää säännöllisiä lausekkeita jäsentääkseen lokimerkinnät ja erottaakseen ne eri kenttiin, on mahdollista luoda ja lisätä merkkijono, joka saa säännöllisen lausekkeen valitsemaan lisätyt kentät oikeiden kenttien sijaan. Esimerkiksi tämä merkintä voi aiheuttaa useita ongelmia:


    $username = "iamnothacker! at Ma Jan 01 00:00:00 +1000 2009"; sprintf("Epäonnistunut kirjautumisyritys %s:lta %s", $käyttäjänimi,)

    Kehittyneemmät lokin lisäyshyökkäykset perustuvat hakemiston läpikäyntihyökkäyksiin, jotka näyttävät lokin selaimessa. Oikeissa olosuhteissa PHP-koodin lisääminen lokiviestiin ja lokitiedoston avaaminen selaimessa johtaa onnistuneeseen koodiin, joka on muotoiltu siististi ja suoritetaan hyökkääjän pyynnöstä. Ja jos kyseessä on haitallisen PHP:n suorittaminen palvelimella, voimme vain toivoa puolustuskerroksen tehokkuutta, mikä voi vähentää vahinkoa.

    Puun ruiskutussuoja

    Helpoin tapa suodattaa kaikki ulkoiset lokiviestit on käyttää sallittujen luetteloa. Oletetaan, että merkistö on rajoitettu vain numeroihin, kirjaimiin ja välilyönteihin. Viestit, jotka sisältävät luvattomia merkkejä, katsotaan vioittuneiksi. Sitten lokiin ilmestyy merkintä mahdollisesta yrityksestä lisätä lokitiedosto. Tämä on yksinkertainen suojausmenetelmä yksinkertaisille tekstilokeille, joissa ei voida välttää viestien sisällyttämistä epäluotettaviin syöttötietoihin.


    Toinen suojausmenetelmä on muuntaa epäluotettavan syöttötiedon paloja käyttämällä base64:n kaltaista järjestelmää, joka tukee rajoitettua merkkijoukkoa, mutta sallii silti erilaisten tietojen tallentamisen tekstimuodossa.

    Path Traversal (tunnetaan nimellä hakemiston läpikulku)

    Polun läpikulkuhyökkäykset ovat yrityksiä vaikuttaa tiedostojen luku- tai kirjoitustoimintoihin verkkosovelluksen taustalla. Tämä tehdään ottamalla käyttöön parametreja, joiden avulla voit manipuloida taustatoimintoihin osallistuvien tiedostojen polkuja. Joten tämäntyyppinen hyökkäys helpottaa tietojen paljastamista ja paikallista/etätiedostojen lisäämistä.


    Käsittelemme tällaisia ​​hyökkäyksiä erikseen, mutta niiden menestyksen perusta on juuri polun läpikulku. Koska alla kuvatut toiminnot liittyvät tiedostopolkujen manipulointiin, on järkevää mainita, että monet PHP-funktiot eivät hyväksy tiedostopolkuja sanan tavallisessa merkityksessä. Sen sijaan funktiot, kuten include() tai file(), hyväksyvät URI:n.


    Se näyttää täysin luonnottomalta. Mutta tämä tarkoittaa, että seuraavat kaksi funktiokutsua ovat samanarvoisia, ja ne käyttävät absoluuttisia polkuja (esimerkiksi luottamatta suhteellisten polkujen automaattiseen lataamiseen).


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

    Asia on, että suhteellinen polku käsitellään sivulla (php.inin include_path-asetus ja käytettävissä olevat automaattiset latausohjelmat). Tällaisissa tapauksissa PHP-toiminnot ovat erityisen haavoittuvia monille parametrien manipuloinnin muodoille, mukaan lukien File URI Scheme Substitution, jossa hyökkääjä voi syöttää HTTP- tai FTP-URI:n, jos tiedostopolun alkuun on upotettu epäluotettavaa tietoa. Puhumme tästä yksityiskohtaisemmin osiossa etätiedostojen sisällyttämistä koskevista hyökkäyksistä, mutta toistaiseksi keskitymme tiedostojärjestelmän polkujen ohittamiseen.


    Tämä haavoittuvuus sisältää polun muuttamisen toisen tiedoston käyttämiseksi. Tämä saavutetaan tyypillisesti lisäämällä sarja ../-sarjoja argumenttiin, joka sitten liitetään funktioihin tai lisätään kokonaan funktioihin, kuten include() , request() , file_get_contents() ja vielä vähemmän epäilyttäviä (joihinkin) funktioihin kuten DOMDocument: :load() .


    Hyökkääjä pakottaa järjestelmän palaamaan päähakemistoon käyttämällä ../-sekvenssiä. Joten polku /var/www/public/../vendor menee itse asiassa osoitteeseen /var/www/vendor. Jakso ../ /public jälkeen vie meidät takaisin päähakemistoon, eli /var/www. Tämä antaa hyökkääjälle mahdollisuuden päästä käsiksi tiedostoihin, jotka sijaitsevat verkkopalvelimelta saatavan /public-hakemiston ulkopuolella.


    Tietenkin polun kulkeminen ei rajoitu vain paluuta. Voit ottaa käyttöön uusia polkuelementtejä päästäksesi alihakemistoihin, joita ei voi käyttää selaimella .htaccess-tiedoston rajoitusasetusten vuoksi. PHP-tiedostojärjestelmän toiminnot eivät välitä Web-palvelimen ei-julkisten tiedostojen ja hakemistojen kulunvalvontamäärityksistä.

    Esimerkkejä Path TraversalDefenseista Path TraversalXML-injektiota vastaan

    Huolimatta JSONin käyttöönotosta kevyenä tiedonsiirtovälineenä palvelimen ja asiakkaan välillä, XML on edelleen suosittu vaihtoehto, ja verkkopalvelun sovellusliittymät tukevat sitä usein rinnakkain JSONin kanssa. XML:ää käytetään myös tietojen vaihtamiseen XML-skeemojen avulla: RSS, Atom, SOAP ja RDF jne.


    XML on läsnä kaikkialla: se löytyy verkkosovelluspalvelimista, selaimista (ensisijainen muoto XMLHttpRequest-pyyntöille ja -vastauksille) ja selainlaajennuksista. Kun otetaan huomioon sen yleisyys ja oletuskäsittely suosituilla jäsentimillä, kuten libxml2, joita PHP käyttää DOM:ssa ja SimpleXML- ja XMLReader-laajennuksissa, XML:stä on tullut injektiohyökkäysten kohde. Kun selain osallistuu aktiivisesti XML-vaihtoon, on otettava huomioon, että XSS:n kautta valtuutetut käyttäjät voivat lähettää XML-pyyntöjä, jotka ovat todellisuudessa hyökkääjien luomia.

    XML External Entity Embedding (XXE)

    Nämä hyökkäykset ovat olemassa, koska XML-jäsennyskirjastot tukevat usein mukautettujen entiteettiviittausten käyttöä. Opit standardinmukaisesta XML-entiteetin täydentämisestä, jota käytetään edustamaan erityisiä merkintämerkkejä, kuten > , < ; ja '. XML:n avulla voit laajentaa vakiokokonaisuuksien joukkoa määrittelemällä mukautettuja entiteettejä itse XML-dokumentin kautta. Ne voidaan määritellä sisällyttämällä ne suoraan valinnaiseen DOCTYPE-tiedostoon. Niiden edustama laajennettu arvo voi viitata ulkoiseen resurssiin, joka tulisi sisällyttää. XXE-hyökkäykset tulivat suosituiksi juuri tavallisen XML:n kyvystä tallentaa mukautettuja linkkejä, joita voidaan laajentaa ulkoisten resurssien sisällön vuoksi. Normaaleissa olosuhteissa epäluotettavat syötteet eivät saa koskaan olla vuorovaikutuksessa järjestelmämme kanssa odottamattomilla tavoilla. Ja useimmat XXE-ohjelmoijat eivät melkein varmasti ennakoi XXE-hyökkäyksiä, mikä on erityisen huolestuttavaa.


    Määritellään esimerkiksi uusi mukautettu harmiton entiteetti:



    Tällä määritelmällä varustettu XML-dokumentti voi nyt viitata entiteettiin, missä entiteetit ovat yleensä sallittuja:


    Tämä tulos on

    Kun XML-jäsentäjä, kuten PHP DOM, tulkitsee tämän XML:n, se käsittelee tämän mukautetun entiteetin heti, kun asiakirja ladataan. Siksi, kun se pyytää vastaavaa tekstiä, se palauttaa seuraavan:


    Tämä tulos on täysin vaaraton


    On selvää, että mukautetuilla kokonaisuuksilla on se etu, että ne edustavat toistuvaa tekstiä ja XML:ää lyhyemmillä entiteettinimilla. Usein on niin, että XML:n on noudatettava tiettyä kielioppia, ja mukautetut entiteetit helpottavat muokkaamista. Koska emme kuitenkaan luota ulkoiseen syötteeseen, meidän on oltava erittäin varovaisia ​​kaikkien sovelluksemme käyttämien XML-tiedostojen kanssa. Esimerkiksi tämä ei ole ollenkaan turvallinen lajike:


    &harmless;

    Pyydetyn paikallisen tiedoston sisällöstä riippuen tietoja voidaan käyttää entiteetin laajentamiseen. Ja sitten laajennettu sisältö voidaan poimia XML-jäsentimästä ja sisällyttää verkkosovelluksen lähteviin tietoihin hyökkääjän analysoitavaksi. Esimerkiksi tietojen paljastamiseen. Purettu tiedosto tulkitaan XML-muodossa, vaikka tulkinnan käynnistämiseksi ei ole mitään erikoismerkkejä. Tämä rajoittaa sitä, missä määrin paikallisen tiedoston sisältö voidaan paljastaa. Jos tiedosto tulkitaan XML:ksi, mutta se ei sisällä kelvollista XML:ää, saamme todennäköisesti virheilmoituksen, joka estää sisällön paljastumisen. PHP:llä on kuitenkin tarjolla hieno temppu laajuuden rajan ohittamiseksi, jotta HTTP-etäpyynnöt vaikuttavat verkkosovellukseen, vaikka palautettua vastausta ei voida välittää takaisin hyökkääjälle.


    XML:n jäsentämiseen ja käyttämiseen PHP:ssä on kolme yleisesti käytettyä menetelmää: PHP DOM, SimpleXML ja XMLReader. Ne kaikki käyttävät libxml2-laajennusta, ja ulkoisten entiteettien tuki on oletuksena käytössä. Tämän seurauksena PHP on oletusarvoisesti alttiina XXE-hyökkäyksille, mikä on erittäin helppo jättää huomiotta, kun harkitaan XML:ää käyttävän verkkosovelluksen tai kirjaston turvallisuutta.


    Älä myöskään unohda, että XHTML ja HTML 5 voidaan serialisoida kelvollisena XML:nä. Tämä tarkoittaa, että jotkin XHTML-sivut tai XML-sarjamuotoinen HTML 5 voidaan jäsentää XML-muodossa käyttämällä DOMDocument::loadXML()-muotoa DOMDocument::loadHTML() -arvon sijaan. Tämä XML-jäsentimen käyttö on myös alttiina ulkoisten XML-kokonaisuuksien lisäämiselle. Muista, että libxml2 ei vielä edes tunnista HTML 5 DOCTYPE -muotoa, joten se ei voi vahvistaa sitä XHTML DOCTYPES -muodossa.

    Esimerkkejä ulkoisten XML-olioiden toteuttamisesta Tiedoston sisältö ja julkistaminen

    Tarkastelimme esimerkkiä tietojen paljastamisesta yllä ja huomasimme, että mukautettu XML-entiteetti voi viitata ulkoiseen tiedostoon.


    &harmless;

    Tässä tapauksessa mukautettu entiteetti laajenee tiedostojen sisällöllä. Koska kaikki tällaiset pyynnöt suoritetaan paikallisesti, tämä mahdollistaa kaikkien tiedostojen sisällön paljastamisen, joita sovellus voi lukea. Eli kun laajennettu entiteetti sisällytetään sovelluksen lähteviin tietoihin, hyökkääjä voi tutkia tiedostoja, joihin ei ole pääsyä. Tässä tapauksessa on kuitenkin vakava rajoitus: tiedostojen on oltava joko XML-muodossa tai sellaisessa muodossa, joka ei johda virheeseen XML-jäsentimessä. Mutta pointti on, että tämä rajoitus voidaan jättää kokonaan huomiotta PHP:ssä:


    &harmless;

    PHP tarjoaa pääsyn kääreeseen URI-tiedostona, joka on yksi tiedostojärjestelmän standarditoimintojen hyväksymistä protokollista: file_get_contents(), request(), request_once(), file(), copy() ja monet muut. PHP-kääre tukee useita suodattimia, joita voidaan käyttää tiettyyn resurssiin niin, että tulokset palautetaan kutsumalla funktiota. Yllä olevassa esimerkissä käytämme convert.base-64-encode-suodatinta kohdetiedostoon, jonka haluamme lukea.


    Tämä tarkoittaa, että hyökkääjä voi lukea mitä tahansa PHP:lle saatavilla olevaa tiedostoa tekstimuodosta riippumatta. Riittää, kun yksinkertaisesti puretaan sovelluksesta tulevat tiedot ja sitten puretaan se rankaisematta. Vaikka tämä ei suoraan vahingoita loppukäyttäjiä tai sovelluksen taustaa, sen avulla hyökkääjät voivat tutkia perusteellisesti sovelluksen rakennetta yrittääkseen löytää muita haavoittuvuuksia. Lisäksi riski, että hyökkääjät havaitaan, on minimaalinen.

    Kulunvalvonnan ohitus

    Pääsyä ohjataan eri tavoin. Koska XXE-hyökkäykset suoritetaan verkkosovelluksen taustalla, nykyisen käyttäjän istuntoa ei voida käyttää. Hyökkääjä voi kuitenkin ohittaa taustajärjestelmän pääsynhallinnan käyttämällä pyyntöjä paikalliselta palvelimelta. Harkitse tätä primitiivistä pääsynhallintaa:


    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("Sinulla ei ole oikeutta käyttää tätä tiedostoa."); )

    Tämä PHP-kappale, kuten monet muut vastaavat, rajoittaa pääsyä tiettyihin PHP-tiedostoihin paikallisella palvelimella, eli localhostilla. Kuitenkin XXE-hyökkäys sovelluksen etupäähän antaa hyökkääjälle tarkat valtuustiedot, joita tarvitaan näiden pääsynvalvontatoimintojen ohittamiseen, koska kaikki HTTP-pyynnöt XML-jäsentimeen tehdään localhostilta.


    &harmless;

    Vaikka lokien katselu rajoitettaisiin paikallisiin pyyntöihin, hyökkääjä voisi silti saada lokit. Sama koskee ylläpito- tai hallintorajapintoja, joihin pääsyä rajoitetaan tällä tavalla.

    DOS-hyökkäykset

    Lähes mitä tahansa, mikä määrää palvelinresurssien kulutuksen, voidaan käyttää DOS-hyökkäyksiin. Lisäämällä ulkoisen XML-entiteetin hyökkääjä voi tehdä mielivaltaisia ​​HTTP-pyyntöjä, jotka oikeissa olosuhteissa kuluttavat palvelinresursseja.


    Puhumme myöhemmin muista mahdollisista XXE-hyökkäysten DOS-käytöistä XML-kokonaisuuden laajentamisen kannalta.

    Suojaus ulkoisten XML-olioiden injektointia vastaan

    Nämä hyökkäykset ovat erittäin suosittuja, joten tulet yllättymään kuinka helppoa on puolustautua niitä vastaan. Koska DOM, SimpleXML ja XMLReader perustuvat libxml2:een, voit yksinkertaisesti käyttää libxml_disable_entity_loader()-funktiota ulkoisten entiteettien käytön poistamiseen. Tämä ei kuitenkaan poista käytöstä mukautettuja entiteettejä, jotka on määritetty valmiiksi DOCTYPE:ssä, koska ne eivät käytä ulkoisia resursseja, jotka edellyttävät HTTP-pyyntöä tai tiedostojärjestelmän toimintaa.


    $vanhaArvo = libxml_disable_entity_loader(true); $dom = uusi DOMDocument(); $dom->loadXML($xml); libxml_disable_entity_loader($oldArvo);

    Tämä on tehtävä kaikille toimille, jotka sisältävät XML:n lataamisen merkkijonoista, tiedostoista tai etä-URI:ista.


    Jos sovellus ei koskaan vaadi ulkoisia entiteettejä, ja useimmille sen pyynnöille, ulkoisten resurssien lataaminen voidaan estää kokonaan maailmanlaajuisemmalla tasolla. Useimmissa tapauksissa tämä on paljon parempi kaikkien XML-latauspisteiden määrittämiseksi, koska monissa kirjastoissa on luontaisia ​​haavoittuvuuksia XXE-hyökkäyksille:


    libxml_disable_entity_loader(true);

    Muista vain palauttaa TRUE jokaisen väliaikaisen ulkoisten resurssien lataamisen jälkeen. Saatat tarvita sitä johonkin niin vaarattomaan hommaan kuin Docbook XML:n muuntamiseen HTML:ksi, jossa XSL-tyylien soveltaminen riippuu ulkoisista kokonaisuuksista.


    Libxml2:n estotoiminto ei kuitenkaan ole ihmelääke. Analysoi muita laajennuksia ja PHP-kirjastoja, jotka jäsentävät tai muuten käsittelevät XML:ää löytääksesi "kytkimensä" ulkoisten entiteettien käyttöä varten.


    Jos tämä ei ole mahdollista, tarkista lisäksi, ilmoittaako XML-dokumentti DOCTYPE. Jos näin on, ja jos ulkoiset entiteetit on poistettu käytöstä, heitä XML-dokumentti pois, estä epäluotettava XML-pääsy mahdollisesti haavoittuvaan jäsentimeen ja kirjaa se todennäköisenä hyökkäyksenä. Tämä on välttämätön askel, koska muita merkkejä ei tule - ei virheitä, ei poikkeuksia. Sisällytä tämä tarkistus tavalliseen syötteen vahvistukseen. Mutta tämä menetelmä on kaukana ihanteellisesta, joten on erittäin suositeltavaa ratkaista perusteellisesti ulkoisten kokonaisuuksien ongelma.


    /** * Yritä nopeaa tunnistusta */ $collapsedXML = preg_replace("/[:space:]/", "", $xml); if(preg_match("/