C# Application Security: Top 10 Vulnerabilities in Practice
Security is one of the most important components of developing modern applications in C# and .NET. Even a small overlooked bug can lead to data leakage or complete system compromise. In this article, we will cover the 10 most common vulnerabilities that C# developers face and show how to avoid them in practice.
1. SQL Injection
The oldest and most dangerous vulnerability. It occurs when user input is directly inserted into an SQL query.
Vulnerable code:
string login = txtLogin.Text;string query = "SELECT * FROM Users WHERE Login = '" + login + "'";SqlCommand cmd = new SqlCommand(query, connection);Secure code (parameterized queries):
string login = txtLogin.Text;string query = "SELECT * FROM Users WHERE Login = @login";SqlCommand cmd = new SqlCommand(query, connection);cmd.Parameters.AddWithValue("@login", login);Additional protection: use an ORM (Entity Framework) — it automatically parameterizes queries.
2. Cross-Site Scripting (XSS)
An attacker injects malicious JavaScript code into a page through user input.
Vulnerable code:
string comment = Request.Form["comment"];Response.Write("<div>" + comment + "</div>");Secure code (output encoding):
string comment = Request.Form["comment"];Response.Write("<div>" + HttpUtility.HtmlEncode(comment) + "</div>");In ASP.NET Core, use @Html.Encode() or Razor syntax with automatic encoding.
3. Cross-Site Request Forgery (CSRF)
An attack where the attacker forces a user to perform an unwanted action on a site where they are authenticated.
Vulnerable code (no protection):
[HttpPost]public IActionResult DeleteAccount(int userId){ // Deleting account without token verification return Ok();}Protection using anti-forgery tokens in ASP.NET Core:
[HttpPost][ValidateAntiForgeryToken]public IActionResult DeleteAccount(int userId){ // Secure deletion return Ok();}On the client side, the token is passed via a hidden form field or header.
4. Insecure Deserialization
When deserializing data from an untrusted source, an attacker can execute arbitrary code.
Vulnerable code (BinaryFormatter):
BinaryFormatter formatter = new BinaryFormatter();using (FileStream fs = new FileStream("data.bin", FileMode.Open)){ var obj = formatter.Deserialize(fs); // Dangerous!}Secure alternatives:
- Use
System.Text.JsonorNewtonsoft.Jsonwith type restrictions. - Enable
TypeNameHandling.None. - Avoid
BinaryFormatter,SoapFormatter, andLosFormatter.
5. Authentication and Session Management Flaws
Weak authentication, storing passwords in plaintext, predictable session tokens.
Mistakes:
- Storing password in plaintext:
User.Password = txtPassword.Text; - Custom hashing implementation without salt.
- Using
Guid.NewGuid()for token generation — too predictable.
Correct approach:
- Use
ASP.NET Core Identity— a built-in solution. - Hash passwords using
BCrypt.Netor