Today’s Lesson
Security for Legal SaaS — Episode 6: How Web Apps Actually Work
The Invisible Machine
Every time a lawyer clicks "Open Case File" in their practice management system, an invisible conversation happens. The browser sends a request across the internet, a server processes it, and a response comes back — all in under 300 milliseconds. Understanding this conversation is the foundation of every security control that follows.
Most legal SaaS vulnerabilities exploit gaps in this conversation. The browser trusts the server to send safe content. The server trusts the browser to send valid requests. Attackers exploit both assumptions.
Key stat: Web applications were the attack vector in 26% of all breaches in 2023, making them the single most exploited category according to the Verizon DBIR.
The Request/Response Cycle
HTTP (HyperText Transfer Protocol — the text-based language that web browsers and servers use to exchange information) is the language browsers and servers speak. Every interaction follows the same pattern:
- Client sends a request — a method (GET, POST, PUT, DELETE), a path (
/api/cases/12345), headers, and optionally a body - Server processes it — authenticates the user, validates the input, queries data, applies business logic
- Server returns a response — a status code (200 OK, 403 Forbidden, 500 Internal Server Error), headers, and a body
| HTTP Method | Purpose | Legal SaaS Example |
|---|---|---|
| GET | Retrieve data | Load a case file listing |
| POST | Create a resource | Upload a new document |
| PUT/PATCH | Update a resource | Edit matter notes |
| DELETE | Remove a resource | Archive a closed case |
Every request carries headers — metadata about the request. Security-critical headers include Authorization (who you are), Content-Type (what you're sending), and Origin (where the request came from). Attackers routinely manipulate these.
Clients, Servers, and the Trust Problem
The client is anything sending requests — a browser, a mobile app, a command-line tool, or an attacker's script. The server is the system that processes them.
Critical principle: The server cannot trust anything the client sends. HTTP requests can be crafted, modified, or replayed by anyone with a network connection. OWASP's Testing Guide emphasises that every client-supplied value — URLs, headers, cookies, form fields, hidden fields — must be treated as potentially malicious.
In legal SaaS, this matters acutely. A matter management system might send the matter ID in the URL: GET /api/matters/4521/documents. If the server only checks "is this user logged in?" without checking "does this user have access to matter 4521?", any authenticated user can enumerate and access every matter by changing the number. This is Insecure Direct Object Reference (IDOR), consistently in the OWASP Top 10.
Cookies, Sessions, and State
HTTP is stateless — each request is independent. The server doesn't inherently know that request #47 comes from the same user as request #46. Cookies solve this by storing a session identifier in the browser that gets sent with every subsequent request.
| Session Mechanism | How It Works | Security Consideration |
|---|---|---|
| Server-side sessions | Cookie holds opaque ID; server stores state | Session fixation, session hijacking |
| JWTs (JSON Web Tokens) | Token holds claims, signed by server | Token theft, no server-side revocation |
| OAuth tokens | Delegated access via tokens | Token leakage, scope creep |
Session Security Requirements
- HttpOnly flag — prevents JavaScript from reading the cookie (mitigates XSS token theft)
- Secure flag — cookie only sent over HTTPS
- SameSite attribute — restricts cross-origin cookie sending (mitigates CSRF attacks)
- Short expiry + rotation — limits the window of stolen session exploitation
NIST SP 800-63B recommends session timeouts proportional to the sensitivity of the data. For legal SaaS handling privileged communications, session durations should be aggressive — 15-30 minutes of inactivity.
APIs: REST, JSON, and Endpoints
Modern legal SaaS is typically a single-page application (SPA) communicating with a REST API (REST stands for Representational State Transfer — an architectural style where each URL represents a resource, and you use standard HTTP methods like GET and POST to interact with it). The browser loads once, then sends JSON requests to API endpoints for data.
The OWASP API Security Top 10 identifies the most critical API risks:
| Risk | Description | Legal SaaS Impact |
|---|---|---|
| Broken Object Level Auth | Accessing other users' objects via ID manipulation | Reading opposing party's documents |
| Broken Authentication | Weak token handling, credential stuffing | Unauthorised access to entire firm's data |
| Unrestricted Resource Consumption | No rate limiting on endpoints | Automated bulk exfiltration of case files |
| Broken Function Level Auth | Calling admin endpoints as a regular user | Paralegal invoking partner-only case closure |
Every API endpoint is an attack surface. Each must independently verify authentication and authorisation — never assume that because the frontend only shows certain buttons, the backend is protected.
The Browser as Trust Boundary
The browser is simultaneously the user's agent and a hostile execution environment. It runs code from your server, but also code from third-party scripts, browser extensions, and potentially injected content.
The Same-Origin Policy (SOP) is the browser's fundamental security model: scripts from https://legalapp.com cannot read responses from https://bankofamerica.com. Without SOP, any website could steal data from any other website you're logged into.
Cross-Origin Resource Sharing (CORS) relaxes SOP in controlled ways. Misconfigured CORS — particularly Access-Control-Allow-Origin: * on authenticated endpoints — is a common vulnerability that allows any website to read your API responses.
Legal SaaS Browser Trust Issues
- Browser extensions — a malicious extension can read DOM content of your legal SaaS, including privileged documents displayed on screen
- Third-party scripts — analytics, chat widgets, and error tracking scripts have full DOM access. Supply chain attacks via compromised third-party scripts have hit thousands of websites
- Local storage — tokens stored in localStorage are accessible to any JavaScript on the page, including injected scripts
- DevTools — any user can inspect network traffic, modify requests, and replay them. Client-side validation is UX, not security
Putting It Together: A Legal SaaS Request
When a lawyer opens a privileged document in your SaaS platform, here is what actually happens:
- Browser sends
GET /api/matters/4521/docs/789with session cookie - Server validates session cookie (authentication)
- Server checks: does this user have access to matter 4521? (authorisation)
- Server checks: does this user's role allow document reads? (function-level auth)
- Server retrieves document from storage
- Server sets response headers:
Content-Type,X-Content-Type-Options: nosniff,Content-Security-Policy - Browser receives and renders the document
Every step is a potential failure point. Skip step 3, and you have IDOR. Skip step 6, and you're vulnerable to content-type sniffing attacks. Return the document without proper Content-Disposition headers, and the browser might execute embedded scripts instead of displaying a PDF.
Conclusion
Web applications are conversations between untrusted parties over an untrusted network. The browser cannot be trusted to send valid requests. The server cannot assume requests come from legitimate clients. Every security control in the episodes that follow — input validation, injection prevention, access control — builds on this foundation.
Next episode: Input Validation and Sanitisation — where we examine how to verify that what the client sends is actually what you expect, before it touches your business logic.