Security

Customer Portal Security: The Authorization Model Decides Everything Else

Portals fail on authorization, not on login. Here is where the check belongs, why OWASP moved broken access control to number one, the two places portals leak, and the questions to settle before a line of code is written.

Almost every customer portal that leaks data has working authentication. The login page is fine, passwords are hashed, sessions expire. What goes wrong is the next question, asked several thousand times a day and answered in a hurry: this logged-in person is asking for record 4471, should they get it? That is authorization, it is a different problem from login, and on a portal it is the problem. Everything below is the model we set before writing code on a client, customer or vendor portal, with the industry evidence linked so you can check it.

Authentication answers who you are, once. Authorization answers what you may touch, on every single request. A portal is mostly the second thing, and almost all the expensive mistakes live there.

What the industry data actually says about access control

This is not a matter of taste. In the OWASP Top 10 for 2021, read on 29 September 2026, broken access control is ranked first, "moving up from the fifth position". The category has 34 CWEs mapped to it, and the data behind the ranking is the part worth quoting to a sceptical stakeholder: "94% of applications were tested for some form of broken access control", with an average incidence rate of 3.81 percent, the highest number of occurrences of any category in the contributed dataset.

Authentication failures sit lower and have moved the other way. Identification and authentication failures ranks seventh, with 22 CWEs and an average incidence rate of 2.55 percent, and OWASP notes it "slid down from the second position". The industry got better at logging people in and did not get better at deciding what they may see once they are in.

That is the whole argument for spending the first week of a portal project on the authorization model rather than the screens. The screens are the cheap part and everybody has opinions about them. The model is the part that is expensive to change after launch, because by then it is embedded in every query.

Four questions that define the model

Before anyone draws a wireframe, four answers need to exist in writing. In our experience these are the questions that, left unanswered, produce the rebuild eighteen months later described in what a custom portal costs and what takes the time.

Write the answers as four sentences and get them signed off by whoever owns the commercial relationship, not just by engineering. Question three in particular is a commercial question wearing a technical hat, and the person who knows the answer is usually in sales.

One more thing belongs in that document: what happens when a person leaves a tenant. Portals are built for joining and almost never for leaving, and the orphaned account with live credentials to a former client’s data is the finding that turns up in the first real security review.

Where the check belongs, and where it does not

The single most common portal defect we see in inherited code is an authorization check that lives only in the layer the user can skip. Hiding a button is not access control. Filtering a list in the client is not access control. The only checks that count are the ones on the far side of the network boundary, as close to the data as you can put them.

LayerWhat it can enforceWhat it must never be trusted for
Client UINot showing a control the user cannot useAnything. It is a hint, and the API is reachable with curl
API route or controllerAuthentication, tenant resolution, coarse role checksRecord-level ownership, because one missed route is a breach
Service or domain layerBusiness rules such as "only the case owner may reassign"Nothing, provided every path goes through it
Data access layerTenant scoping applied to every query by constructionBusiness rules it cannot see, such as workflow state
DatabaseRow-level security as a backstop when the platform supports itBeing the only check, because it is hard to reason about
The layers a portal request passes through. The useful rule is that tenant scoping belongs so low that writing an unscoped query is awkward, and business rules belong high enough to be readable.

OWASP puts the design rule plainly, and it is worth adopting verbatim as a code review standard.

“Except for public resources, deny by default.”

OWASP Top 10:2021, A01 Broken Access Control, read 29 September 2026

The companion rule is about records rather than routes: "Model access controls should enforce record ownership rather than accepting that the user can create, read, update, or delete any record." In a portal that means the query, not the route, carries the tenant. A repository method that can be called without a tenant should not exist, because eventually it will be called that way by someone in a hurry on a Friday.

The practical implementation is boring and works: resolve the tenant once per request from the verified session, put it in a request context the data layer reads, and make the base query builder apply it. Then the dangerous code is the code that deliberately opts out, which is a small and reviewable set, instead of every query that forgot to opt in. The same discipline runs through our notes on building a REST API with Node, Express and PostgreSQL.

Files are where portals leak

Portals exist to exchange documents, so files are usually most of the value and almost always the weakest surface. The failure is nearly always the same: the application checks permission when it renders the list of documents, then hands out a URL that nothing checks again.

  • Predictable object keys. If the storage path contains a sequential identifier and the bucket is readable, the portal is a directory listing with extra steps.
  • Permanent signed URLs. A pre-signed link with a long expiry is a bearer credential. It gets forwarded in email, pasted into a ticket, and outlives the relationship it was issued for.
  • No check on download. Serving files through a route that authenticates but does not re-authorize the specific object is the same defect as a missing record check, moved to the part nobody tests.
  • Uploads trusted by extension. Content type from the client is a suggestion. Portals accept files from outside the organisation by definition, which is exactly the threat model a staff-only tool does not have.
  • No audit on access. When a customer asks who downloaded their document and when, the answer has to exist. Retrofitting that log after the question is asked is worse than useless.

The fix is short: store files under opaque identifiers, serve every download through an endpoint that re-runs the same ownership check the list used, issue short-lived signed URLs rather than durable ones, and log every access with the actor, the object and the timestamp. OWASP adds the operational half of it: "Log access control failures, alert admins when appropriate (e.g., repeated failures)." A portal that logs only successes cannot tell you that somebody spent last night walking the identifier space.

Sessions, and the part of login that still matters

Authorization is the bigger problem, but the login surface of a portal has a specific property worth naming: the users are outside your organisation. You cannot mandate their device, their password manager or their training, and you will have accounts that sit unused for months and then log in from a new country.

