Securing Applications using the OWASP Top 10 Vulnerabilities

Sheldon Cohen
10 min readDec 21, 2023
Broken Authentication
Secure against OWASP Top 10

Securing software applications is of utmost importance in today’s digital landscape. As technology advances, so do the techniques used by malicious actors to exploit vulnerabilities in software. One valuable resource in the world of web application security is the Open Web Application Security Project (OWASP). Let’s take a deep dive into the OWASP Top 10 vulnerabilities and explore mitigation strategies. While some of the code is tailored to. NET, the concepts and strategies are mostly agnostic.

What is OWASP?

The Open Web Application Security Project, commonly referred to as OWASP, is an international non-profit organization dedicated to improving the security of software. It provides practical information about application security, promotes secure coding practices, and fosters a community focused on web application security. One of the most significant contributions of OWASP is the OWASP Top 10, a regularly updated list of the most critical security risks to web applications.

Understanding the OWASP Top 10

The OWASP Top 10 is an invaluable resource for anyone tasked with securing or maintaining web applications. It serves as a guide to understanding and mitigating the most critical security risks. The current iteration of the OWASP Top 10 includes the following risks:

Each of these risks represents a common and significant weakness that can often be exploited to compromise the security of a web application. OWASP provides detailed information about possible vulnerabilities and attack techniques for each risk.

Broken Access Control

Broken access control vulnerabilities, moved up from the 5th to the top risk on the OWASP Top 10 list, as the most serious web application security risk. This occurs when an application fails to enforce proper access controls, allowing unauthorized users to access privileged resources or perform actions they should not be able to. This can lead to unauthorized data exposure, privilege escalation, or unauthorized modification of data.

To address broken access control vulnerabilities, it is essential to implement proper access controls at every level of the application. This includes enforcing role-based access control, implementing strong authentication and authorization mechanisms, and regularly testing for access control weaknesses.

Assuming our system implements Access Based Access Control (ABAC), or Role Based Access Control (RBAC), our method EditUserProfile doesn’t have proper role check.

public IActionResult EditUserProfile(int userId, UserProfile updatedProfile)
{
// Code to edit user profile without checking if the user is authorized
}

To address this vulnerability, let’s add the proper attribute to our method, fixing our violation.

[Authorize(Roles = "EditProfile")]
public IActionResult EditUserProfile(int userId, UserProfile updatedProfile)
{
// Secure code ensuring only authorized users can edit profiles
}

While there are several ways or techniques to address this vulnerability, the main point is to ensure we’re adding the proper access control where we need to.

Injection Vulnerabilities

Injection vulnerabilities occur when untrusted data is sent to an interpreter as part of a command or query. This can lead to the execution of unintended commands or the disclosure of sensitive information. Common types of injection vulnerabilities include SQL, OS, and LDAP injections.

To mitigate injection vulnerabilities, it is crucial to always validate and sanitize user input. Use parameterized queries or prepared statements to prevent malicious input from being interpreted as code. Additionally, implement input validation and proper encoding to ensure that user-supplied data is handled safely.

The following code snippet is vulnerable to SQL Injection. It directly concatenates the user input (searchQuery) into the SQL query without any validation or sanitization. An attacker could manipulate searchQuery to alter the SQL command and possibly access or damage the database.

public List<Product> SearchProducts(string searchQuery)
{
var context = new MyDbContext();
return context.Products.SqlQuery("SELECT * FROM Products WHERE Name LIKE '%" + searchQuery + "%'").ToList();
}

This above code snippet is vulnerable to SQL Injection. It directly concatenates the user input (searchQuery) into the SQL query without any validation or sanitization. An attacker could manipulate searchQuery to alter the SQL command and possibly access or damage the database.

public List<Product> SearchProducts(string searchQuery)
{
var context = new MyDbContext();
return context.Products.Where(p => p.Name.Contains(searchQuery)).ToList();
}

Using Entity Framework automatically parameterizes the user input, preventing injection. Where and Contains are used instead of a raw SQL query, thus ensuring that searchQuery is treated as a value rather than part of the SQL command.

Broken Authentication and Session Management

Broken authentication occurs when an application’s authentication mechanisms are implemented incorrectly or are vulnerable to attacks. Examples are, brute force attacks, credential stuffing, use of default or weak or well-known passwords like Password1 or combinations like admin/admin. This can result in unauthorized access to user accounts, compromise of session tokens, and the disclosure of sensitive information.

