none
SQL INJECTION icin ConnectionString onlemi RRS feed

  • Soru

  • SQL Injection için gerekli önlemleri alabildiğimden şüpheliyim. Kontrol edebilirseniz sevinirim. Şimdiden teşekkürler.


    MClass.cs sayfasındaki bütün kodlar: 
    using Npgsql;
    
    namespace MusteriTakip
    
        
    {
        public class MClass
        {
            public static string cnStr = "User Id=****;Password=****;Host=dumbo.db.elephantsql.com;Database=****;Persist Security Info=True";
            public static NpgsqlConnection cn = new NpgsqlConnection(cnStr);
            
        }
    }


    SELECT (DataGridView):
     string sql;
            public void dgvList()
            {
                DataTable data = new DataTable();
                NpgsqlDataAdapter add = new NpgsqlDataAdapter(sql, MClass.cn);
                add.Fill(data);
                dgv.DataSource = data;
            }
    
            public void dgvMList()
            {
                sql = "SELECT id, ad, unvan, telefon, adres, ts, tb, tt, dt FROM musteri ORDER BY dt DESC";
                dgv = dgvM;
                dgvList();
            }
    
            public void dgvHList()
            {
                sql = "SELECT ad, islem, d FROM hareket INNER JOIN musteri ON hid=id ORDER BY d DESC";
                dgv = dgvH;
                dgvList();
            }


    INSERT:
    public void MW()
            {
    
                var sqlM = "INSERT INTO musteri (ad, unvan, telefon, adres, tb, ts, tt, dt) VALUES (@ad, @unvan, @telefon, @adres, 0, 0, 0, @dt) RETURNING ID";
                var sqlH = "INSERT INTO hareket (hid, islem, d) VALUES (@hid, @islem, @d)";
    
                using (NpgsqlCommand cmdM = new NpgsqlCommand(sqlM, MClass.cn))
                using (NpgsqlCommand cmdH = new NpgsqlCommand(sqlH, MClass.cn))
                {
                    
                }
            }


    SELECT:
    private void MR()
            {
                var sql = "SELECT id, ad, unvan, telefon, adres, ts, tb, tt FROM musteri WHERE id = '"+ id + "'";
                using (NpgsqlCommand cmd = new NpgsqlCommand(sql, MClass.cn))
                {
                    MClass.cn.Open();
    
                    NpgsqlDataReader dr = cmd.ExecuteReader();
                    dr.Read();
    
                    id = Convert.ToInt32(dr["id"]);
                    ad = dr["ad"].ToString();
                    unvan = dr["unvan"].ToString();
                    telefon = dr["telefon"].ToString();
                    adres = dr["adres"].ToString();
                    ts = Convert.ToInt32(dr["ts"]);
                    tb = Convert.ToInt32(dr["tb"]);
                    tt = Convert.ToInt32(dr["tt"]);
    
                    MClass.cn.Close();
                }
            }


    UPDATE:
    public void MU()
            {
                var sqlM = "UPDATE musteri SET ad=@ad, unvan=@unvan, telefon=@telefon, adres=@adres, ts=@ts, tb=@tb, tt=@tt, dt=@dt WHERE '" + id + "' = id";
                var sqlH = "INSERT INTO hareket (hid, islem, d) VALUES (@hid, @islem, @d)";
    
                using (NpgsqlCommand cmdM = new NpgsqlCommand(sqlM, MClass.cn))
                using (NpgsqlCommand cmdH = new NpgsqlCommand(sqlH, MClass.cn)) 
                {
                    MClass.cn.Open();
                    cmdM.ExecuteNonQuery();
                    cmdH.ExecuteNonQuery();
                    MClass.cn.Close();
                }
            }


    • Düzenleyen emreurun 19 Eylül 2020 Cumartesi 10:04
    19 Eylül 2020 Cumartesi 10:03

