Preskočiť na obsah

Escape sekvencie

Takmer každá chyba pri escapovaní je chybou kontextu, nie syntaxe. Znak je známy — úvodzovka, opačná lomka, ampersand — a nejasné je, ktoré zo šiestich protichodných pravidiel platí tam, kam sa ten text práve chystá.

Preto je táto tabuľka usporiadaná podľa kontextu, nie podľa znaku. Tá istá úvodzovka sa v CSV poli zdvojuje, v JSON-e escapuje opačnou lomkou, v HTML sa mení na " a vnútri jednoduchých úvodzoviek v shelle zostáva úplne nedotknutá. Štyri riadky, štyri pravidlá, jeden znak.

Najdôležitejšie pravidlo je to, po ktorom siahame ako po poslednom: escapujte na hranici, ktorú hodnota prekračuje, a escapujte raz. Text escapovaný dvakrát — & v zdroji stránky, \\n vo výstupnom súbore — je typický príznak hodnoty, ktorá prešla dvoma kodérmi a každý si myslel, že je prvý.

JSON reťazce

10

JSON povoľuje presne tieto escapy. Doslovný nový riadok alebo tabulátor v reťazci je neplatný.

EscapeZnamenáKedy ho trebaV kontexte
\""Dvojitá úvodzovka vnútri reťazca"say \"hi\""
\\\Doslovná opačná lomkaDôvod, prečo windowsové cesty rozbíjajú JSON."C:\\dir"
\//Dopredná lomka — voliteľnéLegálne, ale nepotrebné; zvyk z vkladania JSON-u do <script> tagov."a\/b"
\nU+000ANový riadok (line feed)"line\nline"
\rU+000DNávrat vozíka (carriage return)
\tU+0009Tabulátor
\bU+0008Backspace
\fU+000CZlom strany (form feed)
\u00e9éĽubovoľný znak podľa štvorciferného kódového bodu"caf\u00e9"
\ud83d\ude00😀Znak nad U+FFFF ako surrogate párJSON nemá podobu \u{…}, takže znaky nad U+FFFF potrebujú dva escapy.

JavaScript reťazce

10

Nadmnožina tých z JSON-u, plus escapy pre template literály.

