Przejdź do treści

Sekwencje escapowania

Prawie każdy błąd escapowania to błąd kontekstu, a nie błąd składni. Znak jest znany — cudzysłów, backslash, ampersand — i to, co jest niejasne, to która z sześciu sprzecznych zasad stosuje się tam, gdzie string ląduje.

Tak więc ta tabela jest zorganizowana po kontekście, a nie po znaku. Ten sam cudzysłów jest podwojony w komórce CSV, escapowany backslashem w JSON, zamieniony na " w HTML i całkowicie pozostawiony w spokoju wewnątrz pojedynczych cudzysłów w shell. Cztery wiersze, cztery zasady, jeden znak.

Zasada, która ma znaczenie większość, to ta, którą ludzie sięgają po ostatnią: escapuj na granicy, którą wartość przekracza, i escapuj ją raz. Tekst escapowany dwa razy — & w źródle strony, \\n w pliku wyjściowym — to sygnatura wartości, która przeszła przez dwóch koderów, którzy każdy zakładali, że są pierwsi.

Łańcuchy JSON

10

JSON pozwala dokładnie na te escapowania. Dosłowny newline lub tab wewnątrz łańcucha jest nieprawidłowy.

EscapowanieOznaczaKiedy tego potrzebujeszW kontekście
\""Podwójny cudzysłów wewnątrz łańcucha"say \"hi\""
\\\Dosłowny backslashPowód, dla którego ścieżki Windows łamią JSON."C:\\dir"
\//Slash do przodu — opcjonalnieLegalne, ale niepotrzebne; nawyk z osadzania JSON w <script> tagach."a\/b"
\nU+000APodawaj w sobie"line\nline"
\rU+000DPowrót karetki
\tU+0009Tabulacja
\bU+0008Backspace
\fU+000CPodawaj się
\u00e9éDowolny znak wg jego czterocyfrowego punktu kodu"caf\u00e9"
\ud83d\ude00😀Znak powyżej U+FFFF, jako para zastępczaJSON nie ma formy \u{…}, więc znaki astralne wymagają dwóch escapowań.

Łańcuchy JavaScript

10

Nadzbiór JSON, plus ucieczki szablonu dosłownego.

