XSS açıkları değil UTF-8 karakter

2 Cevap php

I'm looking at encoding strings to prevent XSS attacks. Right now we want to use a whitelist approach, where any characters outside of that whitelist will get encoded. Right now, we're taking things like '(' and outputting '(' instead. As far as we can tell, this will prevent most XSS.

Sorun uluslararası kullanıcıların bir sürü var olduğunu, ve tüm site japon içinde olduğunda, kodlama büyük bir bant genişliği domuz olur. Bu temel ASCII setinin dışında herhangi bir karakter bir açığı değildir ve onlar kodlanmış olması gerekmez, ya da hala kodlanmış gereken ASCII kümesi dışında bir karakter olduğunu söylemek için güvenli midir?

2 Cevap

Sadece için kodlama geçirirseniz (çok) kolay olabilir htmlentities() / htmlspecialchars

echo htmlspecialchars($string,  ENT_QUOTES, 'utf-8');

Bu yeterli olup olmadığını Ama baskı konum ne bağlıdır (ve burada).

see also:
http://shiflett.org/blog/2005/dec/googles-xss-vulnerability
http://jimbojw.com/wiki/index.php?title=Sanitizing_user_input_against_XSS
http://www.erich-kachel.de/?p=415 (in german. If I find something similar in English -> update) edit: well, I guess you can get the main point without being fluent in german ;) The string

javascript:eval(String.fromCharCode(97,108,101,114,116,40,39,88,83,83,39,41)) 
passes htmlentities() unchanged. Now consider something like
<a href="<?php echo htmlentities($_GET['homepage']); ?>"
which will send
<a href="javascript:eval(String.fromCharCode(97,108,101,114,116,40,39,88,83,83,39,41))">
to the browser. And that boils down to
href="javascript:eval(\"alert('XSS')\")"
While htmlentities() gets the job done for the contents of an element, it's not so good for attributes.

Genel olarak, evet, bir şey "güvenli" olması için ASCII olmayan bağlı olabilir, ancak dikkate alınması gereken bazı very important uyarılar vardır:

  1. Always ensure that what you're sending to the client is tagged as UTF-8. This means having a header that explicitly says "Content-Type: text/html; charset=utf-8" on every single page, including all of your error pages if any of the content on those error pages is generated from user input. (Many people forget to test their 404 page, and have that page include the not-found URL verbatim)
  2. Always ensure that what you're sending to the client is valid UTF-8. This means you cannot simply pass through bytes received from the user back to the user again. You need to decode the bytes as UTF-8, apply your html-encoding XSS prevention, and then encode them as UTF-8 as you write them back out.

Bu iki uyarılar ilk yüksek harfli karakterler de dahil olmak üzere ve geri bazı yerel çokbaytlı karakter kümesine düşen bir sürü şeyler görmeye gelen müşterinin tarayıcı tutmaktır. Yerel çoklu-bayt karakter kümesi karşı savundum olmaz zararlı ASCII karakterleri belirtmek için birden fazla yol olabilir. Bu konuyla ilgili olarak, bazı tarayıcılar bazı eski sürümleri - cough, yani cough - Bir sayfa UTF-7 olduğu tespit biraz overeager vardı; Bu XSS olanakları yok sonuna kadar açılır. Bu karşı savunmak için, emin html kodlamak herhangi giden "+" işareti yapmak isteyebilirsiniz; Bu size doğru Content-Type başlıklarını üreten yaparken aşırı paranoya olduğunu, ancak bazı gelecek kişinin özel başlıkları kapatan bir anahtar atıldığında sizi kurtaracak. (Örneğin, app önünde kötü yapılandırılmış bir önbelleğe alma ters proxy koyarak, ya da ekstra bir afiş başlık eklemek için bir şey yaparak - php herhangi bir çıkış zaten yazılmış ise herhangi bir HTTP başlıklarını ayarlamak izin vermez)

Cari özellikleri kapsamında geçersiz iken, ASCII karakter olarak eski tarayıcılar tarafından yorumlanır, "aşırı kısa" dizileri belirtmek için UTF-8 mümkündür olanlar nedeniyle ikinci. (See what wikipedia has to say) Ayrıca, birisi bir istek içine bir tek kötü bir bayt eklemek olasıdır; Eğer kullanıcı bu paketi geçerse, bazı tarayıcılar ile ondan sonra kötü bayt ve bir veya daha fazla byte hem yerini neden olabilir "?" ya da başka bir karakter "Bu anlayamadık". Yani bir tek kötü bayt bazı iyi bayt da yutulacak neden olabilir, olduğunu. Eğer çıkış konum ne yakından bakarsanız, çıktı dışarı bir byte veya iki silmek başardı saldırganın bazı XSS ​​yapabileceği bir yerde bir nokta muhtemelen var. UTF-8 olarak girdi çözme ve yeniden kodlama bu saldırı vektörü engeller.