Sări la conținut

Secvențe de escapare

Aproape fiecare bug de escapare este o eroare de context mai degrabă decât o eroare de sintaxă. Caracterul este cunoscut — o ghilimă, o bară inversă, o ampersand — și ceea ce este neclar este care din șase reguli conflictuale se aplică acolo unde șirul este pe cale să aterizeze.

Deci acest tabel este organizat după context, nu după caracter. Aceeași ghilimă este dublată într-o celulă CSV, scapă cu bară inversă în JSON, transformată în " în HTML și lăsată complet singură în interiorul ghilimelor simple în shell. Patru rânduri, patru reguli, un caracter.

Regula care contează cel mai mult este cea pe care oamenii o caută ultimă: escapează la limita pe care valoarea o traversează și escapează-o o singură dată. Textul care este evitat de două ori — un & în sursa paginii, un \\n în fișierul de ieșire — este semnătura unei valori care a trecut prin doi codificatori care fiecare au presupus că erau primii.

Șiruri JSON

10

JSON permite exact aceste escapări. O linie nouă literală sau tab în interiorul unui șir este nevalid.

EscapareÎnseamnăCând ai nevoieÎn context
\""O ghilimă dublă în interiorul unui șir"say \"hi\""
\\\O bară inversă literalăMotivul pentru care căile Windows rupe JSON."C:\\dir"
\//O bară directă — opționalăLegală dar inutilă; un obicei din încorporarea JSON în etichete <script>."a\/b"
\nU+000AO alimentare linie"line\nline"
\rU+000DO întoarcere cărucior
\tU+0009O tabulație
\bU+0008O spate spațiu
\fU+000CUn formular alimentare
\u00e9éOrice caracter după punctul ei de cod din patru cifre"caf\u00e9"
\ud83d\ude00😀Un caracter deasupra U+FFFF, ca o pereche substituteJSON nu are formă \u{…}, deci caractere astrale durează două escapări.

Șiruri JavaScript

10

Un superset al JSON, plus escapările literalelor șablonului.

