Web & Mobile Application Security case study

OWASP crAPI Web and API Security Assessment

Executed a structured security assessment against a local OWASP crAPI deployment and translated technical proof into ten prioritized, business-readable findings.

Skills demonstrated

  • Enumerated directories and fingerprinted the application stack.
  • Manipulated object identifiers to test ownership enforcement.
  • Changed a JWT algorithm to none and removed the signature to test verification.
  • Sent 50+ invalid login attempts to evaluate throttling and lockout.
  • Tested SQL and MongoDB-style payloads and reviewed responses for sensitive disclosure.
  • Documented ten distinct prioritized findings (see Findings Summary); earlier drafts referred to eight after consolidation.

Tools used

  • Burp Suite
  • Gobuster
  • Wappalyzer
  • JWT tooling
  • Postman
  • Docker
  • manual API testing

Project detail

Findings Summary

Severities and remediations below were assigned retrospectively from the documented evidence using standard OWASP/CVSS-style judgment (Critical / High / Medium / Low). They were not part of the original lab write-up.

This assessment documents 10 distinct observations (the original objective said "eight unique prioritized findings"; the table below is the full enumerated set from the Steps, without consolidating duplicates).

IDIssueOWASP categorySeverityFixEvidence
CR-01Broken object-level authorization: changing user ID 8 to 3 returns another user's dataOWASP API1:2023 BOLAHighEnforce object-level authorization on every request; bind resource IDs to the authenticated subject and return 403/404 for cross-user access.Ref 3
CR-02Unsigned JWT (alg: none, signature removed) accepted by the APIOWASP API2:2023 Broken AuthenticationCriticalReject alg: none and unsigned tokens; whitelist allowed algorithms (e.g. RS256/HS256); verify signatures with a server-side key; rotate keys.Refs 4-7
CR-03No account lockout or effective throttling on repeated invalid loginsOWASP API4:2023 Unrestricted Resource ConsumptionMediumAdd progressive rate limiting, account lockout or CAPTCHA after repeated failures, and monitor for credential-stuffing patterns.Refs 8-9
CR-04Exposed MailHog message API (/api/v2/messages) reveals mailbox data, including a one-time passwordOWASP API8:2023 Security MisconfigurationHighDo not expose mail-catcher APIs outside local/dev; require auth and network restriction; never return OTPs via unauthenticated endpoints.Refs 10, 20
CR-05SQL payload accepted and reflected in community post content (weak input validation)OWASP A03:2021 InjectionMediumValidate and encode user content; use parameterized queries server-side; apply output encoding to prevent stored injection/XSS.Refs 11-12
CR-06NoSQL-style $regex payload on coupon validation returns a valid couponOWASP A03:2021 InjectionHighTreat coupon input as a scalar string; reject operator objects ($regex, $gt, etc.); use allow-listed coupon lookup.Refs 13-14
CR-07Verbose Spring validation error discloses backend implementation detailsOWASP API8:2023 Security MisconfigurationLowReturn generic client errors in production; log details server-side only; disable stack traces and framework internals on public APIs.Ref 15
CR-08/.env on port 8888 exposes environment variables and database configurationOWASP API8:2023 Security MisconfigurationCriticalBlock access to .env and config paths; keep secrets in a vault or environment not served by the web root; rotate any exposed credentials.Ref 16
CR-09Community posts endpoint exposes other users' author detailsOWASP API3:2023 Broken Object Property Level AuthorizationMediumApply response filtering / BOPLA controls so clients only receive fields and records they are authorized to see.Ref 17
CR-10Shop orders are enumerable: /orders/1 and /orders/5 return other customers' and admin order/card metadataOWASP API1:2023 BOLACriticalAuthorize order access by ownership/role; use non-guessable IDs; never return full payment-card metadata to unauthorized callers.Refs 18-19

Technical walkthrough

Lab evidence and investigation steps.