Yanıtlar

  • var sql = "SELECT id, ad, unvan, telefon, adres, ts, tb, tt FROM musteri WHERE id = '"+ id + "'";

    Yazmissin. + id + dedigin an gelsin SQL injection.

    Tabii diger yandan, o olsa da olmasa da oradaki kodun calisiyor olmasi insani korkutuyor. Cok gereksiz bir haraketle id global degisken yapilmis!

    var sql = @"SELECT id, ad, unvan, telefon, adres, ts, tb, tt 
        FROM musteri 
        WHERE id = @id";
                

    Parametreli, dogru sekli. 

    Yine bir ton gereksiz Convert de cabasi. Convert yerine basitce cast kullaniyor olman lazimdi.

    (int)dr["id"]



    Blog
    How to create a Minimal, Reproducible Example
    The way to Go.
    World's most advanced open source (object-) relational Database.
    Flutter (for mobile, for web & desktop.


    Not: Temelin geri zekali arkadasi Idris bu mesaja da atlayip ne kadar aptal oldugunu bir kez daha belgeleyebilir. Kendisinin tek marifeti beni takip edip, neden her soruya cevap verdigimi, yardim etmeye calistigimi sorgulamaktir. Bu beyinsiz zavalliya, aptal oldugunu hatirlatmayi unutmayiniz.

    • Yanıt Olarak Öneren Mehmet Emin Kaymaz 21 Eylül 2020 Pazartesi 18:36
    • Yanıt Olarak İşaretleyen emreurun 21 Eylül 2020 Pazartesi 23:06
    21 Eylül 2020 Pazartesi 18:03
    Yanıtlayıcı

Tüm Yanıtlar


  • Bu kodlarınıza bakınca neden SQL injection için endişelendiğinizi anlamadım, eğer bu bir desktop uygulamasıysa(sanki öyle gibi) zaten connection string'i doğrudan koda yazmışsınız. Ben şahsen basitce decompile eder sonra veritabanınızı silebilirim nasıl engelleyeceksiniz beni :) Bunu yapmak varken neden sql cümlenizin içerisine kendi sql'imi sokuşturmakla uğraşmak isteyeyim ki?

    NOT : Select sorgunuzda parametre kullanmayı unutmuşsunuz.

    Bunların dışında niye kendinizi bu kadar yordunuz, ORM kullanmak daha kolay değilmiydi ? Bağlantı nesneniz de global gibi sanki bu da iyi değil, bunlar disposable objeler kullanıp atmanız lazım :)


    19 Eylül 2020 Cumartesi 10:14

  • Bu kodlarınıza bakınca neden SQL injection için endişelendiğinizi anlamadım, eğer bu bir desktop uygulamasıysa(sanki öyle gibi) zaten connection string'i doğrudan koda yazmışsınız. Ben şahsen basitce decompile eder sonra veritabanınızı silebilirim nasıl engelleyeceksiniz beni :) Bunu yapmak varken neden sql cümlenizin içerisine kendi sql'imi sokuşturmakla uğraşmak isteyeyim ki?

    NOT : Select sorgunuzda parametre kullanmayı unutmuşsunuz.

    Bunların dışında niye kendinizi bu kadar yordunuz, ORM kullanmak daha kolay değilmiydi ? Bağlantı nesneniz de global gibi sanki bu da iyi değil, bunlar disposable objeler kullanıp atmanız lazım :)


    Desktop uygulaması. Hepsini geçtim, programın setup dosyasına yanlışlıkla biri ulaşıp yüklese, bütün herşey elinde :) Açılışına şifre koysam, yine kolayca çözülür gibi. Çok yeniyim ve kavramakta güçlük çekiyorum. Bu ihtimali geçtim diyelim. Programı tek pc kullanıcak, kullanıcıdan başka kimse ara yüze ulaşamazsa bile internet üzerindeki bu database'e yine de ulaşılabilinir mi?

    - Select sorgusuna bir türlü parametreleri doğru yerleştiremedim galiba. En son select te parametre kullanılmıyor galiba diyerek sıyırttım kendimi :)

    - Sağolsun CetinBasoz çok uğraştı benimle bu connectionstring meselesi için, ama programlama işinde en iyi yaptığım şey devreye girerek yanlış anlıyorum :) ORM olarak dapper'ı önermişti ama onda da yeteri kadar kaynak bulamadığımdan cesaret edip çalıştıramadım.
    19 Eylül 2020 Cumartesi 11:02

  • Bu kodlarınıza bakınca neden SQL injection için endişelendiğinizi anlamadım, eğer bu bir desktop uygulamasıysa(sanki öyle gibi) zaten connection string'i doğrudan koda yazmışsınız. Ben şahsen basitce decompile eder sonra veritabanınızı silebilirim nasıl engelleyeceksiniz beni :) Bunu yapmak varken neden sql cümlenizin içerisine kendi sql'imi sokuşturmakla uğraşmak isteyeyim ki?

    NOT : Select sorgunuzda parametre kullanmayı unutmuşsunuz.

    Bunların dışında niye kendinizi bu kadar yordunuz, ORM kullanmak daha kolay değilmiydi ? Bağlantı nesneniz de global gibi sanki bu da iyi değil, bunlar disposable objeler kullanıp atmanız lazım :)


    Desktop uygulaması. Hepsini geçtim, programın setup dosyasına yanlışlıkla biri ulaşıp yüklese, bütün herşey elinde :) Açılışına şifre koysam, yine kolayca çözülür gibi. Çok yeniyim ve kavramakta güçlük çekiyorum. Bu ihtimali geçtim diyelim. Programı tek pc kullanıcak, kullanıcıdan başka kimse ara yüze ulaşamazsa bile internet üzerindeki bu database'e yine de ulaşılabilinir mi?

    - Select sorgusuna bir türlü parametreleri doğru yerleştiremedim galiba. En son select te parametre kullanılmıyor galiba diyerek sıyırttım kendimi :)

    - Sağolsun CetinBasoz çok uğraştı benimle bu connectionstring meselesi için, ama programlama işinde en iyi yaptığım şey devreye girerek yanlış anlıyorum :) ORM olarak dapper'ı önermişti ama onda da yeteri kadar kaynak bulamadığımdan cesaret edip çalıştıramadım.

          Yok, select sorgusuna da aynı diğerlerinde yaptığın gibi parametre ekleyebilirsin.

         Normalde veritabanının önüne bir servis koy, veritabanı işlemlerini bu servis yapıp sana dönsün derdim böylece kaynak kodunda veritabanı bilgisi tutman gerekmez ama şimdi tek bilgisayar kullanacak diyince affalladım :) Şimdilik tek kullanıcı demek istedin herhalde yoksa veritabanın neden bir sunucuda olsun ki ?

      ORM tavsiyemin sebebi şu, mesela veri çekmişsin sonra gidip onları tek tek fieldlara atamak için kod yazmak zorunda kalmışsın ya da update etmek için ilgili tablonun tüm alanları elle tek tek yazmışsın. Şimdi düşün aradan 3 ay geçti yeni bir alan ekledin DB'ye tüm kod değişecek sonra test edilecek... :D Bu yüzden SQL cümleleri runtime'da üretmeye gayret göstermek lazım, bir diğer deyişle bu kodları herhangibir model/obje ile çalışabilecek şekilde yazmak lazım ki yarın öbür gün yorulmayalım :) 

     Bir diğer faydası da en azından implicit transaction gibi özellikler barındıyorlar, gördüğüm kadarıyla sen DB'ye insert işlemi yaparken bir transaction içerisinde yapmıyorsun yani tam işlem gerçekleştiği esnada bir problem çıksa veritabanının veri bütünlüğü/doğruluğu zarar görecek.

    NOT: Update içinde parametre kullanmayı unutmuşsun, halbuki aynı sql cümlesi içinde diğer kolonlar için kullanmışsın : 

     var sqlM = "UPDATE musteri SET ad=@ad, unvan=@unvan, telefon=@telefon, adres=@adres, ts=@ts, tb=@tb, tt=@tt, dt=@dt WHERE '" + id + "' = id";

    Ayrıca değişken isimlendirmelerin de çok karışık gibi, fark ettim belli bir mantığı var :) MU(U update'den geliyor herhalde), MR( Read as select ) vb. ama bunları 2 hafta sonra unutursan geri dönüp bu kodu okumak çile olur o yüzden gereksiz kısaltmalar yapma bence.

    19 Eylül 2020 Cumartesi 11:56
  • private void MR()
            {
                var sql = "SELECT id, ad, unvan, telefon, adres, ts, tb, tt FROM musteri WHERE id = '"+ id + "'";
                using (NpgsqlCommand cmd = new NpgsqlCommand(sql, MClass.cn))
                {

    Buraya kadar iyi gidiyordu ki, bundan sonrasi net olarak SQL injection davetiyeleri cikarmis.

    Connection string kabak gibi ortalikta olmak zorunda degil, kurulusta ya da ilk calistirildginda kullaniciya sorulup, sifreleneip saklanabilir ve sonra hep o sifreli halinden okunup kullanilabilir.

    Sen yanlis bilmiyorsam, ElehantSQL'den kullaniyorsun (donup connection string'e baktim dogru biliyormusum), oyleyse programin icerisine onceden de sifreli gomebilrsin.

    Not: Bu arada bence ElephantSQL reklami hak ediyor. Fiyatlari net anlasiliyor en azindan :) AWS, Google, Azure ... fiyatlandirmadaki bilmeceleri cozen beri gelsin. 



    Blog
    How to create a Minimal, Reproducible Example
    The way to Go.
    World's most advanced open source (object-) relational Database.
    Flutter (for mobile, for web & desktop.


    Not: Temelin geri zekali arkadasi Idris bu mesaja da atlayip ne kadar aptal oldugunu bir kez daha belgeleyebilir. Kendisinin tek marifeti beni takip edip, neden her soruya cevap verdigimi, yardim etmeye calistigimi sorgulamaktir. Bu beyinsiz zavalliya, aptal oldugunu hatirlatmayi unutmayiniz.


    19 Eylül 2020 Cumartesi 21:03
    Yanıtlayıcı

  •       Yok, select sorgusuna da aynı diğerlerinde yaptığın gibi parametre ekleyebilirsin.

         Normalde veritabanının önüne bir servis koy, veritabanı işlemlerini bu servis yapıp sana dönsün derdim böylece kaynak kodunda veritabanı bilgisi tutman gerekmez ama şimdi tek bilgisayar kullanacak diyince affalladım :) Şimdilik tek kullanıcı demek istedin herhalde yoksa veritabanın neden bir sunucuda olsun ki ?

      ORM tavsiyemin sebebi şu, mesela veri çekmişsin sonra gidip onları tek tek fieldlara atamak için kod yazmak zorunda kalmışsın ya da update etmek için ilgili tablonun tüm alanları elle tek tek yazmışsın. Şimdi düşün aradan 3 ay geçti yeni bir alan ekledin DB'ye tüm kod değişecek sonra test edilecek... :D Bu yüzden SQL cümleleri runtime'da üretmeye gayret göstermek lazım, bir diğer deyişle bu kodları herhangibir model/obje ile çalışabilecek şekilde yazmak lazım ki yarın öbür gün yorulmayalım :) 

     Bir diğer faydası da en azından implicit transaction gibi özellikler barındıyorlar, gördüğüm kadarıyla sen DB'ye insert işlemi yaparken bir transaction içerisinde yapmıyorsun yani tam işlem gerçekleştiği esnada bir problem çıksa veritabanının veri bütünlüğü/doğruluğu zarar görecek.

    NOT: Update içinde parametre kullanmayı unutmuşsun, halbuki aynı sql cümlesi içinde diğer kolonlar için kullanmışsın : 

     var sqlM = "UPDATE musteri SET ad=@ad, unvan=@unvan, telefon=@telefon, adres=@adres, ts=@ts, tb=@tb, tt=@tt, dt=@dt WHERE '" + id + "' = id";

    Ayrıca değişken isimlendirmelerin de çok karışık gibi, fark ettim belli bir mantığı var :) MU(U update'den geliyor herhalde), MR( Read as select ) vb. ama bunları 2 hafta sonra unutursan geri dönüp bu kodu okumak çile olur o yüzden gereksiz kısaltmalar yapma bence.

    Şimdilik değil, hep bir kullanıcı kullanacak :)Npgsql kullandım, onun da local olarak bir dosyasını bulamadığımdan uzak bir sunucuyla çözdüm işi. Bir yandan pc'nin de başına bir şeyler gelebilir. Başka bir yerde olması db'nin daha güvenli gibi geldi. Ama bu seferde başka güvenlik problemleri çıkıyor tabi :)

    update'te kullanmışım gibi parametre. ben çok mu yanlış anlıyorum acaba parametreyi. @ işaretinin olması parametre olduğunu anlamına gelmiyor mu ?:))

    parametrelerle select sorgusunu nasıl yazabilirim? küçük bir örnekle gösterebilirseniz anlayabilirim ancak :)

    21 Eylül 2020 Pazartesi 17:32
  • private void MR()
            {
                var sql = "SELECT id, ad, unvan, telefon, adres, ts, tb, tt FROM musteri WHERE id = '"+ id + "'";
                using (NpgsqlCommand cmd = new NpgsqlCommand(sql, MClass.cn))
                {

    Buraya kadar iyi gidiyordu ki, bundan sonrasi net olarak SQL injection davetiyeleri cikarmis.

    Connection string kabak gibi ortalikta olmak zorunda degil, kurulusta ya da ilk calistirildginda kullaniciya sorulup, sifreleneip saklanabilir ve sonra hep o sifreli halinden okunup kullanilabilir.

    Sen yanlis bilmiyorsam, ElehantSQL'den kullaniyorsun (donup connection string'e baktim dogru biliyormusum), oyleyse programin icerisine onceden de sifreli gomebilrsin.

    Not: Bu arada bence ElephantSQL reklami hak ediyor. Fiyatlari net anlasiliyor en azindan :) AWS, Google, Azure ... fiyatlandirmadaki bilmeceleri cozen beri gelsin. 



    Blog
    How to create a Minimal, Reproducible Example
    The way to Go.
    World's most advanced open source (object-) relational Database.
    Flutter (for mobile, for web & desktop.


    Not: Temelin geri zekali arkadasi Idris bu mesaja da atlayip ne kadar aptal oldugunu bir kez daha belgeleyebilir. Kendisinin tek marifeti beni takip edip, neden her soruya cevap verdigimi, yardim etmeye calistigimi sorgulamaktir. Bu beyinsiz zavalliya, aptal oldugunu hatirlatmayi unutmayiniz.


    Öncekileri düzgün olup "MR" kodundan sonrası nasıl açık kalmış oluyor, burnum ağzıma girsin anlamıyorum hocam :) Hepsini aynı şekilde yazmışım gibi.
    Nasıl yapabilirim hocam bu şifreleme işini?
    21 Eylül 2020 Pazartesi 17:36
  • var sql = "SELECT id, ad, unvan, telefon, adres, ts, tb, tt FROM musteri WHERE id = '"+ id + "'";

    Yazmissin. + id + dedigin an gelsin SQL injection.

    Tabii diger yandan, o olsa da olmasa da oradaki kodun calisiyor olmasi insani korkutuyor. Cok gereksiz bir haraketle id global degisken yapilmis!

    var sql = @"SELECT id, ad, unvan, telefon, adres, ts, tb, tt 
        FROM musteri 
        WHERE id = @id";
                

    Parametreli, dogru sekli. 

    Yine bir ton gereksiz Convert de cabasi. Convert yerine basitce cast kullaniyor olman lazimdi.

    (int)dr["id"]



    Blog
    How to create a Minimal, Reproducible Example
    The way to Go.
    World's most advanced open source (object-) relational Database.
    Flutter (for mobile, for web & desktop.


    Not: Temelin geri zekali arkadasi Idris bu mesaja da atlayip ne kadar aptal oldugunu bir kez daha belgeleyebilir. Kendisinin tek marifeti beni takip edip, neden her soruya cevap verdigimi, yardim etmeye calistigimi sorgulamaktir. Bu beyinsiz zavalliya, aptal oldugunu hatirlatmayi unutmayiniz.

    • Yanıt Olarak Öneren Mehmet Emin Kaymaz 21 Eylül 2020 Pazartesi 18:36
    • Yanıt Olarak İşaretleyen emreurun 21 Eylül 2020 Pazartesi 23:06
    21 Eylül 2020 Pazartesi 18:03
    Yanıtlayıcı