OWASP Top 10:2025 for web applications
A practical guide to the ten risk categories in the current OWASP Top 10:2025. Use it to scope web application testing, align remediation work, and link findings to the official OWASP taxonomy.
Edition 2025; risk names follow the official OWASP publication.
A01:2025
Broken Access Control
Broken Access Control means the server lets a user do something their role, tenant, or ownership should forbid, even after valid login. Changing an ID to reach another customer's invoice or calling an administrator API directly are typical examples. Hiding a button is not a control because a caller can still send the request to the server.
| What can go wrong | Authorization rules do not consistently enforce what an authenticated user may view, change, approve, or administer. |
|---|---|
| Business effect | A user can reach another customer's record, invoke an administrator-only action, or bypass a workflow boundary. |
| First control to verify | Enforce authorization on every server-side request. |
Attacker Victim Application Security control

The diagram contrasts the unsafe route with the control that interrupts it. Select the image to inspect it at full size.
Why it matters
A user can reach another customer's record, invoke an administrator-only action, or bypass a workflow boundary.
Risk-reduction focus
- Enforce authorization on every server-side request.
- Deny by default and test object, function, and tenant boundaries.
- Log access-control failures and review privileged paths.
Go code example for a web application using Fiber v3
// Vulnerable pattern: trust request-controlled target
app.Get("/records/:id", func(c fiber.Ctx) error {
return c.JSON(repo.Find(c.Params("id")))
})
// Fixed pattern: authorize server-side
if !policy.CanRead(c.Locals("principal"), id) { return fiber.ErrForbidden }A02:2025
Security Misconfiguration
Security Misconfiguration is exposure created by unsafe settings rather than a direct code defect. Examples include production debug mode, default accounts, public storage, or overly broad CORS. A single configuration can make data or functionality reachable outside its intended security boundary.
| What can go wrong | Unsafe defaults, unnecessary features, permissive cloud settings, or missing hardening leave systems exposed. |
|---|---|
| Business effect | Debug interfaces, verbose errors, exposed storage, or weak browser policy can reveal data or create an unintended entry point. |
| First control to verify | Maintain hardened, versioned environment baselines. |
Attacker Victim Application Security control

The diagram contrasts the unsafe route with the control that interrupts it. Select the image to inspect it at full size.
Why it matters
Debug interfaces, verbose errors, exposed storage, or weak browser policy can reveal data or create an unintended entry point.
Risk-reduction focus
- Maintain hardened, versioned environment baselines.
- Remove unused services, accounts, headers, and sample content.
- Continuously review cloud, server, and browser configuration.
Go code example for a web application using Fiber v3
// Vulnerable pattern: trust request-controlled target
app.Get("/records/:id", func(c fiber.Ctx) error {
return c.JSON(repo.Find(c.Params("id")))
})
// Fixed pattern: authorize server-side
if !policy.CanRead(c.Locals("principal"), id) { return fiber.ErrForbidden }A03:2025
Software Supply Chain Failures
Software Supply Chain Failures arise when packages, dependencies, build systems, or update channels are trusted without enough integrity control. A tampered library or leaked release token can alter software delivered to customers even when first-party code has no direct defect.
| What can go wrong | Third-party packages, build systems, update channels, and dependencies are not governed well enough to preserve integrity. |
|---|---|
| Business effect | A compromised or vulnerable component can enter a production release even when first-party application code is sound. |
| First control to verify | Inventory dependencies and pin trusted versions. |
Attacker Victim Application Security control

The diagram contrasts the unsafe route with the control that interrupts it. Select the image to inspect it at full size.
Why it matters
A compromised or vulnerable component can enter a production release even when first-party application code is sound.
Risk-reduction focus
- Inventory dependencies and pin trusted versions.
- Verify provenance and protect build and release credentials.
- Monitor advisories and make patch ownership explicit.
Go code example for a web application using Fiber v3
// Vulnerable pattern: trust request-controlled target
app.Get("/records/:id", func(c fiber.Ctx) error {
return c.JSON(repo.Find(c.Params("id")))
})
// Fixed pattern: authorize server-side
if !policy.CanRead(c.Locals("principal"), id) { return fiber.ErrForbidden }A04:2025
Cryptographic Failures
Cryptographic Failures occur when sensitive data is protected with unsuitable encryption or key management. Insecure transport, obsolete algorithms, keys stored with data, or unencrypted backups can let an interceptor or storage intruder read personal, credential, or business data.
| What can go wrong | Sensitive data is exposed because encryption, key management, protocol choices, or data classification are inadequate. |
|---|---|
| Business effect | Personal data, credentials, payment data, or confidential business records may be disclosed in transit, at rest, or through backups. |
| First control to verify | Classify sensitive data and minimize collection and retention. |
Attacker Victim Application Security control