Open on GitHub
Ref 1: Gobuster enumerates the crAPI host on 127.0.0.1:9000 and identifies live paths such as /health returning HTTP 200.
Ref 1: Gobuster enumerates the crAPI host on 127.0.0.1:9000 and identifies live paths such as /health returning HTTP 200.
Ref 2: Wappalyzer fingerprints the crAPI web application and identifies the front-end and supporting technologies exposed in the browser.
Ref 2: Wappalyzer fingerprints the crAPI web application and identifies the front-end and supporting technologies exposed in the browser.
Ref 3: Burp Repeater shows that changing the user identifier from 8 to 3 returns another user's data, demonstrating broken object-level authorization.
Ref 3: Burp Repeater shows that changing the user identifier from 8 to 3 returns another user's data, demonstrating broken object-level authorization.
Ref 4: Burp captures the login response returning access and refresh JWTs for the authenticated session.
Ref 4: Burp captures the login response returning access and refresh JWTs for the authenticated session.
Ref 5: The JWT decoder exposes token header and claim values, including role and account identifiers, before tampering tests.
Ref 5: The JWT decoder exposes token header and claim values, including role and account identifiers, before tampering tests.
Ref 6: The JWT is modified by setting the algorithm to none and removing the signature to test token integrity validation.
Ref 6: The JWT is modified by setting the algorithm to none and removing the signature to test token integrity validation.
Ref 7: Burp Repeater shows the API accepting the unsigned modified JWT and returning a normal response, confirming missing JWT signature verification.
Ref 7: Burp Repeater shows the API accepting the unsigned modified JWT and returning a normal response, confirming missing JWT signature verification.
Ref 8: Burp Intruder is configured to brute-force the login password field with a wordlist against the authentication request.
Ref 8: Burp Intruder is configured to brute-force the login password field with a wordlist against the authentication request.
Ref 9: Intruder results show repeated invalid password attempts returning responses without account lockout or effective throttling.
Ref 9: Intruder results show repeated invalid password attempts returning responses without account lockout or effective throttling.
Ref 10: Burp Site Map captures /api/v2/messages?limit=50 returning JSON mailbox data from MailHog, identifying an exposed message API.
Ref 10: Burp Site Map captures /api/v2/messages?limit=50 returning JSON mailbox data from MailHog, identifying an exposed message API.
Ref 11: A POST to /community/api/v2/community/posts sends a SQL injection payload in the content field and receives HTTP 200.
Ref 11: A POST to /community/api/v2/community/posts sends a SQL injection payload in the content field and receives HTTP 200.
Ref 12: The SQL payload is reflected back in the created post content, showing weak input validation on community post creation.
Ref 12: The SQL payload is reflected back in the created post content, showing weak input validation on community post creation.
Ref 13: A baseline coupon validation request sends a normal coupon_code value before testing NoSQL-style payload handling.
Ref 13: A baseline coupon validation request sends a normal coupon_code value before testing NoSQL-style payload handling.
Ref 14: A NoSQL-style $regex payload against /community/api/v2/coupon/validate-coupon returns a valid coupon, showing improper server-side validation.
Ref 14: A NoSQL-style $regex payload against /community/api/v2/coupon/validate-coupon returns a valid coupon, showing improper server-side validation.
Ref 15: Fuzzing the login password field triggers a verbose Spring validation error that discloses backend implementation details.
Ref 15: Fuzzing the login password field triggers a verbose Spring validation error that discloses backend implementation details.
Ref 16: Accessing http://127.0.0.1:8888/.env exposes environment variables and database configuration values.
Ref 16: Accessing http://127.0.0.1:8888/.env exposes environment variables and database configuration values.
Ref 17: The community posts endpoint returns recent posts and author details for multiple users, exposing data beyond the current user's context.
Ref 17: The community posts endpoint returns recent posts and author details for multiple users, exposing data beyond the current user's context.
Ref 18: Changing the shop order identifier to /workshop/api/shop/orders/1 returns another customer's order and payment metadata, confirming broken object-level authorization.
Ref 18: Changing the shop order identifier to /workshop/api/shop/orders/1 returns another customer's order and payment metadata, confirming broken object-level authorization.
Ref 19: A second order lookup using /workshop/api/shop/orders/5 returns admin-owned order and card metadata, confirming order records are enumerable.
Ref 19: A second order lookup using /workshop/api/shop/orders/5 returns admin-owned order and card metadata, confirming order records are enumerable.
Ref 20: Burp Proxy captures a MailHog message API response containing a one-time password, showing that exposed mail traffic can reveal account recovery codes.
Ref 20: Burp Proxy captures a MailHog message API response containing a one-time password, showing that exposed mail traffic can reveal account recovery codes.