Modern web applications process critical financial transactions, sensitive personal data, and core business logic every day. When these systems contain architectural weaknesses, attackers exploit them to bypass authentication, steal databases, or take control of underlying servers. Securing these environments requires a structured understanding of common failure modes.
The Open Web Application Security Project (OWASP) maintains the OWASP Top 10, a globally recognized standard that highlights the most critical security risks facing web applications. In this guide, you will learn what each vulnerability entails, how it appears in realistic operational environments, and the defensive controls required to eliminate it.
1. A01: Broken Access Control
Broken access control occurs when an application does not properly enforce restrictions on what authenticated users are allowed to do. Attackers can exploit these flaws to view unauthorized files, modify other users' records, or elevate their privileges to administrator status.
A classic example is an Insecure Direct Object Reference (IDOR). Consider an accounting application where a customer views an invoice by navigating to /api/invoices/1042. If the application only checks that the user is logged in, but fails to check whether invoice 1042 belongs to their account, the user can change the URL to /api/invoices/1043 to view another customer's financial data.
To defend against broken access control, enforce authorization checks at the server side on every single request. Never rely on hidden UI elements or client-side routing to restrict access:
// Secure implementation using an explicit ownership check
public Invoice getInvoice(Long invoiceId, User currentUser) {
Invoice invoice = invoiceRepository.findById(invoiceId)
.orElseThrow(() -> new ResourceNotFoundException("Invoice not found"));
if (!invoice.getAccountId().equals(currentUser.getAccountId())) {
throw new AccessDeniedException("Unauthorized access to invoice");
}
return invoice;
}
2. A02: Cryptographic Failures
Previously known as Sensitive Data Exposure, this category covers weaknesses in how an application protects data in transit and at rest. Common missteps include using obsolete encryption algorithms, transmitting passwords or tokens over unencrypted HTTP, and using weak key derivation functions.
A real-world scenario involves an e-commerce platform that stores user passwords using MD5 or SHA-1 hashes without salt. When an attacker breaches the backend database, they run rainbow tables or precomputed dictionary attacks against the hashes to recover the original passwords within minutes.
Protecting data requires using industry-standard cryptography. Use TLS 1.3 for data in motion, enforce HTTP Strict Transport Security (HSTS), and use adaptive hashing functions like Argon2id or bcrypt with appropriate work factors for credentials.
3. A03: Injection
Injection flaws occur when untrusted user input is passed directly to an interpreter as part of a command or query. The interpreter executes the data as code. Common variants include SQL injection (SQLi), Cross-Site Scripting (XSS), Command Injection, and Lightweight Directory Access Protocol (LDAP) injection.
For example, if an application searches for products by concatenating raw query parameters directly into an SQL statement, an attacker can input crafted SQL syntax to bypass authentication or extract entire tables:
-- Vulnerable concatenation
SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'='1';
-- Secure parameterized query (PreparedStatement in Java)
String sql = "SELECT * FROM users WHERE username = ? AND password_hash = ?";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, inputUsername);
stmt.setString(2, inputPasswordHash);
ResultSet rs = stmt.executeQuery();
The primary defense against injection is separating data from code. Always use parameterized queries (prepared statements) for database operations, context-aware output encoding for HTML rendering, and safe APIs instead of raw system shells.
4. A04: Insecure Design
Insecure design represents architectural flaws where security was omitted during the planning phase rather than introduced by a coding bug. A flawless implementation of a fundamentally broken architecture remains insecure.
An example is an e-commerce discount workflow that allows a buyer to apply a 10% coupon, duplicate the browser tab, and apply the same coupon four more times before checking out. If the business logic does not lock the cart state during discount validation, the system allows arbitrary discounts even though the code contains no SQLi or memory bugs.
Mitigate insecure design by performing threat modeling during the requirements and design phases. Establish security champions within development teams, define clear trust boundaries, and test business logic assumptions before writing production code.
5. A05: Security Misconfiguration
Security misconfiguration happens when security controls are inaccurately configured, left at default settings, or completely disabled. This includes enabled debug ports, verbose error messages exposing stack traces, default admin passwords, and unencrypted cloud storage buckets.
A common operational scenario involves deploying an application framework with debug mode active in production. When an unexpected database exception occurs, the framework returns a detailed stack trace to the browser, exposing the database hostname, internal directory paths, database user names, and underlying library versions.
To eliminate misconfigurations, harden operating systems and software components using established benchmarks like the Center for Internet Security (CIS) standards. Implement automated configuration management and ensure automated pipelines run tests to verify that production deployments turn off debugging features.
6. A06: Vulnerable and Outdated Components
Modern applications rely on deep dependency trees containing hundreds of third-party libraries, container images, and software packages. If any of these open-source dependencies contain known vulnerabilities, attackers can compromise the entire application.
The high-profile exploitation of Apache Log4j (CVE-2021-44228) demonstrated how a single vulnerable logging component in an application's dependency tree can allow unauthenticated remote code execution. Thousands of applications that had never written custom networking code were compromised through an external dependency.
Defending against outdated components requires maintaining an accurate Software Bill of Materials (SBOM). Integrate Software Composition Analysis (SCA) tools directly into your continuous integration (CI) pipeline to alert developers when an imported library contains a documented vulnerability.
7. A07: Identification and Authentication Failures
This category addresses flaws in verifying a user's identity, maintaining active sessions, and managing credentials. Vulnerabilities include allowing weak passwords, failing to protect against credential stuffing, exposing session IDs in URLs, and improper session invalidation upon logout.
In a credential-stuffing scenario, automated botnets test millions of username and password pairs stolen from previous external data breaches against a target login portal. If the target lacks multi-factor authentication (MFA) and rate limiting, the attacker gains control of accounts belonging to users who reused passwords across platforms.
Enforce strong password policies, mandate MFA for sensitive systems, implement rate limiting and CAPTCHAs on login endpoints, and use cryptographically random session tokens managed through secure cookie attributes (HttpOnly, Secure, and SameSite=Strict).
8. A08: Software and Data Integrity Failures
Integrity failures involve code, updates, and serialized data accepted without verifying its authenticity and origin. This includes trusting unverified automated updates, downloading packages from untrusted registries, and insecure object deserialization.
A practical risk involves an application that takes serialized objects directly from an untrusted client cookie and deserializes them into live server memory. Attackers can manipulate serialized objects to execute arbitrary classes or code paths within the execution environment.
Ensure that all software updates, code artifacts, and external libraries are cryptographically signed and verified. Avoid passing serialized objects from untrusted sources, or enforce strict type constraints and digital signatures before deserialization.
9. A09: Security Logging and Monitoring Failures
If an application fails to log security-relevant events—such as failed logins, privilege changes, and access-control failures—attacks go unnoticed. Breaches often take months to detect because organizations lack sufficient telemetry to spot anomalies in real time.
Consider an attacker attempting brute-force attacks against an administrative API. If the API logs nothing when an authentication attempt fails, the security team cannot detect the ongoing campaign until the attacker successfully logs in and exfiltrates data.
Log all authentication events, authorization rejections, and server-side input validation errors with sufficient contextual data (such as timestamps, client IP addresses, and user identifiers). Ensure logs never contain raw passwords, session tokens, or personal data, and forward logs to a centralized Security Information and Event Management (SIEM) system for active alerting.
10. A10: Server-Side Request Forgery (SSRF)
Server-Side Request Forgery occurs when a web application fetches a remote resource specified by an end user without validating the supplied destination URL. This allows an attacker to coerce the server into sending crafted requests to internal network locations, loopback interfaces, or cloud metadata endpoints.
In cloud deployments, an attacker can input the cloud metadata service IP address (such as http://169.254.169.254/latest/meta-data/) into an application feature that fetches an image from a URL. If the server fetches this address, it may leak temporary IAM credentials, providing the attacker direct access to cloud infrastructure.
To prevent SSRF, disable unneeded URL-fetching features. When URL fetching is required, validate input against a strict allowlist of domains and protocols, enforce network segmentation, and disable access to link-local metadata addresses at the firewall level.
Defensive Implementation Checklist
Review this checklist across your development lifecycle to verify baseline coverage against the OWASP Top 10:
- Access Control: Are all backend endpoints protected by explicit, role-based authorization checks that verify asset ownership?
- Data Protection: Is TLS 1.3 enforced across all public endpoints, and are credentials hashed using bcrypt or Argon2id?
- Input & Output Handling: Do all database queries use prepared statements, and is output contextualized before rendering?
- Dependencies: Does the build pipeline fail automatically when an SCA scan detects critical vulnerabilities in external libraries?
- Configuration: Are default passwords removed, stack traces suppressed in production, and cloud storage assets set to private by default?
- Logging & Alerting: Are all failed logins, permission denials, and critical transactions routed to a centralized, monitored log repository?
- Network Boundaries: Are outbound requests from the application layer restricted by network egress rules to prevent SSRF against metadata services?