The diagram contrasts the unsafe route with the control that interrupts it. Select the image to inspect it at full size.
Why it matters
Personal data, credentials, payment data, or confidential business records may be disclosed in transit, at rest, or through backups.
Risk-reduction focus
- Classify sensitive data and minimize collection and retention.
- Use current protocols and vetted cryptographic libraries.
- Protect, rotate, and separate keys from encrypted data.
Go code example for a web application using Fiber v3
// Vulnerable pattern: trust request-controlled target
app.Get("/records/:id", func(c fiber.Ctx) error {
return c.JSON(repo.Find(c.Params("id")))
})
// Fixed pattern: authorize server-side
if !policy.CanRead(c.Locals("principal"), id) { return fiber.ErrForbidden }A05:2025
Injection
Injection happens when input controlled by a caller is concatenated into a command or query and a downstream system treats it as language rather than data, such as SQL, shell, LDAP, or a template. That can change a query's meaning, disclose more data, or trigger work absent from the normal UI.
| What can go wrong | Untrusted input is interpreted as a command, query, template, or expression by a downstream component. |
|---|---|
| Business effect | An attacker may alter a database query, application command, directory lookup, or rendered page beyond the intended request. |
| First control to verify | Use parameterized interfaces and context-aware encoders. |
Attacker Victim Application Security control

The diagram contrasts the unsafe route with the control that interrupts it. Select the image to inspect it at full size.
Why it matters
An attacker may alter a database query, application command, directory lookup, or rendered page beyond the intended request.
Risk-reduction focus
- Use parameterized interfaces and context-aware encoders.
- Apply allow-list validation at trust boundaries.
- Run application identities with only required privileges.
Go code example for a web application using Fiber v3
// Vulnerable pattern: trust request-controlled target
app.Get("/records/:id", func(c fiber.Ctx) error {
return c.JSON(repo.Find(c.Params("id")))
})
// Fixed pattern: authorize server-side
if !policy.CanRead(c.Locals("principal"), id) { return fiber.ErrForbidden }A06:2025
Insecure Design
Insecure Design is a gap in product rules or workflow before code is written, not merely an implementation mistake. Approval without separation of duties, weak account recovery, or missing abuse limits are examples. Code can meet its requirements perfectly and still implement an unsafe product.
| What can go wrong | The product design lacks security requirements, misuse cases, or controls needed for the business workflow it supports. |
|---|---|
| Business effect | Even correctly implemented code can enable fraud, bypass approval limits, or permit unsafe account recovery by design. |
| First control to verify | Model abuse cases and business-rule failures before implementation. |
Attacker Victim Application Security control

The diagram contrasts the unsafe route with the control that interrupts it. Select the image to inspect it at full size.
Why it matters
Even correctly implemented code can enable fraud, bypass approval limits, or permit unsafe account recovery by design.
Risk-reduction focus
- Model abuse cases and business-rule failures before implementation.
- Define security acceptance criteria for critical journeys.
- Use threat modeling and independent design review.
Go code example for a web application using Fiber v3
// Vulnerable pattern: trust request-controlled target
app.Get("/records/:id", func(c fiber.Ctx) error {
return c.JSON(repo.Find(c.Params("id")))
})
// Fixed pattern: authorize server-side
if !policy.CanRead(c.Locals("principal"), id) { return fiber.ErrForbidden }A07:2025
Authentication Failures
Authentication Failures mean a system cannot reliably establish or retain the right identity. Weak passwords, unsafe sessions, unlimited login attempts, or easily abused recovery can let an attacker impersonate another user and inherit that account's access.
| What can go wrong | Identity proofing, session handling, recovery, or credential defenses do not reliably establish and maintain the right user identity. |
|---|---|
| Business effect | An attacker can take over an account, reuse a session, or abuse a weak recovery flow to act as another user. |
| First control to verify | Use phishing-resistant MFA where risk warrants it. |
Attacker Victim Application Security control

