Jak poprawnie uciec cytat w atrybutach HTML?

267

Mam listę rozwijaną na stronie internetowej, która pęka, gdy ciąg wartości zawiera cytat.

Wartość wynosi "asd, ale w DOM zawsze pojawia się jako pusty ciąg.

Próbowałem wszystkiego, co wiem, aby właściwie uciec z łańcucha, ale bezskutecznie.

<option value=""asd">test</option>
<option value="\"asd">test</option>
<option value="&quot;asd">test</option>
<option value="&#34;asd">test</option>

Jak renderować to na stronie, aby komunikat zwrotny zawierał poprawną wartość?

Chris
źródło
Jak generujesz stronę?
SLaks,
1
Co się stanie, jeśli użyjesz pojedynczych cudzysłowów? <option value = '"asd'> test </option>
Wim ten Brink
5
Muszę zaznaczyć, że żadna z tych odpowiedzi nie mówi, jak poprawnie uciec od ciągów znaków w celu użycia w atrybutach HTML
Rebbot
4
@reconbot Zależy to od sposobu generowania kodu HTML. Pytanie dotyczyło cytatów, więc technicznie zaakceptowana odpowiedź odpowiada na zadane pytanie. Jeśli chodzi o to, jak poprawnie uciec od ciągów, nie mam linku przydatnego w ogólnym przypadku, ale w PHP byś użył htmlentities.
Matt Browne,
możliwy duplikat sposobu umieszczania cudzysłowów w wartościach wejściowych HTML
Ciro Santilli 28 冠状 病 六四 事件 法轮功

Odpowiedzi:

343

&quot; jest właściwy sposób, trzeci z twoich testów:

<option value="&quot;asd">test</option>

Możesz zobaczyć, jak działa to poniżej, lub na jsFiddle .

alert($("option")[0].value);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select>
  <option value="&quot;asd">Test</option>
</select>

Alternatywnie możesz wyznaczyć wartość atrybutu pojedynczymi cudzysłowami:

<option value='"asd'>test</option>
Andy E.
źródło
17
Czwarta opcja OP, & # 34 ;, jest również ważnym sposobem na uniknięcie cudzysłowów. Korzyścią jest używanie numerycznych encji html zamiast encji nazwanych, ponieważ encje nazwane nie obejmują wszystkich znaków, a encje numeryczne. Pełna lista HTML4 znajduje się na stronie w3.org/TR/html4/sgml/entities.html .
atk
38
@atk: tak, &quot;odwzorowuje na ten sam znak co &#34;, ale nie ma tu żadnej korzyści z używania opcji numerycznej, ponieważ &quot;jest to zdefiniowany obiekt o nazwie. &quot;jest również łatwiejsze do zapamiętania.
Andy E,
6
Zgadzam się. W tym konkretnym przypadku łatwiej jest użyć & rdquo ;. Chciałem jedynie wskazać ogólny przypadek.
atk
4
@SIDU: zmiana go &amp;quot;a(wymienić &z &amp;)
Andy E
4
^ nieskończona pętla
Omar Meky
16

Jeśli używasz PHP, spróbuj zadzwonić htmlentitieslub htmlspecialcharszadziałać.

Łukasz Czerwiński
źródło
2
samo ich użycie może nie wystarczyć, spróbuj <option value='<?php echo htmlentities("' onmouseover='alert(123);' foo='"); ?>' />- upewnij się, że używasz go z ENT_QUOTES, jest to bezpieczne: <option value='<?php echo htmlentities("' onmouseover='alert(123);' foo='", ENT_QUOTES); ?>' /> ale oprócz ENT_QUOTES powinieneś również dodać ENT_SUBSTITUTE i ENT_DISALLOWED, osobiście używam tego opakowania od lat:function hhb_tohtml(string $str):string { return htmlentities($str, ENT_QUOTES | ENT_HTML401 | ENT_SUBSTITUTE | ENT_DISALLOWED, 'UTF-8', true); }
hanshenrik
12

Zgodnie ze składnią HTML , a nawet HTML5 , wszystkie prawidłowe opcje są następujące:

<option value="&quot;asd">test</option>
<option value="&#34;asd">test</option>
<option value='"asd'>test</option>
<option value='&quot;asd'>test</option>
<option value='&#34;asd'>test</option>
<option value=&quot;asd>test</option>
<option value=&#34;asd>test</option>