EscapareÎnseamnăCând ai nevoieÎn context
\''O ghilimă simplă în interiorul unui șir din ghilimele simple
\""O ghilimă dublă în interiorul unui șir din ghilimele duble
\``O ghilimă inversă în interiorul unui literal șablon
\${${Un literal ${ în interiorul unui literal șablonFără bară inversă începe o interpolare.
\nU+000AO alimentare linie
\xe9éUn caracter după două cifre hex, până la U+00FF
\u00e9éUn caracter după patru cifre hex
\u{1f600}😀Orice punct de cod, indiferent de lungimeNu are nevoie de pereche substitute, spre deosebire de forma cu patru cifre.
\0U+0000Un caracter nul
\u2028U+2028Separator linieValabil într-un șir JS dar nu în JSON — o rupere JSONP clasică.

Text și atribute HTML

8

Doar & și < trebuie strict evitați în text; ghilimele contează în interiorul atributelor.

EscapareÎnseamnăCând ai nevoieÎn context
&amp;&Un ampersandEscapează-o pe asta în primul rând, sau fiecare altă escapare se dublează.
&lt;<Un semn mai mic, deci nu începe o etichetă
&gt;>Un semn mai mare decât
&quot;"O ghilimă dublă în interiorul unui atribut
&#39;'O ghilimă simplă în interiorul unui atribut&apos; de asemenea funcționează în HTML5, dar forma numerică este sigură peste tot.
&nbsp;U+00A0Un spațiu care nu se rupe
&#233;éOrice caracter după punct de cod zecimal
&#xE9;éOrice caracter după punct de cod hex

URL-uri (codificare procent)

9

Care caractere trebuie evitate depinde de partea URL-ului în care se află.

EscapareÎnseamnăCând ai nevoieÎn context
%20 Un spațiu, valabil oriunde în un URL
+ Un spațiu, dar doar în șirul de interogare codat din formăÎntr-un segment de cale aceasta este un semn plus literal.
%25%Un semn procent literalPierdere asta și valoarea se decodifică de două ori.
%2F/O bară în interiorul unui segment cale unic
%3F?Un semn întrebare în interiorul unei valori
%26&Un ampersand în interiorul unei valori parametru
%3D=Un semn egal în interiorul unei valori parametru
%23#Un hash, deci nu începe fragmentul
%C3%A9éUn caracter non-ASCII, ca octeții lui UTF-8Un caracter poate deveni două, trei sau patru grupuri procent.

Câmpuri CSV

5

RFC 4180: cotează câmpul, apoi dublează orice citat în interiorul lui. Barele inversate nu înseamnă nimic.

EscapareÎnseamnăCând ai nevoieÎn context
"""O ghilimă în interiorul unui câmp citat — dublează-o"say ""hi"""
"a,b",Un câmp care conține delimitatorul — cotează câmpul
"a b"U+000AUn câmp care conține o întrerupere linie — cotează câmpul
" a" Păstrează spații conducente sau finalizanteNecitatat, mulți analizatori le taie.
'=SUM(A1)=Opreste foaia de calcul executând celula ca formulăSe aplică la valori care încep cu =, +, - sau @. Aceasta este injecție de formulă.

Literali și identificatori SQL

6

Citește acestea; nu le scrie. Folosește interogări parametrizate în schimb.

EscapareÎnseamnăCând ai nevoieÎn context
'''O ghilimă în interiorul unui literal șir — dublează-o'O''Brien'
"order"orderUn cuvânt rezervat folosit ca nume de coloanăGhilimele duble sunt standardul; SQL Server folosește [paranteze].
`order`orderAcelași în MySQL și MariaDB
\%%Un literal % în interiorul unui tipar LIKE
\__Un literal _ în interiorul unui tipar LIKE
$tag$ … $tag$'PostgreSQL citat dolar — nicio escapare în interiorul în totalUtil pentru corpuri de cod, unde dublarea fiecare citat este neinteligibil.

Argumente shell

6

Ghilimele simple sunt literale, ghilimele duble încă se extind variabile.

EscapareÎnseamnăCând ai nevoieÎn context
'…'$ ` \Totul din interior este literalCotarea cea mai sigură care există — dar nu poate conține o ghilimă simplă.
"…"* ? spaceGlob și spații sunt sigure, variabilele încă se extindAlways quote variables: "$var", never bare $var.
\ Un spațiu într-un nume de fișier necitat
\$$Un semn dolar literal în interiorul ghilimelor duble
\``O ghilimă inversă literală, nu o substituție de comandă
'\'''O ghilimă simplă în interiorul ghilimelor simpleÎnchide, escapează, redeschide — nu există nicio modalitate de a o imbrica direct.

FAQ

De ce JSON meu se rupe pe o cale de fișier Windows?
Deoarece o bară inversă începe o secvență de escapare într-un șir JSON, deci C:\dir este citit ca C, apoi o escapare nevalidă. Scris corect valoarea este "C:\\dir" — două bare inversate în fișier, una în șirul analizat. Slash-urile directe funcționează și pe Windows și evită problema cu totul.
Este %20 sau + corect pentru un spațiu într-un URL?
Ambele, în locuri diferite. %20 este corect oriunde într-un URL. Semnul plus înseamnă un spațiu doar în interiorul unui șir de interogare codificat ca application/x-www-form-urlencoded — în segment de cale este un plus literal. Folosește %20 când ești nesigur, deoarece este corect peste tot.
Cum pun o ghilimă în interiorul unui câmp CSV?
Înfășoară câmpul în ghilimele și dublează pe cel din interior: "say ""hi""". Aceasta este RFC 4180, și aceasta este motivul pentru care un CSV plin de ghilimele dublate nu este corupt. O bară inversă nu înseamnă nimic pentru un analizator CSV conform.
Care este scopul apostrofului din capăt din rândul formulei CSV?
Neutralizează o injecție de formulă. O celulă care începe cu =, +, - sau @ este executată ca formulă atunci când fișierul este deschis într-o foaie de calcul, deci o valoare cum ar fi =SUM(A1) dintr-o sursă de neîncredere devine cod. Prefixarea unui apostrof forțează celula să fie citită ca text.
Trebuie să scap SQL manual?
Nu. Dublarea unei ghilimele este documentată aici deoarece trebuie să citești SQL evitat, nu deoarece ar trebui să îl scrii — folosește interogări parametrizate și lasă driverul să gestioneze valoarea. Escaparea manuală este de unde vine injecția SQL, și nu există o versiune din ea care este sigură la inspecție.