Vai al contenuto

Sequenze di escape

Quasi ogni bug di escape è un errore di contesto piuttosto che un errore di sintassi. Il carattere è noto — una virgoletta, una barra rovesciata, un'e commerciale — e ciò che è poco chiaro è quale delle sei regole conflittuali si applica dove la stringa sta per atterrare.

Quindi questa tabella è organizzata per contesto, non per carattere. La stessa virgoletta è raddoppiata in una cella CSV, con barra rovesciata sfuggita in JSON, trasformata in " in HTML e lasciata completamente da sola all'interno di virgolette singole in una shell. Quattro righe, quattro regole, un carattere.

La regola che importa di più è quella a cui la gente arriva per ultima: sfuggi al confine dove il valore sta per attraversare, e sfuggi una sola volta. Il testo che è sfuggito due volte — un & nel sorgente della pagina, un \\n nel file di output — è la firma di un valore che ha attraversato due codificatori che assumevano ciascuno di essere i primi.

Stringhe JSON

10

JSON consente esattamente questi escape. Una newline o una scheda letterale all'interno di una stringa non è valida.

EscapeSignificaQuando ne hai bisognoNel contesto
\""Una virgoletta doppia all'interno di una stringa"say \"hi\""
\\\Una barra rovesciata letteraleLa ragione per cui i percorsi Windows rompono JSON."C:\\dir"
\//Una barra in avanti — facoltativoLegale ma non necessario; un'abitudine dal incorporamento JSON in tag <script>."a\/b"
\nU+000AUn'alimentazione della linea"line\nline"
\rU+000DUn ritorno di carrello
\tU+0009Una scheda
\bU+0008Un backspace
\fU+000CUn feed di modulo
\u00e9éUn carattere qualsiasi dal suo punto di codice a quattro cifre"caf\u00e9"
\ud83d\ude00😀Un carattere sopra U+FFFF, come una coppia surrogataJSON non ha il modulo \u{…}, quindi i caratteri astrali richiedono due escape.

Stringhe JavaScript

10

Un superset di JSON, più gli escape dei letterali di template.