The diagram contrasts the unsafe route with the control that interrupts it. Select the image to inspect it at full size.
Why it matters
An attacker can take over an account, reuse a session, or abuse a weak recovery flow to act as another user.
Risk-reduction focus
- Use phishing-resistant MFA where risk warrants it.
- Rotate sessions after login and sensitive changes.
- Rate-limit, monitor, and securely design recovery flows.
Go code example for a web application using Fiber v3
// Vulnerable pattern: trust request-controlled target
app.Get("/records/:id", func(c fiber.Ctx) error {
return c.JSON(repo.Find(c.Params("id")))
})
// Fixed pattern: authorize server-side
if !policy.CanRead(c.Locals("principal"), id) { return fiber.ErrForbidden }A08:2025
Software or Data Integrity Failures
Software or Data Integrity Failures occur when code, updates, external data, or serialized objects are trusted without proving they were not altered. An unsigned update or unverified webhook can change business records or cause execution of software the organization never approved.
| What can go wrong | Applications trust code, updates, serialized objects, or data from an integrity boundary that has not been verified. |
|---|---|
| Business effect | Tampered data or an untrusted update can change application behavior, business records, or the software delivered to users. |
| First control to verify | Verify signatures and provenance for code and updates. |
Attacker Victim Application Security control

The diagram contrasts the unsafe route with the control that interrupts it. Select the image to inspect it at full size.
Why it matters
Tampered data or an untrusted update can change application behavior, business records, or the software delivered to users.
Risk-reduction focus
- Verify signatures and provenance for code and updates.
- Treat serialized and external data as untrusted.
- Protect CI/CD approvals and audit release changes.
Go code example for a web application using Fiber v3
// Vulnerable pattern: trust request-controlled target
app.Get("/records/:id", func(c fiber.Ctx) error {
return c.JSON(repo.Find(c.Params("id")))
})
// Fixed pattern: authorize server-side
if !policy.CanRead(c.Locals("principal"), id) { return fiber.ErrForbidden }A09:2025
Security Logging & Alerting Failures
Security Logging & Alerting Failures mean important events occur without usable evidence or timely attention. Missing privilege-change logs, mutable logs, uncorrelated events, or alerts sent to an unable team let compromise persist and prevent accurate reconstruction.
| What can go wrong | Important security events are not recorded, protected, correlated, or acted on in time. |
|---|---|
| Business effect | A compromise can persist longer because investigators cannot reconstruct activity or responders do not receive useful alerts. |
| First control to verify | Log authentication, authorization, admin, and high-value business events. |
Attacker Victim Application Security control

The diagram contrasts the unsafe route with the control that interrupts it. Select the image to inspect it at full size.
Why it matters
A compromise can persist longer because investigators cannot reconstruct activity or responders do not receive useful alerts.
Risk-reduction focus
- Log authentication, authorization, admin, and high-value business events.
- Protect log integrity and define useful alert thresholds.
- Exercise incident response using representative telemetry.
Go code example for a web application using Fiber v3
// Vulnerable pattern: trust request-controlled target
app.Get("/records/:id", func(c fiber.Ctx) error {
return c.JSON(repo.Find(c.Params("id")))
})
// Fixed pattern: authorize server-side
if !policy.CanRead(c.Locals("principal"), id) { return fiber.ErrForbidden }A10:2025
Mishandling of Exceptional Conditions
Mishandling of Exceptional Conditions occurs when errors, timeouts, retries, overload, or unusual states are handled unsafely or inconsistently. A timeout might duplicate an approval, an outage might skip authorization, or an error may expose internals. The non-happy path then becomes a business or data risk.
| What can go wrong | Failures, timeouts, overload, and unexpected states are handled inconsistently or fail open. |
|---|---|
| Business effect | Error paths can expose details, create duplicate transactions, weaken authorization, or leave users in a misleading state. |
| First control to verify | Fail safely with consistent error handling and user messages. |
Attacker Victim Application Security control

The diagram contrasts the unsafe route with the control that interrupts it. Select the image to inspect it at full size.
Why it matters
Error paths can expose details, create duplicate transactions, weaken authorization, or leave users in a misleading state.
Risk-reduction focus
- Fail safely with consistent error handling and user messages.
- Make critical operations idempotent and bounded by timeouts.
- Test degraded dependencies, retries, and state recovery.
Go code example for a web application using Fiber v3
// Vulnerable pattern: trust request-controlled target
app.Get("/records/:id", func(c fiber.Ctx) error {
return c.JSON(repo.Find(c.Params("id")))
})
// Fixed pattern: authorize server-side
if !policy.CanRead(c.Locals("principal"), id) { return fiber.ErrForbidden }