To address broken authentication vulnerabilities, it is essential to implement secure authentication and session management practices. This includes using strong password policies, implementing multi-factor authentication, and securely storing session tokens. Regularly testing for weak passwords and session management vulnerabilities is also crucial.

While there are many mitigation options available, not relying solely on username and password, but instead multi-factor authentication. NIST Digital Identity Guidelines have recommended to stop using just username and password per NIST 800–63 and use multi-factor authentication.

Consider also, using a service as such Auth0. Delegating the authentication to a service that is specifically designed to handle user authentication and session management securely. Auth0 uses advanced security measures and follows best practices, thus mitigating risks associated with broken authentication and session management. It takes care of various aspects like secure password storage, prevention against brute force attacks, and secure session handling, which are crucial for application security.

Sensitive Data Exposure

Sensitive data exposure vulnerabilities occur when an application fails to adequately protect sensitive information, such as passwords, credit card numbers, or personal data. This can happen due to weak encryption, improper storage, or insecure transmission of data.

To mitigate sensitive data exposure, it is vital to implement strong encryption algorithms for data at rest and in transit. Use secure protocols, such as HTTPS, to ensure the secure transmission of sensitive information. Additionally, follow best practices for securely storing and handling sensitive data, such as using strong encryption keys and securely deleting data when no longer needed, hashing data and use of salt.

Hashing vs Encryption: Hashing is a one-way process, which means it’s practically impossible to reverse-engineer the original data from the hash. This is unlike encryption, which is a two-way process,

Use of Salt: Modern hashing algorithms like Argon2 to salt the passwords. Salting adds a unique string to each password before hashing, making it extremely difficult for attackers to use precomputed tables (like rainbow tables) to crack the passwords.

XML External Entities (XXE)

XML External Entities (XXE) vulnerabilities occur when an application processes XML input without disabling external entity references. Attackers can exploit this vulnerability to read local files, perform remote code execution, or launch denial-of-service attacks.

To prevent XXE vulnerabilities, it is crucial to disable external entity references in XML processing. Use secure XML parsers that do not resolve external entities by default. Additionally, validate and sanitize XML input to ensure it does not contain malicious content.

Consider the following example, this parses XML data in an unsafe way and can be exploited to inject a specially forged XML to disclose the /etc/passwd system file referring its path as an external entity:

XXE Xml External Entity

The XXE (XML External Entity) vulnerability occurs when an XML parser processes external entities defined in the XML input. An attacker can exploit this by crafting malicious XML content that includes references to external resources. This can lead to various attacks, such as data exfiltration, denial of service, server-side request forgery (SSRF), and others.

Disable DTD processing and use XmlReader with XmlReaderSettings, and avoid external entity resolution.

Always employ XmlReader with appropriate configurations for secure XML parsing. Refrain from using XmlDocument or XDocument, as they are potentially more vulnerable to XXE (XML External Entity) injection attacks.

public static void ProcessXmlStream(Stream xmlStream)
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Prohibit;
settings.XmlResolver = null;

using (XmlReader reader = XmlReader.Create(xmlStream, settings))
{
// Process XML securely
}
}

Security Misconfiguration

Security misconfiguration vulnerabilities occur when an application is not securely configured. This can include default or weak passwords, exposed sensitive information, outdated software versions, or improperly configured security headers. Approximately 90% of the applications underwent testing for various misconfigurations, revealing an average occurrence rate of 4%. There were more than 208,000 instances of a Common Weakness Enumeration (CWE) identified.

Common Weakness Enumeration (CWE) is a list or a system that provides a way to identify, understand, and prevent software weaknesses and vulnerabilities. Think of it as a reference guide for common mistakes that can happen when people write computer programs.

To mitigate security misconfiguration vulnerabilities, it is crucial to follow secure configuration practices. This includes keeping software and libraries up to date, properly configuring security settings, and removing default accounts and settings. Regularly scanning for misconfigurations and conducting security audits is also recommended.

Best Practices to Avoid Security Misconfiguration:

  • Regularly Update and Patch: Keep all software up to date, including the operating system, web/application server, database server, and any applications or libraries being used.
  • Remove Unnecessary Features: Disable or remove any unnecessary services, features, accounts, or privileges.
    Secure Default Settings: Change default settings to secure ones, including passwords, error messages, and file permissions.
  • Environment-Specific Configurations: Differentiate between development, testing, and production environments, ensuring that each has its own secure configuration.
  • Regular Audits and Reviews: Regularly review and audit the configurations and settings to ensure they remain secure against evolving threats.