EscapowanieOznaczaKiedy tego potrzebujeszW kontekście
\''Pojedynczy cudzysłów wewnątrz jednokrotnie cytowanego łańcucha
\""Podwójny cudzysłów wewnątrz dwukrotnie cytowanego łańcucha
\``Backtick wewnątrz szablonu dosłownego
\${${Dosłowny ${ wewnątrz szablonu dosłownegoBez backslasha to rozpoczyna interpolację.
\nU+000APodawaj w sobie
\xe9éZnak według dwóch cyfr hex, aż do U+00FF
\u00e9éZnak czterema cyframi szesnastkowymi
\u{1f600}😀Dowolny punkt kodu, jednak długiNie potrzebuje pary zastępczej, w przeciwieństwie do czterocyfrowej formy.
\0U+0000Znacz zero
\u2028U+2028Separator wierszaPrawidłowy w łańcuchu JS, ale nie w JSON — klasyczne JSONP uszkodzenie.

Tekst HTML i atrybuty

8

Tylko & i < ściśle muszą być escapowane w tekście; cudzysłowy mają znaczenie wewnątrz atrybutów.

EscapowanieOznaczaKiedy tego potrzebujeszW kontekście
&amp;&AmpersandEscapuj ten pierwszy, inaczej co drugi escape się podwaja.
&lt;<Mniej niż logika, więc nie zaczyna tagu
&gt;>Większa niż logika
&quot;"Podwójny cudzysłów wewnątrz atrybutu
&#39;'Pojedynczy cudzysłów wewnątrz atrybutu&apos; także działa w HTML5, ale forma liczbowa jest bezpieczna wszędzie.
&nbsp;U+00A0Spacja nierdzenna
&#233;éDowolny znak przez dziesiętkowy punkt kodowy
&#xE9;éDowolny znak przez szesnastkowy punkt kodowy

Adresy URL (kodowanie procentowe)

9

Które znaki wymagają escapowania, zależy od części adresu URL, w której siedzi.

EscapowanieOznaczaKiedy tego potrzebujeszW kontekście
%20 Spacja, prawidłowa w dowolnym miejscu w adresie URL
+ Spacja, ale tylko w łańcuchu zapytania zakodowanego w postaciW segmencie ścieżki to dosłowny znak plus.
%25%Dosłowny znak procentPomiń to i wartość dekoduje się dwa razy.
%2F/Slash wewnątrz segmentu pojedynczej ścieżki
%3F?Znak zapytania wewnątrz wartości
%26&Ampersand wewnątrz wartości parametru
%3D=Znak równości wewnątrz wartości parametru
%23#Hash, więc nie zaczyna fragmentu
%C3%A9éZnak nie-ASCII, ponieważ jego bajty UTF-8Jeden znak może stać się dwema, trzema lub czterema grupami procentów.

Pola CSV

5

RFC 4180: opatruj pole w cudzysłowy, a następnie podwój każdy cudzysłów wewnątrz niego. Backslashe nie znaczą nic.

EscapowanieOznaczaKiedy tego potrzebujeszW kontekście
"""Cudzysłów wewnątrz cytowanego pola — podwój go"say ""hi"""
"a,b",Pole zawierające ogranicznik — opatruj pole
"a b"U+000APole zawierające przerwę wiersza — opatruj pole
" a" Zachowaj spacje wiodące lub końcoweNiecytowany, wielu parserów je tnie.
'=SUM(A1)=Zatrzymaj komórkę arkusza kalkulacyjnego wykonującą się jako formułaDotyczy wartości zaczynających się =, +, - lub @. To jest iniekcja formuły.

Literały SQL i identyfikatory

6

Czytaj je; nie pisz ich. Zamiast tego użyj sparametryzowanych zapytań.

EscapowanieOznaczaKiedy tego potrzebujeszW kontekście
'''Cudzysłów wewnątrz dosłownika łańcucha — podwój go'O''Brien'
"order"orderZastrzeżone słowo używane jako nazwa kolumnyPodwójne cudzysłowy to standard; SQL Server używa [nawiasów].
`order`orderTo samo w MySQL i MariaDB
\%%Dosłowna % wewnątrz wzoru LIKE
\__Dosłowny _ wewnątrz wzoru LIKE
$tag$ … $tag$'PostgreSQL cytuje dolar — bez escapowania wewnątrz w ogólePrzydatne dla ciał kodu, gdzie podwojenie każdego cudzysłowu jest nieczytelne.

Argumenty Shell

6

Pojedyncze cudzysłowy to dosłowne, podwójne cudzysłowy wciąż rozszerzają zmienne.

EscapowanieOznaczaKiedy tego potrzebujeszW kontekście
'…'$ ` \Wszystko wewnątrz jest dosłowneNajbezpieczniejsze cytowanie, które istnieje — ale nie może zawierać pojedynczych cudzysłowów.
"…"* ? spaceGloby i spacje są bezpieczne, zmienne wciąż się rozszerzająAlways quote variables: "$var", never bare $var.
\ Spacja w niecytowanej nazwie pliku
\$$Dosłowny znak dolara wewnątrz podwójnych cudzysłowów
\``Dosłowny backtick, nie podstawienie polecenia
'\'''Pojedynczy cudzysłów wewnątrz jednokrotnie cytowanychZamknij, escapuj, otwórz ponownie — nie ma sposobu, aby go zagnieżdżać bezpośrednio.

Częste pytania

Dlaczego mój JSON się załamuje na ścieżce pliku Windows?
Ponieważ backslash rozpoczyna sekwencję escapowania w łańcuchu JSON, więc C:\dir jest czytany jako C, a następnie nieprawidłowy escape. Prawidłowo napisana wartość to "C:\\dir" — dwa backslashe w pliku, jeden w przeanalizowanym łańcuchu. Slashe przednie pracują również na Windows i całkowicie unikają problemu.
Czy %20 czy + jest poprawne dla spacji w adresie URL?
Oba, w różnych miejscach. %20 jest poprawne w dowolnym miejscu adresu URL. Znak plus oznacza spację tylko wewnątrz ciągu zapytania zakodowanego jako application/x-www-form-urlencoded — w segmencie ścieżki jest to dosłowny plus. Użyj %20, gdy nie jesteś pewny, ponieważ jest to prawidłowe wszędzie.
Jak umieścić cudzysłów wewnątrz pola CSV?
Opatruj pole w cudzysłowy i podwój wewnętrzny: "powiedz ""cześć""". To RFC 4180, i to jest powód, dla którego CSV pełny podwojonych cudzysłów nie jest uszkodzony. Backslash nie oznacza niczego dla zgodnego parsera CSV.
Czemu apostrof wiodący w wierszu formuły CSV?
Zapobiega iniekcji formuły. Komórka zaczynająca się od =, +, - lub @ jest wykonywana jako formuła, gdy plik jest otwarty w arkuszu kalkulacyjnym, więc wartość taka jak =SUM(A1) z niezaufanego źródła staje się kodem. Poprzedzenie apostrofem wymusza, aby komórka była czytana jako tekst.
Czy powinienem escapować SQL ręcznie?
Nie. Podwojenie cudzysłowu jest dokumentowane tutaj, ponieważ musisz czytać escapowany SQL, a nie go pisać — użyj sparametryzowanych zapytań i pozwól kierowcy obsługować wartość. Ręczne escapowanie to skąd pochodzi iniekcja SQL, i nie ma wersji tego, które byłyby bezpieczne przez inspekcję.