Zauważ, że jeśli używasz składni XML, cudzysłowy (pojedyncze lub podwójne) są wymagane.

Oto jsfiddle pokazujący wszystkie powyższe działające .

aij
źródło
7

Inną opcją jest zastąpienie podwójnych cudzysłowów pojedynczymi cudzysłowami, jeśli nie masz nic przeciwko. Ale nie wspominam o tym:

<option value='"asd'>test</option>

Wspominam o tym:

<option value="'asd">test</option>

W moim przypadku skorzystałem z tego rozwiązania.

csonuryilmaz
źródło
9
Ale jeśli wartość zawiera pojedyncze i podwójne cudzysłowy, to się nie powiedzie
Raptor
@Raptor Powiedziałem, że jeśli wartość zawiera podwójne cudzysłowy, przekonwertuj je na pojedyncze cudzysłowy. Jeśli wartość zawiera pojedyncze cudzysłowy, nie będzie problemu.
csonuryilmaz
0

Naprawdę powinieneś dopuszczać tylko niezaufane dane do białej listy dobrych atrybutów, takich jak: wyrównaj, alink, alt, bgcolor, border, pad do komórek, odstępy między komórkami, klasa, kolor, cols, colspan, coords, dir, face, height, hspace, ismap, lang , marginheight, marginwidth, multiple, nohref, noresize, noshade, nowrap, ref, rel, rev, wiersze, rozpiętość wierszy, przewijanie, kształt, zakres, podsumowanie, tabindex, tytuł, usemap, valign, wartość, vlink, vspace, szerokość

Naprawdę chcesz ukryć niezaufane dane w procedurach obsługi javascript, a także w atrybutach id lub name (mogą blokować inne elementy w DOM).

Ponadto, jeśli umieszczasz niezaufane dane w atrybucie SRC lub HREF, to jest to naprawdę niezaufany adres URL, więc powinieneś sprawdzić poprawność adresu URL, upewnić się, że NIE jest to JavaScript: URL, a następnie kodowanie encji HTML.

Więcej szczegółów na temat wszystkich dostępnych tutaj: https://www.owasp.org/index.php/Abridged_XSS_Prevention_Cheat_Sheet

Jim Manico
źródło
3
Wiem, że jest późno, ale prawie wszystkie te atrybuty są przestarzałe w HTML4.01 i usunięte w 5. To i tak może teraz nie mieć znaczenia, ponieważ istnieją lepsze sposoby na ochronę siebie, po prostu wskazując to.
trysis
1
Pytanie dotyczy danych zawierających znaki cudzysłowu, a nie danych niezaufanych.
Quentin
-3

Nie ma sposobu na uniknięcie cudzysłowów w wartości tekstu wejściowego ... ale możesz użyć javascript (lub jquery):

<input type="input" name="myinput" id="myinput" value="" />
<script>document.getElementById("myinput").value="This input has a [\"]";</script>
Miguel
źródło
1
Twoje stwierdzenie „Nie ma sposobu na uniknięcie cudzysłowów w wartości tekstu wejściowego” jest po prostu błędne. Zobacz zaakceptowaną odpowiedź z 2010 roku, która uzyskała 276 głosów.
Quentin
Odpuść mi Quentin, ale ODPOWIEDŹ mówi, że nie jest to możliwe. Mówi, że możesz wstawić podwójny cudzysłów z kodem HTML lub możesz użyć prostego cudzysłowu do ograniczenia podwójnego cudzysłowu, ale nie jest możliwe wstawienie podwójnego cudzysłowu do wartości zdefiniowanej za pomocą podwójnego cudzysłowu. Proponuje alternatywę dla czegoś niemożliwego, co jest tym samym, co robię
Miguel,
Aby wstawić podwójny cudzysłów do wartości rozdzielonej podwójnym cudzysłowem, należy użyć kodowania HTML, jak właśnie powiedziałeś.
Quentin,
(Cześć Quentin ... jesteśmy online) Mówię tylko, że wartość tego ciągu nie jest podwójnym cudzysłowiem, jest „,”, to nie to samo.
Miguel
2
Jeśli wstawisz & quot; w wartości i wysyłasz ją, na serwerze otrzymujesz 6 znaków, od & do ;. Nie otrzymujesz podwójnej wyceny. To nie jest to samo i dla mnie nie działa
Miguel