Skip to main content

Command Palette

Search for a command to run...

Application Security Audit Report: Architectural Insights & Lessons Learned

Published
4 min read
I

I’m a software developer and technical writer focused on building and securing web applications. I work across the full stack (MERN) while developing a strong interest in application and API security.

My background in technical writing and API documentation shaped how I think about systems, clarity, structure, and correctness matter as much in code as they do in documentation. I’ve worked with tools like Postman, Swagger, and Figma, and I enjoy translating complex technical ideas into clear, usable knowledge.

These days, I’m learning and writing about web fundamentals, backend systems, and application security, documenting what I build, what I break, and what I’m learning along the way, with an eye toward secure, scalable software and future research.

1. Abstracted Findings & Security Patterns

During the audit of a hybrid-architecture web application, several recurring patterns emerged where functional requirements conflicted with security best practices.

  • The "Trusting Controller" Pattern (Implicit Authorization):

    • Observation: API controllers frequently verified identity (Authentication) but implicitly trusted the request context (Authorization).

    • Generalization: "Implicit Trust in Resource Identifiers." The system assumed that if a valid user requested a resource ID, they were authorized to access it, creating potential for Broken Object Level Authorization (BOLA).

  • The "Type-Safety Availability" Gap:

    • Observation: The backend relied on strict database types (e.g., ObjectIDs) without intermediate validation layers. Unexpected input formats (e.g., semantic slugs instead of hex IDs) caused unhandled exceptions.

    • Generalization: "Input-Driven Availability Failure." A lack of robust input sanitization at the controller level allowed malformed data to trigger application crashes (Denial of Service risk) rather than graceful rejection.

  • The "Frontend-Backend Contract" Drift:

    • Observation: The frontend application evolved to support user-friendly features (pretty URLs/slugs) while the backend logic remained rigid (expecting database keys).

    • Generalization: "API Contract Divergence." Security vulnerabilities often hide in the gap between what the frontend sends (user intent) and what the backend expects (database schema).

2. Insights Grouped by Security Themes

A. Authentication vs. Authorization (The "Auth vs. AuthZ" Distinction)

  • Insight: "Logged In" does not mean "Authorized." Frameworks make authentication easy (middleware), but Relationship-Based Access Control (ReBAC), checking if User A owns Resource B, must be explicitly enforced in business logic.

  • Action: Moved from simple identity checks to "Participant Validation" before executing database queries.

B. API Design & Availability

  • Insight: Semantic URLs (Slugs) improve User Experience and SEO but introduce complexity in input handling. An API that accepts multiple identifier formats (IDs vs. Slugs) increases the attack surface if not handled with strict type checking.

  • Action: Implemented "Smart Querying" logic to validate input types before execution, ensuring the API returns 404 Not Found instead of crashing with 500 Internal Error.

C. Frontend-Backend Trust Boundaries

  • Insight: Client-side routing logic (React Router) is a UI convenience, not a security control. "Hiding" a route or button in the UI does not prevent an attacker from crafting a direct API request.

  • Action: Enforced "Defense in Depth" by ensuring that every restricted UI action has a corresponding, redundant check at the API controller level.

3. Alignment with Standards (OWASP)

  • OWASP API Security Top 10 (2023):

    • API1: Broken Object Level Authorization (BOLA): Mitigated by implementing strict ownership checks on all resource-fetching endpoints.

    • API6: Unrestricted Access to Sensitive Business Flows: addressed by preventing unhandled exceptions that could expose stack traces or crash services.

    • API9: Improper Inventory Management: Highlighted the need for versioning and deprecation strategies when migrating from Integer IDs to UUIDs/Slugs.

  • Secure Design Principles:

    • Fail Safe Defaults: The application should default to rejecting access or returning a standard error when encountering ambiguous input, rather than attempting to process it and crashing.

    • Defense in Depth: Validation must occur at the Gateway (WAF), Controller (Input Validation), and Database (Schema) layers.

4. Developer Lessons ("What I Learned")

  • "The Happy Path is Dangerous."

    • Developers often code for the "Happy Path" (User clicks the right button). Security requires engineering for the "Malicious Path" (Attacker fuzzes the ID parameter).
  • "Type Safety != Security."

    • Using TypeScript or Mongoose schemas helps catch bugs, but it doesn't stop logic flaws. A strictly typed system can still be vulnerable if the logic governing those types is flawed (e.g., crashing on string-to-ObjectId conversion).
  • "Orphaned Data States."

    • In distributed systems (Microservices or Hybrid DBs), deleting a record in one domain (Profile) must cascade to others (Bookings). Failing to do so creates "orphan" data that can be exploited for logic bugs.

5. Safe Content Buckets

A. Key Security Lessons

  • Authorization must be relationship-based (ReBAC), not just role-based (RBAC).

  • Input validation is an Availability control (preventing crashes) as much as an Integrity control.

  • Public-facing identifiers (IDs) should be opaque or generic (Slugs) to prevent enumeration attacks.

B. One-Paragraph Public Summary

"In a recent security audit of a distributed web application, I focused on the critical intersection between API Availability and Authorization. The audit revealed that 'Contract Drift' between frontend features (like semantic URLs) and backend strictness can lead to unhandled exceptions, creating Denial of Service risks. By implementing 'Smart Controller' logic and reinforcing Relationship-Based Access Control (ReBAC), we successfully hardened the application against both BOLA attacks and logic-based crashes, ensuring that security scales alongside user experience."

C. Preventive Practices

  • Input Sanitization: Always validate that an incoming ID matches the expected format (UUID vs. Integer vs. Slug) before passing it to the database driver.

  • Centralized Error Handling: Never expose raw database stack traces to the client; catch exceptions and map them to standard HTTP codes (400/404).

6. Research Reflections (Non-Public / Academic Context)

Research Potential: This audit highlights the tension between Developer Velocity (shipping features fast) and Semantic Correctness in API design. This raised several research questions around API availability and design correctness that I plan to explore academically.

Why this benefits from developer-built systems: "Auditing a system I actively developed created a direct feedback loop between architectural decisions and security outcomes. This made it possible to trace vulnerabilities back to design trade-offs, such as balancing semantic URLs with database constraints and evaluate mitigations in a real-world context."

More from this blog

Kami

9 posts

Technical Writer specialized in API Documentation, User Manuals, and UI/UX Product Design. Skilled in producing clear, precise, and engaging content for various technical documents.