Escape zavisi od konteksta
String nikada nije „escape-ovan“ apstraktno; escape-uje se za jedno konkretno mesto u koje će biti umetnut, a svako mesto ima svoja pravila. Istom tekstu treba \" u JSON-u, '' u SQL-u, '\'' u shellu i " u HTML-u. Upotreba pogrešnog je način na koji nastaju injection greške: HTML escape pre stavljanja teksta u JavaScript string, ili shell escape dvostrukim navodnicima uz ostavljanje aktivnog $.
| Kontekst | Šta mora da se escape-uje | Kako |
|---|---|---|
| JSON string | " \ i kontrolni znakovi | \" \\ \n \t \u00XX |
| Shell, jednostruki navodnici | ' | '\'' (zatvori, doslovni navodnik, ponovo otvori) |
| Shell, dvostruki navodnici | " \ $ ` i ! u interaktivnom bashu | obrnuta kosa crta |
| SQL literal | ' | '' (MySQL prihvata i \') |
| Regex | . * + ? ^ $ { } ( ) [ ] | \ / | obrnuta kosa crta |
| C / Go / Rust / Java | " \ novi red tab | \" \\ \n \t \xHH \uHHHH |
| CSV polje | , " novi red | obaviti navodnicima, udvostručiti navodnike |
| HTML / XML tekst | & < > " ' | & < > " ' / ' |
| YAML | Sve dvosmisleno: yes, no, 1.0, vodeći * ili &, dvotačke | Dvostruki navodnici sa JSON escape sekvencama |
Konkretno, shell
Jednostruki navodnici su jedino potpuno bezbedno navođenje u POSIX shellovima: ništa unutra se ne tumači, a jedini znak koji ne može da se pojavi je sam jednostruki navodnik, koji se piše tako što se navedeni string završi, doda escape-ovani navodnik i počne ponovo: 'it'\''s'. Dvostruki navodnici i dalje proširuju $promenljive, `komande` i \, pa su za slučajeve kad želite proširivanje. Kad prosleđujete podatke iz koda, uopšte ne gradite komandne linije: koristite niz argumenata (execve, subprocess.run([...]), exec.Command) i escape postaje nepotreban.
Konkretno, SQL
Udvostručavanje navodnika je ispravan SQL, ali nije način na koji aplikacije treba da prosleđuju vrednosti. Parametrizovani upiti ($1, ?, :name) šalju vrednost odvojeno od naredbe i čine injection nemogućim. SQL escape koristite za ad-hoc upite u konzoli, ne u kodu.
Pitanja
Kako da stavim jednostruki navodnik unutar shell stringa u jednostrukim navodnicima?
Završite string, dodajte escape-ovani navodnik, počnite ponovo: 'it'\''s'. Ili koristite $'it\'s' u bashu/zsh-u, koji podržava escape sekvence sa obrnutom kosom crtom.
Zašto moj JSON ima \u00e9 umesto é?
Neki enkoderi escape-uju sve ne-ASCII znakove radi bezbednosti u 7-bitnim kanalima. I dalje je ispravan i dekodira se u isti string. JSON.stringify u JavaScriptu i json.dumps sa ensure_ascii=False u Pythonu zadržavaju znakove.
Koja je razlika između escape-a i kodiranja?
Escape štiti nekoliko specijalnih znakova da bi tekst mogao da stoji unutar neke sintakse; kodiranje (Base64, URL) pretvara ceo string u drugi alfabet. Base64 i URL kodiranje su ovde uključeni jer su često potrebni u istom dahu.
Mogu li da escape-ujem za regex u konkretnom jeziku?
Regex escape pokriva metaznakove zajedničke svim uobičajenim mašinama (PCRE, JavaScript, Python, Go RE2, Java). Unutar klase znakova [] važni su samo ] \ ^ i -; alat escape-uje konzervativno tako da rezultat radi svuda.