Owasp

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 13

OWASP TOP 10- ASP.

NET
A1 Injection

- SQL Injection

UYGULA: SQL Injection zaafiyetini önlemek için, Entity Framework gibi bir object relational mapper
(ORM) kullan veya t-sql komutlarını stored procedureler ile çalıştır.

UYGULA: Projemizde dinamik veya direkt SQL sorguları oluşturmak


yerine, SQLParameter kullanarak sql injection saldırılarını önleyebilirsin.

Örnek:

1
2
3 public void OnGet(string userId)
       {
4            string connectionString =
5 "Server=(local);Database=SqlInjectionTest;Trusted_Connection=True;";
6            string queryString = "SELECT * FROM Users WHERE Id = @UserId";
7            using (SqlConnection connection = new SqlConnection(connectionString))
           {
8
               SqlCommand command = new SqlCommand(queryString, connection);
9                command.Parameters.AddWithValue("@UserId", "Ali");
10                try
11                {
12                    connection.Open();
                   SqlDataReader reader = command.ExecuteReader();
13                    while (reader.Read())
14                    {
15                        Console.WriteLine("\t{0}\t{1}\t{2}",
16                            reader[0], reader[1], reader[2]);
17                    }
                   reader.Close();
18                }
19                catch (Exception ex)
20                {
21                    Console.WriteLine(ex.Message);
               }
22                Console.ReadLine();
23            }
24        }
25
26
YANLIŞ: Dinamik T-SQL metinlerini, projenin içerisinde kullanmak.

Örnek:

1
2
public void OnGet(string userId)
3        {
4            string connectionString =
5 "Server=(local);Database=SqlInjectionTest;Trusted_Connection=True;";
6            string queryString = "SELECT * FROM Users WHERE Id = " + userId;
7            using (SqlConnection connection = new SqlConnection(connectionString))
           {
8                SqlCommand command = new SqlCommand(queryString, connection);
9                try
10                {
11                    connection.Open();
12                    SqlDataReader reader = command.ExecuteReader();
                   while (reader.Read())
13                    {
14                        Console.WriteLine("\t{0}\t{1}\t{2}",
15                            reader[0], reader[1], reader[2]);
16                    }
                   reader.Close();
17                }
18                catch (Exception ex)
19                {
20                    Console.WriteLine(ex.Message);
21                }
               Console.ReadLine();
22            }
23        }
24
25

http://www.sonercelik.com.tr/users?userId=1; DROP ALL TABLES; –** adresine istek yaptığımızda,


veritabanındaki bütün tabloları silecektir. Bu açık sayesinde veritabanımıza gelen bütün sorgular
çalışacaktır.

UYGULA: Veritabanı bağlanmak için kullandığın kullanıcının yetkilerini yapacağı iş kadar ayarla. sa


(system administrator) kullanıcısı gibi bütün yetkilere sahip kullanıcılar ile bağlanma.

- Operating System Injection

UYGULA: System.Diagnostics.Process.Start ile belirli komutların çalışmasını sağla.

Örnek:

1 System.Diagnostics.Process process = new System.Diagnostics.Process();


2 System.Diagnostics.ProcessStartInfo startInfo = new
System.Diagnostics.ProcessStartInfo();
3 startInfo.FileName = "validatedCommand";
4 startInfo.Arguments = "validatedArg1 validatedArg2 validatedArg3";
5 process.StartInfo = startInfo;
6 process.Start();
UYGULA: Kullanıcıdan gelen bütün değerlerin format kontrolünü yapın.

