Back to Blog
Application Security
8 min read

API Rate Limiting for Patient Portals: Stopping Abuse Early

Credential stuffing, account enumeration and scraping all look like ordinary traffic one request at a time. Rate limiting is what makes the pattern visible and expensive.

GuardsArm Team

Security Experts

January 4, 2026

API rate limiting

A single login attempt is indistinguishable from a legitimate one. Ten thousand of them, spread across accounts, is credential stuffing. Rate limiting is the control that turns that volume into something you can see and refuse — and on a patient portal it is doing more work than almost anything else.

Reused passwords
Portal credentials are frequently reused from breached consumer sites
Enumeration
Confirming whether someone is your patient is itself a disclosure
Cheap for attackers
Without limits, unlimited attempts cost the attacker nothing

Limit per endpoint, not globally

A single global limit is either too loose to stop abuse or too tight for normal use. Different endpoints carry different risk and need different budgets.

EndpointSuggested limitRationale
Login5 per account per 15 min, 20 per IP per 15 minStops stuffing without locking out a fumbling patient
Password reset request3 per account per hourPrevents reset-flood harassment
Registration / enrolment3 per IP per hourThe enrolment attack surface — see below
Record retrieval60 per session per hourGenerous for a person, restrictive for a scraper
Bulk document download10 per session per hourLegitimate use is small
Search / lookup30 per session per hourClassic enumeration endpoint
Message send20 per session per hourAbuse and spam control

Enrolment deserves particular attention, because portal compromise more often defeats registration than login — covered in patient portal security.


What to key the limit on

Keying on IP alone fails in both directions: it punishes a hospital's own NAT gateway and it does nothing against a botnet.

What to rate limit on, by reliabilityAccount and session identifiers are the most reliable keys; IP is a weak signal on its own because of NAT on one side and botnets on the other.Account identifierCorrect for login and reset — the thing being attackedSession or tokenCorrect for authenticated endpointsDevice fingerprintUseful supplement; imperfect but raises attacker costIP addressUseful for unauthenticated endpoints, weak aloneASN or geographyBlunt, for gross anomalies only
Combine keys: a per-account limit AND a per-IP limit catch different attacks.
Do not let the limit become an oracle
If an over-limit response differs depending on whether the account exists, the rate limiter has become an enumeration tool. Responses must be identical in content and timing regardless.

Distributed attacks need a different answer

An attacker with a thousand IPs each making five requests defeats per-IP limiting entirely, and never trips a per-account limit if they are spraying one password across many accounts.

What catches it:

  • Global anomaly detection — total login failures across the portal, not per source. A step change in the aggregate is the signal.
  • Password spraying detection — many accounts, one password, low per-account volume. Detect on the failure pattern, not the rate.
  • Reputation and bot management for known-bad infrastructure.
  • Adaptive friction — introduce a challenge when the aggregate failure rate rises, rather than blocking outright.

Failing gracefully

How you respond matters as much as when:

  • Return 429 with a Retry-After header, not a generic 500
  • Exponential backoff rather than a hard lockout, which is itself a denial-of-service against your own patients
  • Never lock permanently on failed logins; an attacker will lock every account they can name
  • Log every limit breach with enough context to investigate
  • Alert on the aggregate, not on individual events

Do not break legitimate integrations

Patient portals increasingly serve third-party applications over FHIR, and those clients behave nothing like a browser. A health app syncing a year of records makes a burst of requests that looks exactly like scraping.

Treat them separately: authenticated API clients get their own registered identity, their own quota appropriate to the integration, and their own monitoring. Applying browser-shaped limits to a sanctioned FHIR client breaks it, and the usual fix — raising the global limit — removes the protection for everyone.

GuardsArm tests patient portals and their APIs including rate limit bypass, enumeration and distributed credential attacks. Book a scoping call.

Written by GuardsArm Team

Our team of cybersecurity experts brings decades of combined experience in penetration testing, compliance auditing, and incident response. We're dedicated to helping organizations strengthen their security posture.

Take the next step on “API Rate Limiting for Patient Portals: Stopping Abuse Early”

Talk to the GuardsArm team about how these services apply to your environment.