Nu aveți niciodată încredere în nimic din ceea ce vine de la client. - proverb antic

Acum știm cum să obținem inputul utilizatorului folosind formulare HTML și solicitări POST care declanșează funcția doPost () a claselor noastre de servlet.

Dar trebuie să fim foarte atenți atunci când afișăm acea intrare a utilizatorului, în special altor utilizatori. Nu putem permite doar conținut arbitrar, deoarece atunci utilizatorii rău intenționați ar putea face lucruri rele, cum ar fi să injecteze HTML sau JavaScript în pagina noastră, ceea ce le-ar permite să redirecționeze browserele, să fure informații sau să exploateze scripturi între site-uri pe site-ul dvs.

În schimb, trebuie dezinfecta datele pe care le primim de la utilizatorii noștri, astfel încât să conțină numai conținut sigur. Totuși, nu există un singur mod de a face acest lucru! Este mai degrabă o serie de întrebări la care trebuie să răspundeți, iar răspunsurile depind exact de modul în care doriți să acționeze site-ul dvs. și ce tipuri de conținut doriți să permiteți.

Exemplu de aplicație web

Să începem cu un exemplu de aplicație web care preia date de la un utilizator și apoi le afișează. Iată clasa noastră de servlet:

În funcția sa doGet (), acest servlet adaugă conținutul la cerere și îl redirecționează către un fișier JSP pentru redare. Funcția doPost () obține parametrul de conținut trimis, îl stochează și apoi redirecționează înapoi la o solicitare GET.

Fișierul JSP arată astfel:

Acest fișier arată doar conținutul și apoi un formular care permite utilizatorului să schimbe conținutul.

În cele din urmă, iată fișierul web.xml:

Fișierul web.xml mapează adresa URL/home la servletul nostru. Rulați acest servlet și vizitați http: // localhost: 8080/home și ar trebui să vedeți acest lucru:

codificare

Puteți introduce un anumit text pentru a vă asigura că funcționează.

Aici am tastat Hello world! și a făcut clic pe butonul Trimitere. Servletul a stocat acel conținut, iar acum pagina JSP îl afișează. Vă puteți gândi la aceasta ca la o versiune foarte simplă a unui site web care vă permite să trimiteți postări, cum ar fi Twitter sau Facebook sau orice altceva.

Introducere de utilizator necorespunzătoare

Dar ce se întâmplă dacă introduceți html?

Încercați să introduceți ceva de genul

Acest lucru se datorează faptului că JSP-ul nostru transmite conținutul direct în HTML pe această linie:

Deci, dacă conținutul este

Permiterea utilizatorilor de a introduce HTML arbitrar poate cauza probleme pe site-ul dvs. Imaginați-vă un site precum Twitter sau Facebook sau Tumblr, unde postările unui utilizator sunt afișate altor utilizatori. Dacă sunt un utilizator rău intenționat, aș putea:

  • Dezordonează formatarea site-ului tău.
  • Redirecționați browserele utilizatorului dvs. către propriul meu site.
  • Fură datele utilizatorului.
  • Exploatați scripturi pe mai multe site-uri.

Ca un alt exemplu, încercați să introduceți acest lucru ca conținut:

Acest conținut este doar o lume!

Bună lume badStuff ()!

. Amintiți-vă că și> sunt afișate ca și> în loc să fie analizate ca etichete HTML.

Curat conținut pentru a permite numai utilizarea HTML sigură.

Bandă conținut pentru a nu permite deloc HTML.

devine Hello world! .

A inlocui conținut, astfel încât utilizatorii să poată introduce etichete non-HTML pe care le convertiți în HTML. un anumit conținut [b] îndrăzneț [/ b] devine

ceva conținut îndrăzneț

, de exemplu. Rețineți că va trebui totuși să decideți ce să faceți cu HTML normal amestecat cu acest tip de conținut.

Abordarea pe care o alegeți depinde de modul în care doriți să funcționeze aplicația dvs. web, de preocupările dvs. de securitate și, sincer, de cât timp doriți să investiți în această parte a site-ului dvs. (Faceți lucrul ușor care durează 5 minute sau petreceți o grămadă de timp perfecționând fluxul de intrare?) De fapt, veți folosi probabil o combinație a mai multor dintre opțiunile de mai sus.

