Browsing articles in "Yazılım"
Mar
16

HTML Güvenliği

Uygulamamızı internete açtığımızda birşeyi hiç unutmamalıyız. Sayfa Güvenliği!

Sayfalarımızın kötü niyetli kişilerin gazabına uğramasını istemiyorsak, bir takım güvenlik unsurlarını bilmekte fayda var. Her ne kadar kullanıcılardan giriş aldığımız formlarda client-side kontrolleri sağlasakta bazı kötü niyetli kişiler bu kontrolleri kolaylıkla aşarak istedikleri verileri sistemimize gönderebilirler. Bunlar sql injection denemeleri olabileceği gibi, kötü niyet içeren bir script kod bloğu, farklı bir sayfaya yönlendirilebilen meta veya iframe kod parçaçığı olabilir.

Bu sebeple client-side kontrollerin yanında server-side kontrolleride kullanmamız çok önemlidir. Kullanıcıdan aldığımız verinin doğruluğunu ve güvenli bilgi içeriğ içermediğini yazacağımız kodlar ile kolaylıkla kontrol altında tutabiliriz.

Örneğin bloğumuzun yorum bölümünde yer alan forumda yorum alanına (zengin metin editörü kullandığımızı hayal edebilirsiniz) girilen ifadelerin iyi niyetli mi kötü niyetli mi olduğunu kontrol edebilecek yardımcı kodları şu şekilde kontrol edebiliriz.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
private static readonly Regex HtmlTagExpression = new Regex(@"(?'tag_start'</?)(?'tag'\w+)((\s+(?'attr'(?'attr_name'\w+)(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+)))?)+\s*|\s*)(?'tag_end'/?>)", RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex WhiteSpaceBetweenHtmlTagsExpression = new Regex(@">(/w+)<", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex HtmlLineBreakExpression = new Regex(@"<br(/s+)/>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
 
private static readonly Dictionary<string, List<string>> ValidHtmlTags = new Dictionary<string, List<string>> {
	{ "p", new List<string>() },
	{ "br", new List<string>() }, 
	{ "strong", new List<string>() }, 
	{ "b", new List<string>() }, 
	{ "em", new List<string>() }, 
	{ "i", new List<string>() }, 
	{ "u", new List<string>() }, 
	{ "strike", new List<string>() }, 
	{ "ol", new List<string>() }, 
	{ "ul", new List<string>() }, 
	{ "li", new List<string>() }, 
	{ "a", new List<string> { "href" } }, 
	{ "img", new List<string> { "src", "alt" } },
	{ "q", new List<string> { "cite" } }, 
	{ "cite", new List<string>() }, 
	{ "abbr", new List<string>() }, 
	{ "acronym", new List<string>() }, 
	{ "del", new List<string>() }, 
	{ "ins", new List<string>() }
};
 
public static string ToSafeHtml(string text)
{
	return RemoveInvalidHtmlTags(text);
}
 
public static string RemoveInvalidHtmlTags(string text)
{
	return HtmlTagExpression.Replace(text, new MatchEvaluator((Match m) => {
		if (!ValidHtmlTags.ContainsKey(m.Groups["tag"].Value))
			return String.Empty;
 
		string generatedTag = String.Empty;
 
		System.Text.RegularExpressions.Group tagStart = m.Groups["tag_start"];
		System.Text.RegularExpressions.Group tagEnd = m.Groups["tag_end"];
		System.Text.RegularExpressions.Group tag = m.Groups["tag"];
		System.Text.RegularExpressions.Group tagAttributes = m.Groups["attr"];
 
		generatedTag += (tagStart.Success ? tagStart.Value : "<");
		generatedTag += tag.Value;
 
		foreach (Capture attr in tagAttributes.Captures)
		{
			int indexOfEquals = attr.Value.IndexOf('=');
 
			if (indexOfEquals < 1)
				continue;
 
			string attrName = attr.Value.Substring(0, indexOfEquals);
 
			if (ValidHtmlTags[tag.Value].Contains(attrName))
				generatedTag += " " + attr.Value;
		}
 
		if (tagStart.Success && tagStart.Value == "<" && tag.Value.Equals("a", StringComparison.OrdinalIgnoreCase))
			generatedTag += " rel=\"nofollow\"";
 
		generatedTag += (tagEnd.Success ? tagEnd.Value : ">");
 
		return generatedTag;
	}));
}

Yukarıda yer alan kod ile “ValidHtmlTags” kitaplığında tanımlanmış HTML kodları dışında herhangi kötü niyetli bir HTML kod bloğu varsa temizlenecektir.

Gelen değeri aşağıdaki şekilde kullanabilirsiniz..

string result = ToSafeHtml(gelenveri);
Mar
11

HTML Agility Pack Kullanımı

HTML içeriklerinin başarılı bir biçimde çekilmesi ve parse edilmesi için HTML Agility Pack (HAP) ile tanışmanızı öneririm. http://htmlagilitypack.codeplex.com/ adresinde ilgili uygulamaya ulaşabilirsiniz.

HTML Agility Pack oldukça başarılı ve hızlı, download edilen web sayfaları üzerinde parse işlemi gerçekleştirebiliyor.  DOM ve XPATH desteği mevcut. Ayrıca son çıkan versiyonlar LINQ to Object desteği gelmiş durumda.

Kolay bir sorgu ile bir web sayfası içerisinde yer alan tüm linkleri, resim URL’lerine kolaylıkla erişebilirsiniz.

Simon Mourier tarafından hazırlanan bu kod benim gibi web tarama ve veri toplayıcılar için çok iş görüyor.

HtmlDocument doc = new HtmlDocument();
doc.Load("file.htm");
foreach(HtmlNode link in doc.DocumentElement.SelectNodes("//a[@href"])
{
HtmlAttribute att = link["href"];
att.Value = FixLink(att);
}
doc.Save("file.htm");

Xpath hakkında sorgulama ve detaylı bilgilere W3Schools.com’un şu sayfasından ulaşabilirsiniz.

Uygulamaya ait kaynak kodu indirmek için ise buraya tıklayabilirsiniz.

Mar
10

Sub Domainlerde Cookie Paylaşımı

Eğer web sitenizde farklı sub-domainler üzerinde ortak cookie lerden faydalanmak istiyorsanız bu yazının size yardımcı olacağını düşünüyorum.

Cookielerde sayfamızı ziyaret eden kullanıcılar için çeşitli bilgileri barındırabiliyoruz. Tabi sitemizi farklı sub-domainler kullanıyorsak ve bu cookilerde birbirini ilgilendiren bilgiler yer alıyorsa ne yapmamız gerekiyor? Örneğin ana domainimize  login olan bir kullanıcı beni hatırla seçeneğini işaretledi ve içeriğimiz ile ilgili farklı bir sub-domaine yönlendirildi. Bu kişinin login detaylarıda cookiemizde saklı. Fakat biz ana domaine ait cookie ye güvenlik nedeniyle ulaşamıyoruz. Ne yapmamız gerekiyor?

Örneğin www.mustafabudak.com üzerinde aşağıdaki kodu yazalım.

<% Response.Cookies(“User”)=1 %>

Bu oluşturulan cookie kullanıcının tarayıcıyı açık tuttuğu süre boyunca aktif olacaktır. Cookie sadece www.mustafabudak.com domaini ile ilişkilendirilmiştir. blog.mustafabudak.com şeklinde bir sub-domainimiz olduğunda bilgilere ulaşmamız mümkün değildir.

Bu problemi aşağıdaki şekilde çözebiliriz.

<%

Response.Cookies(“User”)=1

Response.Cookies(“User”).Domain = “.mustafabudak.com”

%>

Cookie’nin domain özelliği ile oluşturulan cookie ile tüm sub-domainlerimizin bu cookie bilgilerine ulaşmasını sağlayabiliriz.

Kas
23

MySQL Procedure Kullanımı

MySQL’de performansı oldukça arttıran Procedure kullanımına bakalım.

MySQL üzerinde işlem yapmamıza olanak sağlayan oldukça faydalı bir program Navicat Database Tool for MySQL kullanmanızı tavsiye ederim.

Navicat for MySQL

Navicat for MySQL

MySQL Console içerisinde kullanacağımız veritabanını seçerek procedure yazmaya başlıyoruz.

DROP PROCEDURE IF EXIST usp_filecategorydelete
CREATE PROCEDURE `usp_filecategorydelete`(IN pCategoryID INTEGER, OUT Result INT)
 BEGIN
DELETE FROM filecategory WHERE CategoryID = pCategoryID;
SET Result = 1;
COMMIT;
END;

Şimdi procedure içerisinde yer alan kodları açıklayalım;

1- DROP PROCEDURE IF EXIST usp_filecategorydelete
2- CREATE PROCEDURE `usp_filecategorydelete`
2.1 – (IN IsSoftDelete int, IN pCategoryID INTEGER, OUT Result INT)

3- BEGIN
4- DELETE FROM filecategory WHERE CategoryID = pCategoryID;
5- SET Result = 1;
6- SELECT Result;
7- END;

  1. Procedure varsa siler, yoksa dikkate alınmaz.
  2. Procedure oluşturur.
    2.1 İlk olarak dışarıdan gelecek olan parametrenin ne tipte olacağı yazılır,IN, INOUT ve OUT olarak üç tip vardır.

    IN – parametreyi içeri alır.
    OUT – procedure sonuçlarını dışarı verir
    INOUT – hem içeriği hem dışarı değer verir

    Sonra, parametre değişkenin ismi yazılır. Son olarak parametre değişkenin veri tipi belirlenir. Bunlar MySQL veri tipleridir. (INT, BOOLEAN, VARCHAR(KarakterSayısı), TEXT vb.)

    Devamında arzu edilirse “DEFAULT Değer” şeklinde parametreye varsayılan değer atayabilirsiniz.

  3. Procedure BEGIN ile başlar.
  4. Dileğimiz SQL cümlesini artık kullanabiliriz. Dışarıdan gelen parametremizi SQL cümlesine geçebiliriz.
  5. SET komutu ile çıkış paremetremize değer atarız.
  6. Ekrana çıktı verebilmek için SELECT komutunu kullanabiliriz.
  7. Procedure END ile bitiririz.

Basit bir procedure kullanımı hakkında bilgi vermek istedim. İleriki konularda dinamik procedure oluşturma, farklı bir tablo içerisinde yer alan kayıtları kullanmayı, procedure içerisinde procedure çalıştırma hakkında çeşitli paylaşımlarım olacak.

Sigames
Turksportal
LC Waikiki
Galatasaray SK

Kategoriler

Yorumlar