Cross-Site Scripting (XSS)

Cross-Site Scripting (XSS) vulnerabilities occur when an application does not properly validate user-supplied input, allowing attackers to inject malicious scripts into web pages viewed by other users. This can lead to session hijacking, defacement of web pages, or the theft of sensitive information.

To prevent XSS vulnerabilities, it is essential to properly validate and sanitize user input. Implement output encoding to ensure that user-supplied data is displayed safely. Additionally, use content security policies to restrict the execution of scripts and prevent XSS attacks.

We’ll encode user input before displaying it in web pages. using the HttpUtility.HtmlEncode.

public ActionResult ShowComment(string userComment)
{
var model = new CommentViewModel
{
UserComment = HttpUtility.HtmlEncode(userComment)
};
return View(model);
}

HttpUtility.HtmlEncode converts special characters to their HTML-encoded equivalents (e.g., < becomes &lt;). This means that any script tags or other potentially harmful inputs will be displayed as plain text rather than being executed as scripts.

@model YourNamespace.CommentViewModel

<p>@Model.UserComment</p>

Insecure Deserialization

Insecure deserialization vulnerabilities occur when an application does not properly validate or sanitize serialized data. Attackers can exploit this vulnerability to execute arbitrary code, perform denial-of-service attacks, or tamper with application logic.

To mitigate insecure deserialization vulnerabilities, it is crucial to validate and sanitize serialized data before deserializing it. Implement secure deserialization libraries that enforce strict deserialization rules. Additionally, monitor deserialization activities for suspicious or unexpected behavior.

Using Components with Known Vulnerabilities

Using components with known vulnerabilities can expose an application to attacks targeting those vulnerabilities. This includes outdated libraries, frameworks, or third-party components that have known security flaws.

To address this risk, it is crucial to regularly update and patch all components used in an application. Keep track of security advisories and apply patches promptly. Additionally, use tools that can detect and alert you to the presence of vulnerable components in your application.

Consider using toolsike SonarQube or Dependabot to keep up with 3rd party components.

Insufficient Logging and Monitoring

Insufficient logging and monitoring vulnerabilities occur when an application does not adequately log security events or fails to monitor those logs effectively. This can make it difficult to detect and respond to security incidents, such as unauthorized access attempts or data breaches.

To mitigate insufficient logging and monitoring vulnerabilities, it is essential to implement comprehensive logging and monitoring practices. Log security-relevant events, such as authentication failures and access control violations. Regularly review and analyze logs to identify potential security incidents. Implement real-time alerting to promptly respond to suspicious activities. Consider using tooling such as OpenTelemetry for Observability.

Best Practices to Avoid Insufficient Logging and Monitoring:

  1. Comprehensive Logging: Ensure that your application logs all access control failures, input validation failures, and server-side input handling errors.
  2. Integration of Application Logs with SIEM Systems: Connect your application logs to a Security Information and Event Management (SIEM) system for effective monitoring and analysis.
  3. Regular Monitoring: Implement regular monitoring of logs to identify suspicious activities or patterns that could indicate a security breach.
  4. Sensitive Data Protection: Avoid logging sensitive information like passwords, payment details, or personal information. If needed, ensure they are encrypted or masked.
  5. Log Storage Security: Secure your log files against unauthorized access and tampering. Store them in a secure and separate environment, such as S3.
  6. Use of Correlation IDs: Implement correlation IDs in your logs to track user sessions and requests across different services and components.
  7. Real-Time Alerts: Set up real-time alerts for certain types of events, such as multiple failed login attempts or strange application behaviors, indicating potential security issues.
  8. Regular Audits and Reviews: Conduct regular audits of your logs and monitoring tools to ensure they are capturing the necessary information and functioning as expected.
  9. Error Handling: Implement robust error handling that logs errors without exposing sensitive information to the user.

Wrapping it up

Securing applications requires a thorough understanding of the OWASP Top 10 vulnerabilities and effective mitigation strategies.

Addressing these common security risks, developers can significantly enhance the security of their applications. Implementing secure coding practices, conducting regular security audits, and staying informed about the latest threats and vulnerabilities are essential steps in building secure software.

Following these principles, can enhance your application security and protect your digital assets from malicious actors. Remember, securing software is an ongoing process that requires continuous learning and adaptation to new threats.

Stay vigilant, stay updated, and prioritize security in every aspect of your application development process.

Have comments, or thoughts? Drop a comment!

--

--

Sheldon Cohen

Technology professional with 15+ years of software development