OWASP’s guidance for that surface is concrete. Use "a server-side, secure, built-in session manager that generates a new random session ID with high entropy after login". Implement "weak password checks, such as testing new or changed passwords against the top 10,000 worst passwords list". And "where possible, implement multi-factor authentication to prevent automated credential stuffing, brute force, and stolen credential reuse attacks". It also points policy at NIST 800-63b rather than the old complexity-and-rotation habits, which is the change most enterprise portals have still not made.

For a portal serving business customers, the strongest option is usually to stop holding passwords at all: federate to the customer’s own identity provider where they have one, and offer passkeys where they do not. We covered the implementation detail of the second in WebAuthn and passkeys in Node. Either route removes an entire class of incident from your estate and moves the account lifecycle to the party that actually knows when someone leaves.

What you take on by building rather than buying

A portal platform sells you an authorization model you did not have to design, and charges for it per user. Microsoft’s Power Pages pricing page, read on 29 September 2026, publishes $200.00 per website for 100 authenticated users per site per month paid yearly, and $75.00 per website for 500 anonymous users per site per month paid yearly, sold in capacity packs of 100 and 500 respectively. That is roughly $2 per authenticated user per month, stepping in blocks of 100.

Read that as a price for the security work as much as for the hosting. Whichever way you go, the surface below has to be owned by somebody, and the question is only whether it is your team or the vendor’s.

SurfaceOn a portal platformOn a custom build
Identity and session managementVendor, configured by youYours, unless you federate
Tenant and record scopingVendor primitives, misconfigurableYours, by construction, if you design it first
File access control and auditUsually vendor, worth verifying per objectYours, and the most commonly skipped
Patching the frameworkVendorYours, forever
Proving it to an auditorVendor attestations plus your configurationYour own evidence, which is why the audit log has to be designed in
Cost shapePer user, stepping in capacity blocksFixed build plus ongoing maintenance
Neither column is free. A platform converts engineering risk into a per-user line item; a custom build converts a per-user line item into engineering you own.

The cost crossover is a separate calculation and we worked it through in custom portal development costs and timelines. The security point here is narrower: if the requirement is data-dependent authorization that a platform cannot express, buying does not remove the work, it just hides it in a pile of configuration that nobody can review.

The review before a portal goes live

Run this as an adversarial session with two people and real credentials from two different tenants, not as a checklist someone ticks alone. Every item below has been a genuine finding on a portal that had already passed its own testing.

  • Swap the identifier. Log in as tenant A and request tenant B’s record by id, on every resource type, through the API rather than the UI. This is the single highest-yield test that exists.
  • Call the route the UI hides. Find an admin-only endpoint, call it as a standard user, and confirm the response is a refusal and not an empty success.
  • Forward a file link. Take a document URL as one tenant, open it logged out and as another tenant, and check the expiry actually expires.
  • Remove a user mid-session. Revoke access while a session is live and confirm the next request fails rather than the next login.
  • Read the logs afterwards. Every one of the attempts above should be visible, attributed and timestamped. If they are not, the portal cannot tell you about a real attacker either.
  • Check staff access. Whatever your own support team can see, confirm it is logged and scoped. Internal access to customer data is a control, not a convenience.

This list also does most of the work for a compliance exercise, because access control and logging are where those frameworks concentrate. If that is on the horizon, our SOC 2 readiness checklist covers what the evidence has to look like, and the hardening in securing a Node application in production covers the layer underneath.

If you are commissioning a portal and want the authorization model written down and reviewed before the build starts, or you have inherited one and want the swap-the-identifier test run properly across it, talk to us. Examples of the portals we have built are on the work page.

What is the biggest customer portal security risk?

Broken access control, by a wide margin. OWASP ranks it first in the 2021 Top 10, having moved up from fifth, with 34 CWEs mapped and 94% of tested applications showing some form of it. In a portal it usually appears as a record that belongs to one customer being returned to another because the check was on the route rather than on the query.

Is multi-factor authentication enough to secure a portal?

No. MFA is strongly recommended by OWASP to prevent credential stuffing and stolen credential reuse, and it closes the login surface. It does nothing about what a legitimately logged-in user can reach. A portal with perfect MFA and no record-level authorization still hands one customer another customer’s invoices.

Should tenant scoping live in the database or the application?

Put it as low as you can while keeping it readable, which for most stacks means the data access layer applies it to every query by construction, with database row-level security as a backstop where the platform supports it. The goal is that writing an unscoped query is awkward and deliberate, rather than the default that someone forgets to override.

How should portal file downloads be secured?

Store objects under opaque identifiers, serve every download through an endpoint that re-runs the same ownership check used to list the file, issue short-lived signed URLs rather than durable ones, and log every access with actor, object and timestamp. A long-lived signed URL is a bearer credential that outlives the relationship it was issued for.

Does buying a portal platform remove the security work?

It moves it. A platform supplies identity, session management and framework patching, and prices that per user: Power Pages publishes $200 per website for 100 authenticated users per month paid yearly. What it cannot supply is a correct model of your tenants, roles and record ownership, and a misconfigured platform leaks exactly as effectively as a poorly built application.

What should be tested before a portal launch?

Run an adversarial session with real credentials from two tenants. Request one tenant’s records as the other through the API, call admin-only endpoints as a standard user, forward a signed file URL and check it expires, revoke a user mid-session and confirm the next request fails, then read the logs and confirm every attempt is attributed and timestamped.

Need help building this?

Let our team build it for you.

Dude Lemon builds production-grade web apps, APIs, and cloud infrastructure. Get a free consultation and project proposal within 48 hours.

Start a project