You are currently viewing Web Application Security: Check Each Boundary

Web Application Security: Check Each Boundary

A profile page should show the signed-in user’s address. But a browser can request someone else’s profile, too. The server has to decide, on every request, whether the current user may read or change that record. Hiding a button in the interface won’t enforce that rule.

Web application security protects an application’s data and functions as browsers, users, services, and networks interact. At each boundary, ask: What data is coming in? Who is making the request? What may they do? Those questions matter in a small study project as much as they do in a production service.

Follow one request through the application

A typical request starts in a browser and reaches a web server or application framework. The server may read a session, validate input, query a database, and build an HTML or JSON response. The browser can improve usability, but users control its code and form fields. Security decisions must happen on the server, using information it can verify.

Consider a notes application. The route identifies the requested note, while a session identifies the signed-in account. Before returning the note, the server checks that it belongs to that account or has been shared with it. A query that finds the note only by its identifier misses the crucial check.

Request path from browser to application and database

Know the main failure modes

Authentication is not authorization

Authentication establishes who a user is, often through a login that creates a server-recognized session. Authorization decides what that user may do with a particular resource. Signing in should not grant access to every account’s data. Check permissions on the server for each relevant read, update, and delete operation, including requests made through an API rather than a visible page.

Use a maintained framework’s session mechanism instead of inventing one. Session cookies should normally be marked Secure so they travel only over HTTPS, HttpOnly so browser scripts cannot read them, and given an appropriate SameSite policy. These settings address specific risks; they do not replace authorization checks. Logout should invalidate the session, and privileged actions may call for an additional identity check.

Input can cross into code or markup

Input is data until an application passes it into a context with special syntax. Joining strings to build a database query can let input change what the query means. Parameterized queries keep values separate from query structure. Putting untrusted text into HTML without context-appropriate escaping can likewise make a browser interpret it as markup or script. Template engines often escape ordinary text by default, but developers need to know when their code bypasses that protection.

Validation answers a different question: does the input meet the application’s rules for length, date range, file type, or another field? Validate on the server even when the browser validates a form. A value can pass those checks and still be unsafe in an output context, so validation cannot replace parameterization or output encoding.

Browsers may send requests without user intent

Browsers automatically include session cookies with some requests. That can allow another site to trigger a request the user did not intend—the basis of cross-site request forgery. For state-changing actions, use the framework’s CSRF protection where cookie-based authentication needs it, along with an appropriate SameSite setting. Don’t use a simple link or GET request for a state-changing operation. An API without automatically attached credentials has a different risk profile; its defenses should match how clients authenticate.

Put defenses where they belong

Each control should protect the boundary where a failure can occur. Here are common checks for a beginner project.

Boundary Practical check
Browser to server Use HTTPS, validate incoming data on the server, and apply request size limits.
Request to user data Check the signed-in user’s permission for the specific resource and action.
Application to database Use parameterized queries and a database account with only needed privileges.
Data to HTML Encode for the output context; avoid injecting untrusted text into executable script.
Application to logs Record useful events without storing passwords, session tokens, or unnecessary personal data.

HTTPS protects traffic between the browser and the endpoint it connects to. It cannot fix faulty permissions or unsafe code. Configure it throughout the deployed path, including any reverse proxy, and do not serve login pages or authenticated content over HTTP. Store passwords with a reputable password-hashing function designed for that purpose, not reversible encryption or a general-purpose fast hash. Prefer established framework authentication components to custom password handling.

Make ordinary features safer

Uploads, errors, and third-party code

A filename check is not enough for uploads. Limit file size, accept only formats the feature needs, inspect content instead of trusting its declared type, and store uploads outside executable application paths. When serving files back, set an appropriate content type and download behavior. A profile-picture feature, for example, rarely needs to accept arbitrary documents.

Error messages should help users recover without revealing database queries, stack traces, secrets, or internal file paths. Keep detailed diagnostics in access-controlled logs, with sensitive fields removed or masked. Review dependency and framework updates: the application also relies on code your team did not write. Remove packages and features the project no longer uses so they do not become additional maintenance work.

Developer checks protections for a web application

Configuration is part of the application

A safe local setup can become unsafe in deployment if debug mode stays on, default credentials remain in place, or administration pages are broadly exposed. Keep secrets out of source control, limit access to deployment settings, and give application and database processes only the permissions they need. Protect backups with access controls and test the restore procedure; a missing or unreadable backup will not help after a mistake or outage.

Practice with a small application you control

A local notes project lets you test these assumptions without probing anyone else’s system. Create two test accounts and one note owned by each. In your test environment, use the application’s normal interface to verify that each account can view its own note but cannot view or edit the other’s. Check that editing fails after logout, then repeat the permission checks for any API endpoints the interface uses. These are authorization tests on an application you control, not exercises against a public service.

Add a few automated checks: reject an empty title with a clear error, display HTML-like characters in note text as text, and reject an update without the expected CSRF protection if the application uses cookie sessions. Run the tests again after changing routes or data-access code. If the second account can still edit the first account’s note, fix the server-side ownership check before touching the interface. Removing the edit button will not close the gap.