Latte Güvenlikle Eş Anlamlıdır
Latte, kritik Siteler Arası Komut Dosyası Çalıştırma (XSS) güvenlik açığına karşı etkili koruma sağlayan PHP için tek şablonlama sistemidir. Bu, bağlama duyarlı kaçış sayesinde mümkündür. Şunları ele alacağız:
- XSS güvenlik açığının prensibi nedir ve neden bu kadar tehlikelidir?
- Latte'nin XSS'e karşı savunmada neden bu kadar etkili olduğu
- Twig, Blade ve benzeri şablonlarda güvenlik açığı nasıl kolayca oluşturulabilir?
Siteler Arası Komut Dosyası Çalıştırma (XSS)
Siteler Arası Komut Dosyası Çalıştırma (kısaca XSS), web sitelerinin en yaygın ve aynı zamanda çok tehlikeli güvenlik açıklarından biridir. Saldırganın, şüphelenmeyen kullanıcının tarayıcısında çalışacak kötü amaçlı bir komut dosyasını (malware olarak da bilinir) yabancı bir sayfaya eklemesine olanak tanır.
Böyle bir komut dosyası neler yapabilir? Örneğin, saldırıya uğrayan sayfadan, oturum açıldıktan sonra görüntülenen hassas veriler de dahil olmak üzere herhangi bir içeriği saldırgana gönderebilir. Sayfayı değiştirebilir veya kullanıcı adına başka istekler gerçekleştirebilir. Örneğin, bir web postası olsaydı, hassas mesajları okuyabilir, görüntülenen içeriği değiştirebilir veya yapılandırmayı yeniden ayarlayabilir, örneğin gelecekteki e-postalara da erişim sağlamak için tüm mesajların kopyalarının saldırganın adresine iletilmesini etkinleştirebilirdi.
Bu nedenle XSS, en tehlikeli güvenlik açıkları sıralamasında ön sıralarda yer almaktadır. Web sitesinde bir güvenlik açığı ortaya çıkarsa, kötüye kullanımı önlemek için mümkün olan en kısa sürede giderilmelidir.
Güvenlik Açığı Nasıl Oluşur?
Hata, web sayfasının oluşturulduğu ve değişkenlerin yazdırıldığı yerde ortaya çıkar. Bir arama sayfası oluşturduğunuzu ve başlangıçta aranan terimi içeren bir paragrafın şu şekilde olduğunu hayal edin:
echo '<p>Arama sonuçları <em>' . $search . '</em> için</p>';
Saldırgan, arama kutusuna ve dolayısıyla $search
değişkenine
<script>alert("Hacklendiniz!")</script>
gibi HTML kodu da dahil olmak üzere herhangi bir karakter dizisi
yazabilir. Çıktı hiçbir şekilde işlenmediği için, görüntülenen sayfanın bir parçası haline gelir:
<p>Arama sonuçları <em><script>alert("Hacklendiniz!")</script></em> için</p>
Tarayıcı, aranan karakter dizisini yazdırmak yerine JavaScript'i çalıştırır. Ve böylece sayfanın kontrolünü saldırgan ele geçirir.
Değişkene kod eklemenin JavaScript'i çalıştıracağını, ancak yalnızca saldırganın tarayıcısında çalıştıracağını iddia edebilirsiniz. Kurbana nasıl ulaşır? Bu açıdan bakıldığında, birkaç XSS türü ayırt ederiz. Arama örneğimizde yansıtılmış XSS'ten bahsediyoruz. Burada kurbanı, parametrede kötü amaçlı kod içeren bir bağlantıya tıklamaya yönlendirmek de gerekir:
https://example.com/?search=<script>alert("Hacklendiniz!")</script>
Kullanıcıyı bağlantıya yönlendirmek belirli bir sosyal mühendislik gerektirse de, karmaşık bir şey değildir.
Kullanıcılar, e-postalarda veya sosyal ağlarda olsun, bağlantılara pek düşünmeden tıklarlar. Ve adreste şüpheli bir
şey olduğu, bir URL kısaltıcı kullanılarak gizlenebilir, kullanıcı o zaman yalnızca
bit.ly/xxx
görür.
Ancak, depolanmış XSS veya kalıcı XSS olarak adlandırılan ikinci ve çok daha tehlikeli bir saldırı biçimi de vardır; burada saldırgan, kötü amaçlı kodu sunucuya, bazı sayfalara otomatik olarak eklenecek şekilde kaydetmeyi başarır.
Örnek olarak, kullanıcıların yorum yazdığı sayfalar verilebilir. Saldırgan, kod içeren bir gönderi gönderir ve bu sunucuya kaydedilir. Sayfalar yeterince güvenli değilse, her ziyaretçinin tarayıcısında çalışacaktır.
Saldırının özünün, sayfaya <script>
karakter dizisini sokmak olduğu düşünülebilir. Aslında, JavaScript eklemenin birçok yolu
vardır. Örneğin, bir HTML niteliği kullanarak ekleme örneğini gösterelim. Resimlere alt
niteliğinde
yazdırılacak bir açıklama eklenebilen bir fotoğraf galerimiz olsun:
echo '<img src="' . $imageFile . '" alt="' . $imageAlt . '">';
Saldırganın açıklama olarak akıllıca oluşturulmuş bir karakter dizisi " onload="alert('Hacklendiniz!')
eklemesi yeterlidir ve yazdırma işlenmezse, sonuç kodu şöyle görünecektir:
<img src="photo0145.webp" alt="" onload="alert('Hacklendiniz!')">
Sahte onload
niteliği şimdi sayfanın bir parçası haline geldi. Tarayıcı, içinde bulunan kodu resim
indirilir indirilmez çalıştırır. Hacklendiniz!
XSS'ten Nasıl Korunulur?
Örneğin <script>
karakter dizisini engellemek gibi bir kara liste kullanarak saldırıyı tespit etmeye
yönelik her türlü girişim yetersizdir. İşlevsel bir savunmanın temeli, sayfa içinde yazdırılan tüm verilerin
tutarlı bir şekilde temizlenmesidir.
Öncelikle, özel anlamı olan tüm karakterlerin karşılık gelen başka dizilerle değiştirilmesi söz konusudur, buna argo
tabirle kaçış (escaping) denir (dizinin ilk karakterine kaçış karakteri denir, dolayısıyla adlandırma). Örneğin,
HTML metninde <
karakterinin özel bir anlamı vardır, bir etiketin başlangıcı olarak yorumlanmaması
gerektiğinde, görsel olarak karşılık gelen bir diziyle, yani HTML varlığı <
ile değiştirilmelidir.
Ve tarayıcı küçüktür işaretini yazdırır.
Verileri yazdırdığımız bağlamı ayırt etmek çok önemlidir. Çünkü farklı bağlamlarda karakter dizileri farklı şekilde temizlenir. Farklı bağlamlarda farklı karakterlerin özel anlamları vardır. Örneğin, HTML metninde, HTML niteliklerinde, bazı özel öğelerin içinde vb. kaçış işlemi farklılık gösterir. Bunu birazdan ayrıntılı olarak ele alacağız.
Temizleme işlemini doğrudan karakter dizisini sayfada yazdırırken yapmak en iyisidir, böylece gerçekten yapıldığından ve tam olarak bir kez yapıldığından emin oluruz. Temizleme işleminin doğrudan otomatik olarak şablonlama sistemi tarafından yapılması en iyisidir. Çünkü temizleme otomatik olarak yapılmazsa, programcı bunu unutabilir. Ve bir ihmal, web sitesinin savunmasız olduğu anlamına gelir.
Ancak XSS yalnızca şablonlarda veri yazdırmayla ilgili değildir, aynı zamanda uygulamanın güvenilmeyen verilerle doğru
şekilde ilgilenmesi gereken diğer bölümlerini de ilgilendirir. Örneğin, uygulamanızdaki JavaScript'in bunlarla
bağlantılı olarak innerHTML
değil, yalnızca innerText
veya textContent
kullanması
gerekir. Dizeleri JavaScript olarak değerlendiren fonksiyonlara özel dikkat gösterilmelidir; bunlar eval()
, aynı
zamanda setTimeout()
veya setAttribute()
fonksiyonunun onload
gibi olay nitelikleriyle
kullanılmasıdır. Ancak bu, şablonların kapsadığı alanın dışına çıkar.
3 maddede ideal savunma:
- Verilerin yazdırıldığı bağlamı tanır
- Verileri verilen bağlamın kurallarına göre temizler (yani “bağlama duyarlı”)
- Bunu otomatik olarak yapar
Bağlama Duyarlı Kaçış
Bağlam kelimesiyle tam olarak ne kastediliyor? Belgenin içinde, yazdırılan verilerin işlenmesi için kendi kuralları olan bir yerdir. Belgenin türüne (HTML, XML, CSS, JavaScript, düz metin, …) bağlıdır ve belirli bölümlerinde farklılık gösterebilir. Örneğin, bir HTML belgesinde, çok farklı kuralların geçerli olduğu birçok yer (bağlam) vardır. Kaç tane olduğuna şaşırabilirsiniz. İşte ilk dördü:
<p>#metin</p>
<img src="#nitelik">
<textarea>#hammetin</textarea>
<!-- #yorum -->
Bir HTML sayfasının varsayılan ve temel bağlamı HTML metnidir. Buradaki kurallar nelerdir? <
ve
&
karakterlerinin özel anlamları vardır, bunlar bir etiketin veya varlığın başlangıcını temsil eder, bu
yüzden bunları HTML varlığıyla değiştirerek kaçış işlemine tabi tutmalıyız (<
yerine
<
, &
yerine &
).
İkinci en yaygın bağlam HTML niteliğinin değeridir. Metinden farklı olarak, burada özel anlamı olan tırnak işareti
"
veya '
dir, bu da niteliği sınırlar. Niteliğin sonu olarak anlaşılmaması için varlıkla
yazılmalıdır. Tersine, nitelikte <
karakteri güvenle kullanılabilir, çünkü burada özel bir anlamı
yoktur, burada bir etiketin veya yorumun başlangıcı olarak anlaşılamaz. Ancak dikkatli olun, HTML'de nitelik değerleri
tırnak işaretleri olmadan da yazılabilir, bu durumda birçok karakterin özel anlamı vardır, yani bu başka bir ayrı
bağlamdır.
Belki şaşıracaksınız ama <textarea>
ve <title>
öğelerinin içinde özel kurallar
geçerlidir, burada <
karakteri, ardından /
gelmiyorsa kaçış işlemine tabi tutulmayabilir (ancak
tutulabilir). Ama bu daha çok bir incelik.
HTML yorumlarının içi ilginçtir. Burada kaçış için HTML varlıkları kullanılmaz. Hatta hiçbir belirtim, yorumlarda nasıl kaçış yapılması gerektiğini belirtmez. Sadece biraz tuhaf kurallar uymak ve içlerinde belirli karakter kombinasyonlarından kaçınmak gerekir.
Bağlamlar ayrıca katmanlanabilir, bu da HTML'e JavaScript veya CSS eklediğimizde olur. Bu iki farklı şekilde yapılabilir, öğe ve nitelik ile:
<script>#js-öğe</script>
<img onclick="#js-nitelik">
<style>#css-öğe</style>
<p style="#css-nitelik"></p>
İki yol ve iki farklı veri kaçış yöntemi. <script>
ve <style>
öğelerinin içinde,
HTML yorumlarında olduğu gibi, HTML varlıkları kullanılarak kaçış yapılmaz. Bu öğelerin içine veri yazdırırken
uyulması gereken tek kural vardır: metin </script
veya </style
dizisini içermemelidir.
Tersine, style
ve on***
niteliklerinde HTML varlıkları kullanılarak kaçış yapılır.
Ve tabii ki, iç içe geçmiş JavaScript veya CSS içinde bu dillerin kaçış kuralları geçerlidir. Yani, örneğin
onload
niteliğindeki bir dize önce JS kurallarına göre, sonra da HTML niteliği kurallarına göre kaçış
işlemine tabi tutulur.
Uff… Gördüğünüz gibi, HTML bağlamların katmanlandığı çok karmaşık bir belgedir ve verileri tam olarak nereye yazdırdığınızı (yani hangi bağlamda) fark etmeden, bunu doğru şekilde nasıl yapacağınızı söylemek imkansızdır.
Bir Örnek İster misiniz?
Rock'n'Roll
dizesini ele alalım.
Bunu HTML metninde yazdırırsanız, bu özel durumda herhangi bir değiştirme yapmaya gerek yoktur, çünkü dize özel anlamı olan hiçbir karakter içermez. Tek tırnak içine alınmış bir HTML niteliği içinde yazdırırsanız durum farklıdır. Bu durumda, tırnak işaretlerini HTML varlıklarına kaçış işlemine tabi tutmak gerekir:
<div title='Rock'n'Roll'></div>
Bu basitti. Bağlamlar katmanlandığında, örneğin dize JavaScript'in bir parçası olduğunda çok daha ilginç bir durum ortaya çıkar.
Önce onu JavaScript'in kendisine yazdıralım. Yani, tırnak içine alalım ve aynı zamanda içindeki tırnak işaretlerini
\
karakteriyle kaçış işlemine tabi tutalım:
'Rock\'n\'Roll'
Kodun bir şeyler yapması için bir fonksiyon çağrısı da ekleyebiliriz:
alert('Rock\'n\'Roll');
Bu kodu <script>
kullanarak HTML belgesine eklersek, başka bir şey ayarlamaya gerek yoktur, çünkü
içinde yasaklı </script
dizisi bulunmaz:
<script> alert('Rock\'n\'Roll'); </script>
Ancak bunu bir HTML niteliğine eklemek istersek, tırnak işaretlerini de HTML varlıklarına kaçış işlemine tabi tutmamız gerekir:
<div onclick='alert('Rock\'n\'Roll')'></div>
Ancak iç içe geçmiş bağlam yalnızca JS veya CSS olmak zorunda değildir. Genellikle URL de olabilir. URL'deki
parametreler, özel anlamı olan karakterlerin %
ile başlayan dizilere dönüştürülmesiyle kaçış işlemine
tabi tutulur. Örnek:
https://example.org/?a=Jazz&b=Rock%27n%27Roll
Ve bu dizeyi bir nitelikte yazdırdığımızda, bu bağlama göre kaçış işlemini de uygular ve &
yerine
&
yazarız:
<a href="https://example.org/?a=Jazz&b=Rock%27n%27Roll">
Buraya kadar okuduysanız tebrikler, yorucuydu. Artık bağlamların ve kaçış işleminin ne olduğu hakkında iyi bir fikriniz var. Ve karmaşık olduğu konusunda endişelenmenize gerek yok. Latte bunu sizin için otomatik olarak yapar.
Latte vs Saf Sistemler
Bir HTML belgesinde nasıl doğru bir şekilde kaçış yapılacağını ve bağlamın, yani verileri yazdırdığımız yerin bilgisinin ne kadar önemli olduğunu gösterdik. Başka bir deyişle, bağlama duyarlı kaçışın nasıl çalıştığını. XSS'e karşı işlevsel bir savunma için gerekli bir ön koşul olmasına rağmen, Latte bunu yapabilen PHP için tek şablonlama sistemidir.
Bugün tüm sistemler otomatik kaçışa sahip olduklarını iddia ederken bu nasıl mümkün olabilir? Bağlam bilgisi olmadan otomatik kaçış, yanlış bir güvenlik hissi yaratan biraz saçmalıktır.
Twig, Laravel Blade ve diğerleri gibi şablonlama sistemleri, şablonda herhangi bir HTML yapısı görmezler. Dolayısıyla bağlamları da görmezler. Latte'ye kıyasla kör ve saftırlar. Yalnızca kendi etiketlerini işlerler, diğer her şey onlar için önemsiz bir karakter akışıdır:
░░░░░░░░░░░░░░░░░{{ foo }}░░░░░░░
░░░░░░░░░░░░░░░░{{ foo }}░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░{{ foo }}░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░{{ foo }}░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░{{ foo }}░░░░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░{{ foo }}░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░{{ foo }}░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░{{ foo }}░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░{{ foo }}░░░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░{{ foo }}░░░░
- metinde: <span>{{ foo }}</span>
- etikette: <span {{ foo }} ></span>
- nitelikte: <span title='{{ foo }}'></span>
- tırnaksız nitelikte: <span title={{ foo }}></span>
- URL içeren nitelikte: <a href="{{ foo }}"></a>
- JavaScript içeren nitelikte: <img onload="{{ foo }}">
- CSS içeren nitelikte: <span style="{{ foo }}"></span>
- JavaScript'te: <script>var = {{ foo }}</script>
- CSS'te: <style>body { content: {{ foo }}; }</style>
- yorumda: <!-- {{ foo }} -->
Saf sistemler yalnızca < > & ' "
karakterlerini mekanik olarak HTML varlıklarına dönüştürür, bu
da çoğu kullanım durumunda geçerli bir kaçış yöntemi olsa da, her zaman geçerli değildir. Bu nedenle, aşağıda
göstereceğimiz gibi çeşitli güvenlik açıklarının oluşumunu ne tespit edebilir ne de önleyebilirler.
Latte şablonu sizin gördüğünüz gibi görür. HTML, XML'i anlar, etiketleri, nitelikleri vb. tanır. Ve bu sayede bireysel bağlamları ayırt eder ve verilere bunlara göre işlem yapar. Böylece kritik Siteler Arası Komut Dosyası Çalıştırma güvenlik açığına karşı gerçekten etkili bir koruma sunar.
░░░░░░░░░░░<span>{$foo}</span>
░░░░░░░░░░<span {$foo} ></span>
░░░░░░░░░░░░░░<span title='{$foo}'></span>
░░░░░░░░░░░░░░░░░░░░░░░░░░░<span title={$foo}></span>
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░<a href="{$foo}"></a>
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░<img onload="{$foo}">
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░<span style="{$foo}"></span>
░░░░░░░░░░░░░░░░░<script>░░░░░░{$foo}</script>
░░░░░░░░░<style>░░░░░░░░░░░░░░░░{$foo}░░░</style>
░░░░░░░░░░░░░░░<!--░{$foo}░-->
- metinde: <span>{$foo}</span>
- etikette: <span {$foo} ></span>
- nitelikte: <span title='{$foo}'></span>
- tırnaksız nitelikte: <span title={$foo}></span>
- URL içeren nitelikte: <a href="{$foo}"></a>
- JavaScript içeren nitelikte: <img onload="{$foo}">
- CSS içeren nitelikte: <span style="{$foo}"></span>
- JavaScript'te: <script>var = {$foo}</script>
- CSS'te: <style>body { content: {$foo}; }</style>
- yorumda: <!-- {$foo} -->
Canlı Gösterim
Solda Latte'deki şablonu, sağda ise oluşturulan HTML kodunu görüyorsunuz. $text
değişkeni burada birkaç
kez ve her seferinde biraz farklı bir bağlamda yazdırılıyor. Ve dolayısıyla biraz farklı bir şekilde kaçış işlemine
tabi tutuluyor. Şablon kodunu kendiniz düzenleyebilirsiniz, örneğin değişkenin içeriğini değiştirebilirsiniz vb.
Deneyin:
Harika değil mi! Latte bağlama duyarlı kaçış işlemini otomatik olarak yapar, böylece programcı:
- nerede nasıl kaçış yapılacağını düşünmek veya bilmek zorunda kalmaz
- hata yapamaz
- kaçış işlemini unutamaz
Bunlar bile Latte'nin yazdırırken ayırt ettiği ve verilere işlemi uyarladığı tüm bağlamlar değildir. Şimdi diğer ilginç durumları ele alacağız.
Saf Sistemler Nasıl Hacklenir
Birkaç pratik örnekle, bağlamları ayırt etmenin ne kadar önemli olduğunu ve saf şablonlama sistemlerinin neden Latte'nin aksine XSS'e karşı yeterli koruma sağlamadığını göstereceğiz. Saf sistem temsilcisi olarak örneklerde Twig kullanacağız, ancak aynı şey diğer sistemler için de geçerlidir.
Nitelik Güvenlik Açığı
Yukarıda gösterdiğimiz gibi, bir HTML niteliği kullanarak sayfaya kötü amaçlı kod enjekte etmeye çalışacağız. Twig'de bir resim oluşturan bir şablonumuz olsun:
<img src={{ imageFile }} alt={{ imageAlt }}>
Nitelik değerlerinin etrafında tırnak işareti olmadığına dikkat edin. Kodlayıcı bunları unutmuş olabilir, bu basitçe olur. Örneğin, React'te kod bu şekilde, tırnak işaretleri olmadan yazılır ve diller arasında geçiş yapan bir kodlayıcı daha sonra tırnak işaretlerini kolayca unutabilir.
Saldırgan, resim açıklaması olarak akıllıca oluşturulmuş bir karakter dizisi
foo onload=alert('Hacklendiniz!')
ekler. Twig'in değişkenin HTML metin akışında mı, bir nitelik içinde mi,
HTML yorumunda mı vb. yazdırıldığını anlayamayacağını, kısacası bağlamları ayırt etmediğini zaten biliyoruz. Ve
yalnızca < > & ' "
karakterlerini mekanik olarak HTML varlıklarına dönüştürür. Yani sonuç kodu
şöyle görünecektir:
<img src=photo0145.webp alt=foo onload=alert('Hacklendiniz!')>
Ve bir güvenlik açığı oluştu!
Sahte onload
niteliği sayfanın bir parçası haline geldi ve tarayıcı resmi indirir indirmez onu
çalıştırır.
Şimdi Latte'nin aynı şablonla nasıl başa çıktığına bakalım:
<img src={$imageFile} alt={$imageAlt}>
Latte şablonu sizin gördüğünüz gibi görür. Twig'in aksine, HTML'i anlar ve değişkenin tırnak içinde olmayan bir niteliğin değeri olarak yazdırıldığını bilir. Bu yüzden onları ekler. Saldırgan aynı açıklamayı eklediğinde, sonuç kodu şöyle görünecektir:
<img src="photo0145.webp" alt="foo onload=alert('Hacklendiniz!')">
Latte XSS'i başarıyla önledi.
JavaScript'te Değişken Yazdırma
Bağlama duyarlı kaçış sayesinde, JavaScript içinde PHP değişkenlerini tamamen yerel olarak kullanmak mümkündür.
<p onclick="alert({$movie})">{$movie}</p>
<script>var movie = {$movie};</script>
Eğer $movie
değişkeni 'Amarcord & 8 1/2'
dizesini içeriyorsa, aşağıdaki çıktı
üretilir. HTML içinde farklı bir kaçışın kullanıldığına, JavaScript içinde farklı ve onclick
niteliğinde yine farklı olduğuna dikkat edin:
<p onclick="alert("Amarcord & 8 1\/2")">Amarcord & 8 1/2</p>
<script>var movie = "Amarcord & 8 1\/2";</script>
Bağlantı Kontrolü
Latte, src
veya href
niteliklerinde kullanılan değişkenin bir web URL'si (yani HTTP protokolü)
içerip içermediğini otomatik olarak kontrol eder ve güvenlik riski oluşturabilecek bağlantıların
yazdırılmasını önler.
{var $link = 'javascript:attack()'}
<a href={$link}>tıkla</a>
Yazdırır:
<a href="">tıkla</a>
Kontrol, nocheck filtresi kullanılarak kapatılabilir.
Latte Sınırları
Latte, tüm uygulama için XSS'e karşı tamamen eksiksiz bir koruma değildir. Latte kullanırken güvenlik hakkında düşünmeyi bırakmanızı istemeyiz. Latte'nin amacı, saldırganın sayfanın yapısını değiştirememesini, sahte HTML öğeleri veya nitelikleri ekleyememesini sağlamaktır. Ancak yazdırılan verilerin içerik doğruluğunu kontrol etmez. Veya JavaScript davranışının doğruluğunu. Bu zaten şablonlama sisteminin yetkinliğinin dışına çıkar. Verilerin doğruluğunu doğrulamak, özellikle kullanıcı tarafından girilen ve dolayısıyla güvenilmeyen verileri doğrulamak, programcının önemli bir görevidir.