EscapeZnamenáKedy ho trebaV kontexte
\''Jednoduchá úvodzovka v reťazci s jednoduchými úvodzovkami
\""Dvojitá úvodzovka v reťazci s dvojitými úvodzovkami
\``Spätný apostrof vnútri template literálu
\${${Doslovné ${ vnútri template literáluBez opačnej lomky začne interpoláciu.
\nU+000ANový riadok (line feed)
\xe9éZnak podľa dvoch hex číslic, po U+00FF
\u00e9éZnak podľa štyroch hex číslic
\u{1f600}😀Ľubovoľný kódový bod bez ohľadu na dĺžkuNepotrebuje surrogate pár, na rozdiel od štvorciferného zápisu.
\0U+0000Nulový znak
\u2028U+2028Oddeľovač riadkovV JS reťazci platný, v JSON-e nie — klasická porucha JSONP.

HTML text a atribúty

8

V texte musia byť escapované striktne len & a <; úvodzovky sú dôležité v atribútoch.

EscapeZnamenáKedy ho trebaV kontexte
&amp;&AmpersandEscapujte ho ako prvý, inak sa každý ďalší escape zdvojí.
&lt;<Znak menšie než, aby nezačal tag
&gt;>Znak väčšie než
&quot;"Dvojitá úvodzovka vnútri atribútu
&#39;'Jednoduchá úvodzovka vnútri atribútuV HTML5 funguje aj &apos;, ale číselná podoba je bezpečná všade.
&nbsp;U+00A0Nezlomiteľná medzera
&#233;éĽubovoľný znak podľa desiatkového kódového bodu
&#xE9;éĽubovoľný znak podľa hexadecimálneho kódového bodu

URL (percentové kódovanie)

9

Ktoré znaky treba escapovať, závisí od časti URL, v ktorej stoja.

EscapeZnamenáKedy ho trebaV kontexte
%20 Medzera, platná kdekoľvek v URL
+ Medzera, ale len vo form-encoded query stringuV ceste je to doslovné plus.
%25%Doslovné percentoAk ho vynecháte, hodnota sa dekóduje dvakrát.
%2F/Lomka vnútri jednej časti cesty
%3F?Otáznik vnútri hodnoty
%26&Ampersand vnútri hodnoty parametra
%3D=Rovná sa vnútri hodnoty parametra
%23#Mriežka, aby nezačala fragment
%C3%A9éZnak mimo ASCII ako jeho UTF-8 bajtyZ jedného znaku môžu byť dve, tri aj štyri percentové skupiny.

CSV polia

5

RFC 4180: pole obaľte úvodzovkami a tú vnútri zdvojte. Opačné lomky nič neznamenajú.

EscapeZnamenáKedy ho trebaV kontexte
"""Úvodzovka vnútri obaleného poľa — zdvojte ju"say ""hi"""
"a,b",Pole obsahujúce oddeľovač — obaľte pole
"a b"U+000APole obsahujúce zlom riadku — obaľte pole
" a" Zachovanie medzier na začiatku alebo konciBez obalenia ich mnohé parsery odstrihnú.
'=SUM(A1)=Zabráni tabuľkovému procesoru vykonať bunku ako vzorecPlatí pre hodnoty začínajúce =, +, - alebo @. Toto je formula injection.

SQL literály a identifikátory

6

Toto čítajte, nepíšte. Použite parametrizované dopyty.

EscapeZnamenáKedy ho trebaV kontexte
'''Úvodzovka vnútri reťazcového literálu — zdvojte ju'O''Brien'
"order"orderRezervované slovo použité ako názov stĺpcaDvojité úvodzovky sú štandard; SQL Server používa [hranaté zátvorky].
`order`orderTo isté v MySQL a MariaDB
\%%Doslovné % vnútri vzoru LIKE
\__Doslovný _ vnútri vzoru LIKE
$tag$ … $tag$'Dolárové obaľovanie v PostgreSQL — vnútri sa neescapuje vôbec ničUžitočné pre telá kódu, kde je zdvojovanie každej úvodzovky nečitateľné.

Argumenty v shelle

6

Jednoduché úvodzovky sú doslovné, dvojité stále rozvíjajú premenné.

EscapeZnamenáKedy ho trebaV kontexte
'…'$ ` \Všetko vnútri je doslovnéNajbezpečnejšie obaľovanie, aké existuje — ale nemôže obsahovať jednoduchú úvodzovku.
"…"* ? spaceGloby a medzery sú v bezpečí, premenné sa stále rozvíjajúPremenné vždy obaľujte: "$var", nikdy bez úvodzoviek.
\ Medzera v neobalenom názve súboru
\$$Doslovný znak dolára vnútri dvojitých úvodzoviek
\``Doslovný spätný apostrof, nie substitúcia príkazu
'\'''Jednoduchá úvodzovka vnútri jednoduchých úvodzoviekZavrieť, escapovať, otvoriť — priamo sa vnoriť nedá.

Časté otázky

Prečo mi JSON padá na windowsovej ceste k súboru?
Pretože opačná lomka v JSON reťazci začína escape sekvenciu, takže C:\dir sa prečíta ako C a potom neplatný escape. Správne zapísaná hodnota je "C:\\dir" — dve lomky v súbore, jedna v načítanom reťazci. Na Windowse fungujú aj dopredné lomky a problém úplne obídu.
Je pre medzeru v URL správne %20 alebo +?
Oboje, ale na inom mieste. %20 je správne kdekoľvek v URL. Plus znamená medzeru iba v query stringu kódovanom ako application/x-www-form-urlencoded — v ceste je to doslovné plus. Ak si nie ste istí, použite %20, pretože je správne všade.
Ako dám úvodzovku do CSV poľa?
Pole obaľte úvodzovkami a tú vnútornú zdvojte: "povedal ""ahoj""". Tak to určuje RFC 4180 a preto CSV plné zdvojených úvodzoviek nie je poškodené. Opačná lomka pre CSV parser neznamená nič.
Načo je ten apostrof pred vzorcom v riadku CSV?
Zneškodňuje formula injection. Bunka začínajúca na =, +, - alebo @ sa pri otvorení v tabuľkovom procesore vykoná ako vzorec, takže z hodnoty =SUM(A1) z nedôveryhodného zdroja sa stane kód. Apostrof na začiatku vynúti, aby sa bunka čítala ako text.
Mám escapovať SQL ručne?
Nie. Zdvojenie úvodzovky je tu zdokumentované preto, aby ste escapované SQL vedeli prečítať, nie aby ste ho písali — použite parametrizované dopyty a nechajte hodnotu na ovládači. Ručné escapovanie je pôvod SQL injection a neexistuje jeho verzia, ktorá by bola bezpečná už na pohľad.