Conținutul interzis

Respingerea conținutului este probabil cea mai ușoară opțiune, dar chiar și atunci aveți mai multe întrebări la care să răspundeți:

  • Doriți să utilizați un lista albă care asigură că intrarea conține numai conținut permis?
  • Sau vrei să folosești un lista neagră care verifică conținutul respins?

Folosirea unei liste albe este mai sigură, dar mai restrictivă. De obicei, veți utiliza o expresie obișnuită pentru a interzice conținutul, indiferent dacă folosiți o listă albă sau o listă neagră.

Să modificăm clasa noastră de servlet pentru a utiliza o listă albă care permite utilizatorilor să introducă doar litere, cifre și spații.

Acum funcția doPost () folosește o expresie regulată împreună cu funcția matches () pentru a vă asigura că valoarea de intrare conține doar litere, numere și spații. Dacă nu se potrivește cu expresia noastră regulată, înseamnă că intrarea conține caractere ilegale, iar servletul adaugă un atribut de eroare și transmite solicitarea către JSP. Dacă intrarea se potrivește cu expresia regulată, aceasta înseamnă că conține doar litere, cifre și spații și permitem solicitarea să treacă.

Acum, JSP afișează eroarea doar dacă este prezentă:

Acum încercați să introduceți lucruri de genul acesta

Această abordare a interzicerii anumitor conținut este destul de frecventă pentru numele de utilizator, mai ales pentru că probabil le veți folosi în adresele URL, care au propriile cerințe de conținut. Deci, probabil că nu doriți ca un nume de utilizator să fie /index.html sau o grămadă de spații sau conținut HTML.

Conținutul care scapă

Etichetele HTML sunt delimitate de simbolurile și>, ca în

. Dacă browserul dvs. vede unul dintre aceste simboluri, știe că conținutul este o etichetă HTML, deci ar trebui folosit pentru a formata textul în loc să îl afișați vizualizatorului.

Dar dacă vrem ca textul nostru să includă un simbol sau>? Ce se întâmplă dacă vrem să afișăm ceva de genul că îmi place foarte mult eticheta! fără ca partea să fie analizată ca HTML?

Avem nevoie să evadare aceste caractere folosind entități HTML. Entitățile HTML sunt un șir special de caractere care sunt redate ca un singur caracter și nu sunt analizate ca etichete HTML.

  • redă ca
  • > redă ca>
  • & redă ca &
  • „redă ca”
  • „redă ca”

Entitățile și> sunt bune pentru redarea conținutului ca text pur în loc de HTML care ar trebui analizat. Entitatea & este necesară, deoarece o & cu semn normal este tratată ca începutul unei entități (deci, dacă doriți ca textul dvs. să fie redat ca în loc de, ar trebui să utilizați < ). Entitățile „și” sunt utile atunci când doriți să introduceți conținutul utilizatorului în atributele elementelor (de exemplu, dacă doriți să faceți acest lucru

Deci, dacă vrem să redăm conținutul utilizatorului exact așa cum l-au introdus, fără ca acesta să fie analizat ca HTML, trebuie doar să înlocuim simbolurile care ar putea fi analizate ca HTML sau să interfereze cu formatarea noastră cu entitatea HTML corespunzătoare. Probabil am putea face acest lucru folosind funcțiile replace () și replaceAll (), dar în loc să reinventăm roata, să folosim un libar care face acest lucru pentru noi.

Biblioteca Apache Commons Lang oferă mai multe funcții utile pentru a scăpa de conținut. Descărcați fișierul .ary libary și copiați-l în folderul lib din directorul aplicației dvs. web. Acum putem folosi acea bibliotecă în servletul nostru:

Acum funcția doPost () folosește funcția escapeHtml4 () pentru a scăpa de conținut, ceea ce îl redă ca text pur în loc de conținut HTML:

Această abordare a evadării conținutului este utilă dacă doriți un editor de text foarte simplu, care să nu ofere niciun stil și doriți să redați textul exact cum au introdus-o utilizatorii.

Curățarea conținutului

Nu toate etichetele sau atributele HTML sunt periculoase, deci ar putea avea sens să permiți unele HTML, atâta timp cât nu permiți lucrurile periculoase. De exemplu, ați putea dori să permiteți