XSS Güvenlik İlkeleri !
Markanız için 300X300 alan.
XSS Güvenlik İlkeleri; XSS saldırılarına karşı alınan önlemlerin bütününü ifade eder. XSS saldırıları çok can yakıcı olmakla birlikte kolaylıkla önlenebilen saldırılardır. Bu XSS Güvenlik İlkeleri sayfanın anlaşılabilmesi için Aşılama Teorisi ve XSS - Cross Site Scripting sayfaları iyi anlaşılmış olmalı.
XSS sayfalarının uzunluğu gözünüzü korkutmasın. Mantığı anlayıp 2, 3 tane kuralı uyguladığınızda saldırıların neredeyse tamamını atlatmış sayılırsınız.
Kullanıcılardan gelen verilere ne tarayıcı ne de sunucu tarafında asla güvenilmez. Buna, sunucuya gönderilen başlık bilgileri (HTTP Header) ve benzeri de dahildir. Kullanıcıdan gelen her veri hem tarayıcı hem de sunucu tarafında titizlikle denetlenmeli.
Genel olarak; denetimlerde #1 ve #2 numaralı kurallar yeterli görülse de dikkatli olunmalı ve gerekiyorsa diğer kurallar da uygulanmalı.
Sunucu ya da tarayıcı tarafında olması fark etmez eğer saldırı belirlendiyse tamga dönüştürmek ya da zararlı tamgaları (ya da içeriği) uzaklaştırmak yerine işlem tümüyle sonlandırılmalıdır.
Eğer bu yapılamıyorsa (örneğin benim kullanıcılarım yorum bölümüne <script>
yazabilmeliler) o zaman dönüştürme ya da -yerine göre- arındırma işlemi uygulanmalıdır.
Aşağıda listesi olup XSS Güvenlik İlkeleri kapsamında dönüştürülmesi önerilen tamgalar yalnızca örnektir. Dönüştürme ya da arındırma işlemlerinde yalnızca aşağıdaki tamgalarla sınırlı kalmak istemeyebilirsiniz.
XSS Güvenlik İlkeleri - Kural 0 - İzin Verilen Yerler Dışında Kalan Hiç Bir Yere Güvenilmeyen Veri Eklemeyin
XSS Güvenlik İlkelerinin ilk kuralı: Hepsini reddet. Güvenilmeyen içerik Kural 1 ve Kural 5 uygulanmadığı sürece belgeye eklenmemeli. XSS Güvenlik İlkeleri kural 0'ın nedeni HTML'de kaçış kurallarının çok karmaşık olabileceği bir çok yabancı içerik var. Güvenilmeyen içeriğin belgeye yerleştirilmesi için hiç bir iyi gerekçe bulunmuyor. Buna JavaScript'teki URL
'ler de dahil.
Encode kuralları bu tür durumlarda hileli ve oldukça zorlu. Belgeye eğer güvenilmeyen içerik eklenecekse farklı tarayıcılarda çaprazlama denetim yapılmalı.
<script>
...GÜVENİLMEYEN VERİYİ BURAYA ASLA KOYMA...</script>
- Doğrudan betiğe<!--
...GÜVENİLMEYEN VERİYİ BURAYA ASLA KOYMA...-->
- HTML yorumlarına<div
...GÜVENİLMEYEN VERİYİ BURAYA ASLA KOYMA...=test
/>
- Öznitelik adı olarak<
GÜVENİLMEYEN VERİYİ BURAYA ASLA KOYMA...href="/test"
/>
- Etiket adı olarak<style>
...GÜVENİLMEYEN VERİYİ BURAYA ASLA KOYMA...</style>
- Doğrudan CSS
En önemlisi kaynağına güvenilmeyen JavaScript kodları asla kabul edilmemeli, çalıştırılmamalı.
Örnek olarak callback
değişkeni içeren JavaScript kod snippetleri -tümüyle arındırılamayacağından- tehlikelidir. Güvenilmiyorlarsa hiç kullanılmamalılar.
XSS Güvenlik İlkeleri - KURAL 1 - HTML Etiketlerine Güvenilmeyen Veri Eklerken HTML Kaçışı
XSS Güvenlik İlkelerinin #1 numaralı kuralı güvenilmeyen verinin belgeye ekleneceği durumlarda kullanılıyor. Bu <div>
, <p>
, <span>
gibi gibi olağan HTML etiketlerini kapsar.
<body>
...GÜVENİLMEYEN VERİ BURAYA EKLENMEDEN ÖNCE KAÇILMALI...</body>
<span>
...GÜVENİLMEYEN VERİ BURAYA EKLENMEDEN ÖNCE KAÇILMALI...</span>
Betik, tasarım ve olay gibi içeriklerin çalıştırılmasını önlemek için zararlı olabilecek bazı tamgalar özellikle (ve hatta kesinlikle) dönüştürülmeli.
&
-->&
<
--><
>
-->>
"
-->"
'
-->'
-'
önerilmiyor çünkü HTML yönergelerinde değil de XML ve XHTML yönergelerinde bulunuyor. (Bkz: Bölüm 24.4.1)/
-->/
- İleri yatık çizgi HTML entity'lerin kapatılmasına yardımcı oluyor.
XSS Güvenlik İlkeleri - KURAL 2 - HTML Özniteliklerine Güvenilmeyen Veri Eklerken Öznitelik Kaçışı
XSS Güvenlik İlkelerinin #2 numaralı kuralı width
ve name
gibi HTML özniteliklerine uygulanır. href
, src
, style
gibi karmaşık özniteliklere ya da olaylara atanacak değerler için KURAL 3'ün uygulanması aşırı derecede önemli.
<div attr=...GÜVENİLMEYEN VERİ BURAYA EKLENMEDEN ÖNCE KAÇILMALI...>İçerik</div>
- Tırnaklanmamış özniteliğin içine<div attr='...GÜVENİLMEYEN VERİ BURAYA EKLENMEDEN ÖNCE KAÇILMALI...'>İçerik</div>
- tek tırnaklı özniteliğin içine<div attr="...GÜVENİLMEYEN VERİ BURAYA EKLENMEDEN ÖNCE KAÇILMALI...">İçerik</div>
- çift tırnaklı özniteliğin içine
Abecesayısal tamgalar dışındaki tamgaların ASCII değerleri 256'dan daha düşük ise atanmadan önce -varsa kendi entity adları ile yoksa- &#xHH
ile değiştirilerek özniteliğin dönüştürülmesi önlenir. Bunun nedeni özniteliklerin yazımında "
(çift tırnak -ya da tırnak '
-) imi kullanılmadığı durumlarda oluşacak taşmayı engellemektir. Uygun biçimde tırnaklanan öznitelikler aynı uygunluktaki tırnak ile kapatılırlar. Öznitelik tırnaklanmazsa [beyaz boşluk] % * + , - / ; < = > ^
ve |
dahil bir çok tamga ile kapatılabilirler.
Öznitelik kapatıldıktan sonra ardından gelen aşılama ile saldırı başarıya ulaşacağından özniteliklerin güvensiz verilerindeki tamgaların dönüştürülmesi ile saldırı önlenir.
XSS Güvenlik İlkeleri - KURAL 3 - Güvenilmeyen Veriyi JavaScript'te Değer Olarak Atarken JavaScript Kaçışı
XSS Güvenlik İlkelerinin #3 numaralı kuralına göre dinamik olarak oluşturulan JavaScript betik bloklarına ve olay özniteliklerine arındırılmış veri ekleniyorsa eklenen veri kesinlikle tırnak içine alınmış "veri" olmalıdır. JavaScript'te, eklenen güvenilmeyen veri ; = [beyaz boşluk] +
dahil -ancak bunlarla sınırlı olmamak üzere- yürütmeye (execute) neden olacağından ötürü tümüyle tehlikeli olup, dikkatle kullanılmalıdır.
<script>alert('...GÜVENİLMEYEN VERİ BURAYA EKLENMEDEN ÖNCE KAÇILMALI...')</script>
- Tırnak içinde metin içinde<script>x='...GÜVENİLMEYEN VERİ BURAYA EKLENMEDEN ÖNCE KAÇILMALI...'</script>
- Tek tarafı tırnaklanmış deyiş içinde<div onmouseover="x='...GÜVENİLMEYEN VERİ BURAYA EKLENMEDEN ÖNCE KAÇILMALI...'"</div>
- Tırnaklanmış olay işleyicisi içinde
Unutmayın ki güvenilmeyen verinin asla güvenli olarak kullanılamayacağı JavaScript işlevleri de vardır - GÜVENLİ BİÇİMDE KAÇILMIŞ OLSALAR BİLE !
<script>
window.setInterval('...BAŞARILI BİÇİMDE KAÇSANIZ BİLE XSS SALDIRISI BAŞARIYA ULAŞIR. ÇAPRAZLANDINIZ !...');
</script>
- Abecesayısal tamgalar dışındaki tamgaların ASCII değerleri 256'dan daha düşük ise değer olarak ya da başka bir özniteliğe atanmadan önce
\xHH
ile değiştirilmeli. \"
gibi kaçışlar kullanılmamalı çünkü öncelikli olarak HTML öznitelik ayrıştırıcısı çalışır ve"
imi eşleşir.\"
gibi kaçışlardan ayrıca kaçınılmalı çünkü "escape-the-escape" yani "kaçıştan kurtul" saldırılarıyla saldırgan\"
kodunu gönderirse bu\\"
biçimine dönüşerek"
imine izin verilmiş olur.
Eğer bir olay işleyicisi uygun biçimde tırnaklanırsa kapatılmaları aynı uygunluktaki tırnak ile gerçekleşir. Olay işleyicileri ne yazık ki genellikle tırnakla kullanılmıyorlar. Tırnaksız kullanılan olay dinleyicileri [beyaz boşluk] % * + , - / ; < = > ^
ve |
dahil daha bir çok tamga ile kapatılabilirler. Ayrıca tırnak kullanılmış olsa bile kapatan etiketlerden olan </script>
de betik bloğunu kapatır çünkü HTML ayrıştırıcı JavaScript ayrıştırıcıdan önce çalışır.
Her zaman her yerde uygun olmasa da verileri AJAX kullanarak JSON olarak alıp yasak &
zararlı tamgaları kaçmak işe yarayabilir.
XSS Güvenlik İlkeleri - KURAL 3.1 - JSON değerlerinde HTML Kaçışı
Veri eğer JSON ile alınıyorsa HTTP başlık bilgisi
Content-Type: text/html; charset=UTF-8
yerine
Content-Type: application/json; charset=UTF-8
olmalıdır. Böylece yanıtla gelen <script></script>
bloğu gibi zararlı veri tarayıcı tarafında çalıştırılmaz.
<script>
var initData = <%= JSON_a_çevrilen_veri %>; // Bu kullanım yanlıştır. Aşağıdaki yöntemlerden birini kullanın.
</script>
JSON entity tamgaları Çıktı Encode Kuralları Özeti'nde gösterildiği gibi dönüştürülmeli.
ya da
HTML entity dönüşümü için içerik bir etikete yazılmalı ve bu etiketin textContent
'i değişkene atanmalı ya da sunucu tarafında '<
' tamgası '\u003c
' ile değiştirilmeli.
XSS Güvenlik İlkeleri - KURAL 4 - HTML Style Özellik Değerlerine Güvensiz Veri Atamada CSS Kaçışı ve Sıkı Onaylama
CSS (Cascading Style Sheet - Kalıtsal Biçim Dosyaları) güçlüdür. Bu yüzden XSS Güvenlik İlkeleri doğrultusunda güvenlik önlemleri alınmalı. Güvenilmeyen veri yalnızca ve yalnızca değer olarak atanmalı. Biçim dosyasında başka hiç bir yerde güvensiz veri kullanılmamalı.
url
, behavior
, ve özel (-moz-
özeli gibi) özelliklerde güvensiz veri kullanımından kaçınılmalıdır. Ayrıca -JavaScript çalıştırabildiğinden ötürü- IE şablonlarında (şablon = RegExp) güvensiz veri kullanımından kaçınılmalıdır.
Unutulmamalı ki bazı CSS özellikleri güvensiz verileri asla değer olarak almazlar - CSS KAÇIŞLARI DÜZGÜNCE GERÇEKLEŞTİRİLMİŞ OLSA BİLE -
URL
'lerin yalnızca http
ile başladığını (Javascript
ya da expression
ile değil) unutmayın.
- Abecesayısal tamgalar dışındaki tamgaların ASCII değerleri 256'dan daha düşük ise atanmadan önce
\HH
ile değiştirilmeli. \"
gibi kaçışlar kullanılmamalıdır çünkü HTML öznitelik çözümleyicisi daha önce çalışarak"
imini daha önce görebilir.- Ayrıca
\"
gibi kaçışlardan kaçınılmalı çünkü "escape-the-escape" yani "kaçıştan kurtul" saldırılarıyla saldırgan\"
kodunu gönderirse bu\\"
biçimine dönüşerek"
imine izin verilmiş olur. - Tırnak imi özniteliklerde kullanılmış olmalı. Buna rağmen
</style>
etiketi özniteliğin değerini sonlandırabilir çünkü HTML çözümleyici JavaScript çözümleyiciden önce çalışır. - Tırnak kullanılsa da kullanılmasa da saldırgan derecede (aşırı önlemci bir biçimde) XSS saldırı önlemleri alınması önerilir.
XSS Güvenlik İlkeleri - KURAL 5 - HTML URL Değişken Değerlerine Güvenilmeyen Veri Eklemeden Önce URL Kaçışı
XSS Güvenlik İlkelerinin #5 numaralı kuralına göre; URL
'lerde de GET için kullanılan sorgu satırlarında (sunucuya gönderilen istek satırlarında) kullanılan kaçış için kullanılır.
Abecesayısal tamgalar dışındaki tamgaların ASCII değerleri 256'dan daha düşük ise atanmadan önce \HH
ile değiştirilmeli.
URL
'lerde entity kullanımının bir yararı yoktur.
Tüm özniteliklerde "
imi kullanılmalı.
URL
'ler tümüyle ya da göreli URL
'ler encode işleminden geçirilmemeli. Çünkü href
ya da src
gibi öznitelikler beklenmeyen protokollere karşı denetimden geçirilmeliler, özellikle JavaScript bağlantıları.
URL
'ler de diğer sıradan veri biçimleri gibi, uygun biçimde encode edilmeli (örneğin href
öznitelikleri öznitelik kuralına bağlı olarak, içerik ise içerik kuralına bağlı olarak vb...).
XSS Güvenlik İlkeleri - KURAL 6 - İşe Uygun Tasarlanmış Bir Kütüphüne ile HTML İçeriği Arındırılmalı
Güvenli ve güvensiz verilerin bir arada kullanıldığı durumlarda güvenli veride HTML etiketleri kullanılıyorsa güvensiz verilerdeki HTML etiketlerini ayıklamak çok zordur.
Dikkatli olunmalı ve gerekiyorsa farklı yazılımlardan yardım alınmalı.
XSS Güvenlik İlkeleri - KURAL 7 - DOM Tabanlı XSS'in Önlenmesi
DOM tabanlı XSS'in engellenmesi için DOM Tabanlı XSS sayfasına bakın.
XSS Güvenlik İlkeleri - BONUS KURAL 1 - HTTPOnly
Çerez Bayrakları
Çerezlerde HTTPOnly
çerez bayraklarının etkinleştirilmesi çerezlerin (JavaScript gibi) betiklerin yardımıyla okunmasını, silinmesini ve değiştirilmesini engeller.
HTTPOnly
bayrağı etkin çerezler, JavaScript kodlarına karşı görünmez olurlar.
XSS Güvenlik İlkeleri - BONUS KURAL 2 - İçerik Güvenlik İlkesi Oluşturulmalı
İçerik Güvenlik İlkesi (CSP - Content Security Policy); tarayıcı tarafında sayfanın hangi kökenlerle (veb siteleri ile) iletişim kurabileceğini (kaynak paylaşılabileceğini) belirler.
XSS Güvenlik İlkeleri - BONUS KURAL 3 - Kendiliğinden-Kaçan Hazır Kodlardan Yararlanın
XSS Güvenlik İlkeleri doğrutulsunda, zararlı olabilecek içeriğe karşı hazır kodlardan yararlanılabilir.
XSS Güvenlik İlkeleri - BONUS KURAL 4 - X-XSS-Protection
Yanıt Başlığını Kullanın
X-XSS-Protection
yanıt başlığı; XSS'e karşı filtresi bulunan çağdaş tarayıcılardaki zaten etkin olan güvenlik önlemlerini eğer bu XSS güvenlik önlemleri kullanıcı tarafından elle kapatıldıysa yalnızca bu başlığı kullanan veb sitesi için yeniden etkinleştirir.
XSS Önleme Kuralları
Aşağıdaki dizelge -XSS Güvenlik İlkeleri kapsamında- güvenilmeyen verileri yerlerine uygun biçimde yerleştirmenizde size yol gösterici olacaktır.
Veri Türü | Kullanım Biçimi | Kod Örneği | Savunma |
---|---|---|---|
Metin | HTML Gövdesi | <span>Güvenilmeyen İçerik</span> |
HTML Entity Encoding |
Metin | Güvenli HTML Öznitelikleri | <input type="text" name="dosyaAdı" value="Güvenilmeyen İçerik"> |
Aggressive HTML Entity Encoding Only place untrusted data into a whitelist of safe attributes (listed below). Strictly validate unsafe attributes such as background, id and name. |
Metin | GET Değişkeni | <a href="/site/ara?value=Güvenilmeyen İçerik">tıklaBana</a> |
URL Encoding |
Metin | src ya da href özniteliğinde Güvenilmeyen URL |
<a href="Güvenilmeyen URL">BanaTıkla</a> <iframe src="Güvenilmeyen URL"> |
Canonicalize input URL Validation Safe URL verification Whitelist http and https URL's only (Avoid the JavaScript Protocol to Open a new Window) Attribute encoder |
Metin | CSS Değeri | <div style="width: Güvenilmeyen İçerik;">Seçim</div> |
Strict structural validation CSS Hex encoding Good design of CSS Features |
Metin | JavaScript Değişkeni | <script>var şuankiDeğer='Güvenilmeyen İçerik';</script> <script>Birİşlev('Güvenilmeyen İçerik');</script> |
Ensure JavaScript variables are quoted JavaScript Hex Encoding JavaScript Unicode Encoding Avoid backslash encoding (\" or \' or \\) |
HTML | HTML Body | <div>Güvenilmeyen HTML</div> |
HTML Validation (JSoup, AntiSamy, HTML Sanitizer) |
Metin | DOM XSS | <script>document.write("Güvenilmeyen Girdi: " + document.location.hash);</script> |
DOM based XSS Prevention Cheat Sheet |
Güvenli HTML Öznitelikleri : align
, alink
, alt
, bgcolor
, border
, cellpadding
, cellspacing
, class
, color
, cols
, colspan
, coords
, dir
, face
, height
, hspace
, ismap
, lang
, marginheight
, marginwidth
, multiple
, nohref
, noresize
, noshade
, nowrap
, ref
, rel
, rev
, rows
, rowspan
, scrolling
, shape
, span
, summary
, tabindex
, title
, usemap
, valign
, value
, vlink
, vspace
, width
.
Çıktı Encode Kuralları Özeti
Encode Türü | Encode Yöntemi |
---|---|
HTML Entity Encoding | & ile & değiştirilmeli< ile < değiştirilmeli> ile > değiştirilmeli" ile " değiştirilmeli' ile ' değiştirilmeli/ ile / değiştirilmeli |
HTML Öznitelik Encoding | Abecesayısal tamgalar dışındaki tüm tamgalar öz HTML Entity biçimleri ile kaçılmalı (&#xHH ), boşluklar dahil.( HH = Hex Değeri) |
URL Encoding | Ölçün yüzde encode. URL Encode yalnızca değerleri encode ederken kullanılmalı, tüm URL ya da yol bölümleri üzerinde değil. |
JavaScript Encoding | Abecesayısal tamgalar dışındaki tüm tamgalar \uXXXX unicode kaçış biçimiyle kaçılmalı.( X = Tam Sayı) |
CSS Hex Encoding | CSS kaçışları \XX ve \XXXXXX biçimlerini destekler. İki tamgalı kaçış, ardından gelen tamganın kaçış tamgası olması durumunda soruna neden olabilir. İki çözüm var : (a) CSS kaçışının ardından bir boşluk eklenir (CSS ayrıştırıcı tarafından görmezden gelinir) (b) ya da tüm CSS kaçışı kullanılır (gerekiyorsa değerdeki uygun yerlere sıfır eklenerek) |