EscapeSignificaQuando ne hai bisognoNel contesto
\''Una virgoletta singola all'interno di una stringa tra virgolette singole
\""Una virgoletta doppia all'interno di una stringa tra virgolette doppie
\``Un backtick all'interno di un letterale di template
\${${Un ${letterale all'interno di un letterale di templateSenza la barra rovesciata avvia un'interpolazione.
\nU+000AUn'alimentazione della linea
\xe9éUn carattere di due cifre esadecimali, fino a U+00FF
\u00e9éUn carattere da quattro cifre esadecimali
\u{1f600}😀Un qualsiasi punto di codice, per quanto lungoNon ha bisogno di una coppia surrogata, a differenza della forma a quattro cifre.
\0U+0000Un carattere nullo
\u2028U+2028Separatore di lineaValido in una stringa JS ma non in JSON — una rottura JSONP classica.

Testo HTML e attributi

8

Solo & e < devono rigorosamente essere sfuggiti nel testo; le virgolette contano all'interno degli attributi.

EscapeSignificaQuando ne hai bisognoNel contesto
&amp;&Un'e commercialeSfuggi a questo per primo, o ogni altro escape si raddoppia.
&lt;<Un segno minore, quindi non inizia un tag
&gt;>Un segno maggiore di
&quot;"Una virgoletta doppia all'interno di un attributo
&#39;'Una virgoletta singola all'interno di un attributo&apos; funziona anche in HTML5, ma la forma numerica è sicura ovunque.
&nbsp;U+00A0Uno spazio non-breaking
&#233;éUn carattere qualsiasi dal suo punto di codice decimale
&#xE9;éUn carattere qualsiasi dal suo punto di codice esadecimale

URL (codifica percentuale)

9

Quali caratteri hanno bisogno di sfuggire dipende dalla parte dell'URL in cui si trovano.

EscapeSignificaQuando ne hai bisognoNel contesto
%20 Uno spazio, valido in qualsiasi punto di un URL
+ Uno spazio, ma solo in una stringa di query codificata con moduloIn un segmento di percorso questo è un segno più letterale.
%25%Un segno di percentuale letteraleMancalo e il valore decodifica due volte.
%2F/Una barra all'interno di un singolo segmento di percorso
%3F?Un punto interrogativo all'interno di un valore
%26&Un'e commerciale all'interno di un valore di parametro
%3D=Un segno uguale all'interno di un valore di parametro
%23#Un hash, quindi non inizia il frammento
%C3%A9éUn carattere non-ASCII, come i suoi byte UTF-8Un carattere può diventare due, tre o quattro gruppi di percentuali.

Campi CSV

5

RFC 4180: avvolgi il campo tra virgolette, quindi raddoppia quello interno. Le barre rovesciate non significano nulla.

EscapeSignificaQuando ne hai bisognoNel contesto
"""Una virgoletta all'interno di un campo tra virgolette — raddoppiala"say ""hi"""
"a,b",Un campo contenente il delimitatore — avvolgi il campo
"a b"U+000AUn campo contenente un'interruzione di riga — avvolgi il campo
" a" Conserva spazi iniziali o finaliSenza virgolette, molti parser li ritagliano.
'=SUM(A1)=Interrompi un foglio di calcolo eseguendo la cella come una formulaSi applica a valori che iniziano con =, +, - o @. Questo è injection formula.

Letterali SQL e identificatori

6

Leggili; non scriverli. Usa query parametrizzate invece.

EscapeSignificaQuando ne hai bisognoNel contesto
'''Una virgoletta all'interno di un letterale di stringa — raddoppiala'O''Brien'
"order"orderUna parola riservata usata come nome di colonnaLe virgolette doppie sono lo standard; SQL Server usa [parentesi graffe].
`order`orderLo stesso in MySQL e MariaDB
\%%Un percentuale letterale all'interno di un modello LIKE
\__Un underscore letterale all'interno di un modello LIKE
$tag$ … $tag$'Quotazione dollaro PostgreSQL — nessun escape al suo interno affattoUtile per i corpi del codice, dove raddoppiare ogni virgoletta è illeggibile.

Argomenti shell

6

Le virgolette singole sono letterali, le virgolette doppie ancora si espandono variabili.

EscapeSignificaQuando ne hai bisognoNel contesto
'…'$ ` \Tutto all'interno è letteraleLa quotazione più sicura che ci sia — ma non può contenere una virgoletta singola.
"…"* ? spaceI globs e gli spazi sono sicuri, le variabili si espandono ancoraAlways quote variables: "$var", never bare $var.
\ Uno spazio in un nome file senza virgolette
\$$Un segno di dollaro letterale all'interno di virgolette doppie
\``Un backtick letterale, non una sostituzione di comando
'\'''Una virgoletta singola all'interno di virgolette singoleChiudi, sfuggi, riapri — non c'è modo di annidarla direttamente.

FAQ

Perché il mio JSON si rompe su un percorso di file Windows?
Perché una barra rovesciata inizia una sequenza di escape in una stringa JSON, quindi C:\dir viene letto come C, poi un escape non valido. Scritto correttamente il valore è "C:\\dir" — due barre rovesciate nel file, una nella stringa analizzata. Le barre in avanti funzionano anche su Windows e evitano completamente il problema.
%20 o + è corretto per uno spazio in un URL?
Entrambi, in posti diversi. %20 è corretto in qualsiasi punto di un URL. Il segno più significa uno spazio solo all'interno di una stringa di query codificata come application/x-www-form-urlencoded — in un segmento di percorso è un più letterale. Usa %20 quando sei incerto, perché è corretto ovunque.
Come metto una virgoletta dentro un campo CSV?
Avvolgi il campo in virgolette e raddoppia quello interno: "say ""hi""". Questo è RFC 4180, e per questo una CSV piena di virgolette raddoppiate non è corrotta. Una barra rovesciata non significa nulla per un parser CSV conforme.
Qual è l'apostrofo iniziale nella riga della formula CSV?
Blocca un'iniezione di formula. Una cella che inizia con =, +, - o @ viene eseguita come una formula quando il file viene aperto in un foglio di calcolo, quindi un valore come =SUM(A1) da una fonte non attendibile diventa codice. L'aggiunta di un apostrofo costringe la cella a essere letta come testo.
Dovrei sfuggire a SQL a mano?
No. Raddoppiare una virgoletta è documentato qui perché hai bisogno di leggere SQL sfuggito, non perché dovresti scriverlo — usa query parametrizzate e lascia che il driver gestisca il valore. Lo sfuggire a mano è da dove proviene l'iniezione SQL, e non c'è versione di essa che sia sicura per ispezione.