1
2 //Kullanıcıdan gelen değer
3 string ipAddress = "127.0.0.1";
4  
5 //Ip adresi değerini boş olup, olmadığını kontrol etme
if (!string.IsNullOrEmpty(ipAddress))
6 {
7  // Ip adresi formatını kontrol etme
8  if (IPAddress.TryParse(ipAddress, out var address))
9  {
  return address.ToString();
10  }
11  else
12  {
13  //Verilen formata uygun değilse hata ekranına yönlendir.
14  }
15

- LDAP Injection

UYGULA: LDAP sorgularında özel karakterleri escape edip, çalıştır.

https://www.nuget.org/packages/AntiXss paketini yükledikten sonra;

1 string encodedId = Microsoft.Security.Application.Encoder.LdapFilterEncode(id);


2  
3 DirectorySearcher search = new DirectorySearcher(new DirectoryEntry());
4 search.Filter = "(&(objectClass=user)(employeeid=" + encodedId + "))";
5 search.PropertiesToLoad.Add("mail");
search.PropertiesToLoad.Add("telephonenumber");
6 SearchResult sresult = search.FindOne();
7
A2 Broken Authentication

UYGULA: ASP.NET Identity framework paketini kullan. Her kullanıcıya farklı PBKDF2 hashleme ve


SecurityStamp gibi güvenlik önlemlerinden yararlanabilirsiniz.

UYGULA: Güvenli parola politikası oluştur. 6 ayda bir parola yenileme, Büyük harf, Küçük harf özel
karakter zorunluluğu gibi.

Örnek: ASP.NET Identity Konfigürasyonu

1
2 services.Configure<IdentityOptions>(options =>
3 {
4  //Parola Ayarları
 options.Password.RequireDigit = true;
5  options.Password.RequiredLength = 8;
6  options.Password.RequireNonAlphanumeric = true;
7  options.Password.RequireUppercase = true;
8  options.Password.RequireLowercase = true;
 options.Password.RequiredUniqueChars = 6;
9
 options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
10  options.Lockout.MaxFailedAccessAttempts = 3;
11  options.SignIn.RequireConfirmedEmail = true;
12  options.User.RequireUniqueEmail = true;
13 });
14

UYGULA: Çerez politikası belirle. Belirli bir süre içerisinde oturuma kapatmak gibi.

1 services.ConfigureApplicationCookie(options =>
2 {
3  options.Cookie.HttpOnly = true;
4  options.Cookie.Expiration = TimeSpan.FromHours(1)
 options.SlidingExpiration = true;
5
});
6

A3 Sensitive Data Exposure

YANLIŞ: Veritabanında ki parolaları şifreleme teknikleri ile kullanmak.

Tersine mühendislik ile kırılabilir. Ayrıca kullanıcı gizliliğine karşıdır. Kullanıcının parolalarını aynı
şifreleme tekniği ile bir başkası çözebilir.

UYGULA: Güçlü hashleme yöntemleriyle parolaları sakla.

UYGULA: Parolalarda dictionary saldırısı gibi saldırıları önlemek için, Büyük harf, Küçük Harf, Özel
karakter girilmesini zorunlu kıl.

UYGULA: TLS 1.2 protokülünü kullan. LetsEncrypt.org ile ücretsiz sertifika alabilirsin.


UYGULA: Sunucuda SSL gibi eski protokol ve şifreleme tekniklerini devre dışı
bırak. IISCrypto ve https://docs.microsoft.com/en-us/windows-server/identity/ad-
fs/operations/manage-ssl-protocols-in-ad-fs sayfalarını inceleyebilirsiniz.

UYGULA: Security Headers ile web uygulama güvenliği için tarayıcıyı özelleştir. 

ASP.NET Security Headers ve Samesite Cookie blog yazımı veya StripHeaders, SCOTT


HANSELMAN ASP.NET Security Headers, SecurityEssentials sayfalarını inceleyebilirsiniz.

Örnek IIS Web.config:

1
2 <configuration>
3   <system.webServer>
4     <httpProtocol>
5       <customHeaders>
        <add name="Strict-Transport-Security" value="max-age=31536000"/>
6         <add name="X-Content-Type-Options" value="nosniff"/>
7         <add name="X-Xss-Protection" value="1; mode=block"/>
8         <add name="X-Frame-Options" value="SAMEORIGIN"/>
9         <add name="Content-Security-Policy" value="default-src https:; img-src * 'self'
data: https:; style-src 'self' 'unsafe-inline' www.google.com platform.twitter.com
1 cdn.syndication.twimg.com fonts.googleapis.com; script-src 'self' 'unsafe-inline'
0 'unsafe-eval' www.google.com cse.google.com cdn.syndication.twimg.com
1 platform.twitter.com platform.instagram.com www.instagram.com cdn1.developermedia.com
1 cdn2.developermedia.com apis.google.com www.googletagservices.com adservice.google.com
1 securepubads.g.doubleclick.net ajax.aspnetcdn.com ssl.google-analytics.com
az416426.vo.msecnd.net/;"/>
2         <add name="Referrer-Policy" value="no-referrer-when-downgrade"/>
1         <add name="Feature-Policy" value="geolocation 'none';midi 'none';notifications
3 'none';push 'none';sync-xhr 'none';microphone 'none';camera 'none';magnetometer
1 'none';gyroscope 'none';speaker 'self';vibrate 'none';fullscreen 'self';payment
'none';"/>
4
        <remove name="X-Powered-By" />
1         <remove name="X-AspNet-Version" />
5         <remove name="Server" />
1       </customHeaders>
6     </httpProtocol>
...
1
7

A4 XML External Entities (XXE)

XXE (XML External Entity) Güvenlik Zafiyeti xml verisini parse ederken, özel olarak çağrılmış bir
entity (varlık) çağrılması sonucu çalışır.

Önlemek İçin Örnek:

1 XmlReaderSettings settings = new XmlReaderSettings();


2 settings.DtdProcessing = DtdProcessing.Prohibit;
3 XmlReader reader = XmlReader.Create(streamReader, settings);                          
4 System.Xml.XmlDocument gelen = new System.Xml.XmlDocument();
gelen.Load(reader);
5
settings.DtdProcessing = DtdProcessing.Prohibit; ile önleyebiliriz.

A5 Broken Access Control

Weak Account management

Çerezlerin httpOnly aracılığıyla gönderildiğinden emin olun:

1 CookieHttpOnly = true,

ExpireTimeSpan ve SlidingExpiration süresini ayarlayarak gerekli önlemleri alabilirsin:

1 ExpireTimeSpan = TimeSpan.FromMinutes(60),
2 SlidingExpiration = false

Çerezin Production (Canlı) ortamda https üzerinde gönderilmesini sağlayabilirsin.

1 <httpCookies requireSSL="true" xdt:Transform="SetAttributes(requireSSL)"/>


2 <authentication>
3     <forms requireSSL="true" xdt:Transform="SetAttributes(requireSSL)"/>
</authentication>
4

Giriş Yap, Kayıt Ol, Parola Sıfırlama gibi metotlarda brute force saldırılarını önlemek için
düzenlemeler yapın. Ayrıca bir Captcha sistemi kullanabilirsiniz. reCAPTCHA gibi.

1 [HttpPost]
2 [AllowAnonymous]
3 [ValidateAntiForgeryToken]
4 [AllowXRequestsEveryXSecondsAttribute(Name = "LogOn",
5 Message = "You have performed this action more than {x} times in the last {n} seconds.",
Requests = 3, Seconds = 60)]
6 public async Task<ActionResult> LogOn(LogOnViewModel model, string returnUrl)
7

YANLIŞ: Kendi yazdığınız kimlik doğrulama ve session management sistemlerini kullanmak. Bunun


yerine .Net ile uzun zamandır geliştirilmiş yapıları kullanın.

YANLIŞ: Giriş Yaptıktan sonra kullanıcıya "Email adresiniz yanlış" veya "Şifreniz yanlış" gibi bilgiler
vermek.

"Başarısız giriş denemesi" gibi daha genel bilgiler vererek kötü niyetli insanların bilgi edinmesini
önleyebilirsin.

Missing function-level access control

UYGULA: Action veya Handler metotlarınızı yetkili girişe, role veya policy'e göre kısıtlayın.

1 [Authorize(Roles = "Admin", Policy="AtLeast21Age")]


[HttpGet]
2
3 public ActionResult Index(int page = 1)

Insecure Direct object references

Gelen verilerin, var olup olmadığına, başka kullanıcının verilerini değiştirmediğini kontrol etmeliyiz.
Burada primary key veri tipi olarak Guid gibi benzersiz bir veri tipi kullanarak bu verilerin daha zor
bulunmasını sağlayabiliriz. Integer gibi ardışık veriler ile daha kolay deneme yapılacaktır.

1
2 // Güvensiz, gelen id başka bir kullanıcıya ait olsada çalışacaktır.
3 public ActionResult Edit(Guid id)
4 {
5   var user = _context.Users.FirstOrDefault(e => e.Id == id);
  return View("Details", new UserViewModel(user);
6 }
7  
8 // Güvenli, gelen id kullanıcıya ait mi kontrol ediliyor
9 public ActionResult Edit(Guid id)
10 {
  var user = _context.Users.FirstOrDefault(e => e.Id == id);
11     if (user.Id != _userIdentity.GetUserId())
12   {     
13         return View("Error", error);
14   }
15   return View("Edit", new UserViewModel(user);
}
16
17

A6 Security Misconfiguration

Debug and Stack Trace

Production ortamında hata sayfalarının gösterilmesini kapatmalıyız.

1
2 #if DEBUG
            if (env.IsDevelopment() || HostingEnvironment.IsEnvironment("Local"))
3             {
4                 app.UseDeveloperExceptionPage();
5                 app.UseDatabaseErrorPage();
6             }
#else
7
            app.UseHsts();
8             app.UseSecurityHeader();
9 #endif
10

YANLIŞ: Varsayılan kullanıcı parolaları basit yapmak. Canlı ortamda bu şifreler rahatlıkla kırılabilir.

UYGULA: Web API projelerini sadece https protokülüyle yayınla. (bknz: Downgrade attack) Web
projelerinde http, https protokollerini kullanabilirsin ancak httpden https'e yönlendir.
1 app.UseHttpsRedirection();

Cross-site request forgery

YANLIŞ: Hassas verileri Anti-Forgery-Tokens kullanmadan gönder.

UYGULA: Hassas verileri POST/PUT ile Anti-Forgery-Tokens kullanarak göndermeliyiz. Burada


amaç bu token oluşmadan yani get isteği olmadan post/put yapmayı önlemektir.

1 <form method="post" asp-antiforgery="true">


2     ...
3 </form>
1 [HttpPost]
2 [ValidateAntiForgeryToken]
3 public ActionResult LogOff()
1 @inject  Microsoft.AspNetCore.Antiforgery.IAntiforgery antiforgeryProvider
2 $.ajax(
3 {
4     type: "POST",
5     url: '@Url.Action("Action", "Controller")',
    contentType: "application/x-www-form-urlencoded; charset=utf-8",
6     data: {
7         id: id,
8         '__RequestVerificationToken':
9 '@antiforgeryProvider.GetAndStoreTokens(this.Context).RequestToken'
    }
10 })
11

A7 Cross-Site Scripting (XSS)

YANLIŞ: Kullanıcıdan gelen her değeri kabul et. HTML, JavaScript, CSS, LDAP gibi değerleri
encode edilmiş şekilde almalıyız.

YANLIŞ: [AllowHTML] özelliğini @Html.Raw metotunu kullan. XSS-Protection yazımı
inceleyebilirsiniz.

UYGULA: İsteklere verilen cevaplara Content Security Policy headerını ekle.

1 <system.webServer>
2     <httpProtocol>
3         <customHeaders>
4             <add name="Content-Security-Policy"
                value="default-src 'none'; style-src 'self'; img-src 'self';
5
                font-src 'self'; script-src 'self'" />
6
A8 Insecure Deserialization

Deserialization can be dangerous Buradaki yazıyı inceleyebilirsiniz.

YANLIŞ: Güvenilmeyen kaynaklardan serialized objectler kabul etmek.

UYGULA: Kötü niyetli kişiler cookielerdeki serileştirilmiş oturum bilgilerini değiştirebilir. ters


serileştirdiğimizde bu bilgilerin o kullanıcıya ait olup olmadığını kontrol etmeliyiz.

UYGULA: Domain Objectlerine deserilization(ters serileştirme) yapılmasını önlemeliyiz.

UYGULA: Ters serileştirdiğimiz kodları kullanırken sınırılı erişim yetkileriyle çalıştırmalıyız.

A9 Using Components with Known Vulnerabilities

UYGULA: .NET framework sürümlerini güncelle.

UYGULA: Nuget paketlerinin güncel sürümlerini kullan.

UYGULA: OWASP Dependency-Check aracını kullan.

A10 Insufficient Logging & Monitoring

UYGULA: Bütün oturum açma, erişim hataları, sunucu tarafındaki doğrulama hataları, şüpheli veya
tehlikeli olabilecek kullanıcıları algılamak için buralardaki işlemleri log günlüğüne kaydet.

UYGULA: Şüpheli faaliyetlerin tespit edilmesi ve zamanında yanıtlanması için etkili izleme ve


uyarılar oluşturun.

YANLIŞ: Hata mesajlarını genel bir yazı ile günlüğe kaydetmek. _logger.LogInformation("Hata


alındı."); gibi.

Bunun yerine yığın izlemeyi, hata mesajını ve hataya neden olan kullanıcı kimliğini günlüğe
kaydedin.

YANLIŞ: Kullanıcı parolası gibi hassas verileri günlüğe kaydetmek.


Logging

Startup.cs dosyasına bazı eklemeler yaparak bütün hataları yakalabiliriz.

1 app.UseExceptionHandler(errorApp =>
2  {
3   errorApp.Run(async context =>
4   {
      var errorFeature = context.Features.Get<IExceptionHandlerFeature>();
5       var exception = errorFeature.Error;
6  
7       Log.Error(String.Format("Stacktrace of error:
8 {0}",exception.StackTrace.ToString()));
9   });
 });
10

Dependency injection ile razor ve controller sayfalarımızda loglama yapabiliriz.

1
2 public class AboutModel : PageModel
3 {
4     private readonly ILogger _logger;
5  
    public AboutModel(ILogger<AboutModel> logger)
6     {
7         _logger = logger;
8     }
9     public string Message { get; set; }
10  
    public void OnGet()
11     {
12         Message = $"About page visited at {DateTime.UtcNow.ToLongTimeString()}";
13         _logger.LogInformation(Message);
14     }
15 }
16

Monitoring

Monitoring, çalışan bir sistemin performansını, sağlığını  temel performans göstergeleri


aracılığıyla takip etmemize olanak tanır.

ASP.NET Elasticsearch, Kibana, Serilog ile Loglama yazımı okuyabilirsiniz.

Microsoft Github Reposu Observability linkinden, Logging ve Monitoring hakkında detaylı bilgiler


edinebilirsiniz.
[BONUS]

Güvenilmeyen url adreslerine yönlendirmeyi önlemek için;

1
2
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
3         {
4             returnUrl = returnUrl ?? Url.Content("~/");
5  
6             if (ModelState.IsValid)
7             {          
                var result = await _signInManager.PasswordSignInAsync(Input.Email,
8 Input.Password, Input.RememberMe, lockoutOnFailure: false);
9                 if (result.Succeeded)
10                 {
11                     _logger.LogInformation("User logged in.");
12                     return LocalRedirect(returnUrl);
                }
13                 if (result.RequiresTwoFactor)
14                 {
15                     return RedirectToPage("./LoginWith2fa", new { ReturnUrl =
16 returnUrl, RememberMe = Input.RememberMe });
                }
17
                if (result.IsLockedOut)
18                 {
19                     _logger.LogWarning("User account locked out.");
20                     return RedirectToPage("./Lockout");
21                 }
                else
22                 {
23                     ModelState.AddModelError(string.Empty, "Invalid login attempt.");
24                     return Page();
25                 }
26             }
            return Page();
27         }
28
29

 return LocalRedirect(returnUrl); metotununu kullanabiliriz.

Diğer Tavsiyeler

HTTP Strict Transport Security diğer adıyla HSTS, internet tarayıcıların gelen her istekte HTTPS'e
yönlendirerek, downgrade saldırılarını önlemeye yarar.

1 app.UseHsts();

ile kullanabiliriz. 

Third-Party Code Security and Quality (Üçüncü parti Kod Güvenlik ve Kalitesi)


Kullandığımız 3. parti kütüphane, paket, kod, framework içerisindeki zaafiyetler doğrudan bizi de
etkileyebilir. Bunu önlemek için 3. parti kodları incelememiz ve test etmemiz gerekir.

Code Tampering (Kod Kurcalama)

Web uygulamalarının compile edilmiş halini on-premise olarak başka firmalara veriyorsak,
yazdığımız kodların kurcalanmasını önlemek için bir obfuscator aracı kullanmamız
gerek. Obfuscator dediğimiz araçlar, decompile edilmiş kodların anlaşılabilirliği daha zor hale
getiren, yani obfuscate (bulanıklaştırma) işlemini yapan araçlardır.

ASP.NET uyumlu obfuscator olan, Dotfuscator aracını inceleyebilirsiniz. 

Reverse Engineering (Tersine Mühendislik)

Bir makinenin nasıl çalıştığını anlamak için, parçalarını sökeriz ve bu parçaların nasıl çalıştığına
bakarız. Aynı şekilde yazılım alanında compile edilmiş kodları, decompile ederek bütün kodu
görebiliriz. Ayrıca bir web uygulamasında bu işe hangi teknolojinin kullanıldığını, hangi
frameworklerin kullanıldığını öğrenerek başlayabiliriz.

Örnek olarak IIS veya Kestrel Response'ların Server Header'ına kullandığımız teknoloji hakkında
karşı tarafa bilgi vermektedir. Bunu şu şekilde önleyebiliriz.

IIS Kullanıyorsak;

1
2 <configuration>
  <system.webServer>
3     <httpProtocol>
4       <customHeaders>
5 ...    
6         <remove name="X-Powered-By" />
        <remove name="X-AspNet-Version" />
7         <remove name="Server" />
8       </customHeaders>
9     </httpProtocol>
10

Kestrel Kullanıyorsak;

1 public class Program


    {
2         public static void Main(string[] args)
3         {
4             CreateHostBuilder(args).Build().Run();
5         }
6  
7         public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
8                 .ConfigureWebHostDefaults(webBuilder =>
9                 {
10                     webBuilder.UseStartup<Startup>()
11                     .ConfigureKestrel((context, options) => {
12                         options.AddServerHeader = false;
                    });
13                 });
14
15     }
16

You might also like