Public Portal DDoS Protection: Cache Without Leaking

Improve public portal DDoS protection with safe CDN caching, targeted traffic controls, and practical checks that keep private candidate submissions working.

Ernest Bursa

Ernest Bursa

Founder · · 13 min read
Three startup coworkers discussing operations beside networking equipment in an open Los Angeles garage

Public portal DDoS protection starts with separating information anyone can read from actions and records that belong to one person. Keep verified public responses cheap to serve through a content delivery network, or CDN. Exclude private and credential-bearing responses from shared storage, then test whether applicants and security researchers can still complete their submissions when traffic controls are active.

A working careers page is only one part of a working hiring process. The candidate still needs to open a private link, upload a file, and receive a truthful acknowledgement. A security researcher needs to find reporting instructions and send a confidential report. If protection works on the first page but breaks those later steps, people cannot complete the task they came for.

This proposed engineering review is designed for a small team. It combines a recent incident lesson with a practical exercise you can adapt to your own application. It is not an attack-resistance certification or a promise that a particular hosting configuration will stay available.

What did Read the Docs learn from uncached requests?

Requests that look trivial can still consume scarce application capacity. Start your review with the paths that reach the origin server, where your application runs, rather than assuming popular pages account for all the work.

Read the Docs published its incident account on September 8, 2026. The attack itself happened in mid-to-late June and lasted nearly ten days. The provider reported a peak above 5.5 million requests per minute, changing request signatures, and traffic aimed at uncached responses. Temporary redirects initially reached its Python backend; the team moved those redirects to the edge. Requests for unique nonexistent paths also created expensive misses. Its response included targeted challenges because challenging every reader would disrupt integrations.

Those observations describe Read the Docs, not Kit or your company. The useful question for your team is narrower: which apparently cheap requests still make your application do work?

Begin with a fictional portal

For this exercise, imagine a small software company with a public careers site and a vulnerability-reporting program. A job seeker can read a role description anonymously. A candidate can follow a private link to their application. A researcher can read the security policy and then submit details that must remain confidential.

Give the recruiter, security lead, and engineer a blank sheet of paper. Ask each person to draw their journey from entry to acknowledgement. Include old bookmarked addresses and links in previously sent emails. This is a proposed workshop, not a description of any customer’s incident.

Now mark where each step needs the application server. A redirect may need a database lookup. A missing page may render a personalized layout. A form may include a token. Find these dependencies before an emergency prompts a broad caching change.

For ownership questions beyond this exercise, our guide to self-hosting and staffing responsibility helps frame who maintains the service. Here, keep the review focused on incoming traffic and what each response contains.

How do you decide which portal responses are truly public?

Classify the complete response, including its headers and variants. A public-looking address does not prove that every visitor receives the same material or that a shared cache may safely reuse it.

The HTTP caching standard, RFC 9111, distinguishes three easily confused directives. no-store tells caches not to store the response. private prevents storage by a shared cache. no-cache allows storage but requires validation before reuse. An Authorization request header is not an absolute fence either: explicit response directives can permit shared reuse. Copying a familiar header name without understanding these distinctions is not enough.

Make a response inventory

Use the following table as a proposed review worksheet. It is an aid to engineering judgment, not a compliance standard. Assign one person to collect evidence for each row and another to review the conclusion.

Surface Question to answer Evidence to collect
Public job information Is this entire response safe for every intended reader? Anonymous and authenticated responses, tenant and language variants, meaningful query parameters
Redirect or missing page Can the destination or body depend on identity? Response headers, destination, body, cache key, and permission-dependent behavior
Private candidate page Does the link or response grant access or reveal personal information? Token handling, storage policy, session behavior, and isolation between test users
Application or report submission What proves that the action was accepted? Request result, stored record, failure state, and acknowledgement behavior
API or upload Can its client handle the protection response? Expected format, actual content type, authentication state, and failure handling

Work through real examples using test accounts and dummy information. Compare two tenants, two languages, a signed-in visitor, and an anonymous visitor where those states exist. Add the states your product actually supports instead of treating this list as exhaustive.

Pay attention to a page’s small details. A generic job description might sit beside a candidate name or a form token. The central text being public does not make the assembled response shareable. Decide whether to separate public data from the private interface, rather than trying to declare the whole page harmless.

Preserve the distinctions that change meaning

A cache key determines which requests are treated as asking for the same response. Cloudflare’s cache-key documentation describes how ignoring query strings can combine requests that differ in those parameters. Evaluate that option before enabling it across a portal.

For the exercise, write the meaning of every key component beside it. The host may identify the customer. The language may change instructions. A filter may select a different role. A credential may change who is allowed to see the response. If you cannot explain why a distinction is safe to remove, leave it intact while you investigate.

Keep sanitized evidence of the comparison. Record which routes were examined, which states were tested, and what remains unknown. A screenshot alone cannot demonstrate a cache policy. Avoid putting real candidate links or confidential report content into the review document.

How should you protect redirects and missing pages?

Review redirects and error responses as separate resources with their own privacy and freshness rules. A status code tells you what happened; it does not tell you whether the response is safe to share.

For the fictional company, start with an old careers URL. If its destination is fixed and public, ask whether that redirect can be handled before the application server. Then try an old candidate link. Its destination could depend on authentication or application state, so it needs a separate decision even if both responses use the same redirect status.

Treat missing pages with similar care. A short-lived cached public 404 can avoid repeated work for the same absent resource. It cannot stop an unlimited stream of new nonexistent paths from reaching the origin, because each path can produce a new cache miss. A response that hides a private resource from an unauthorized visitor also needs a different policy from a genuinely public missing page.

Give stale information an owner

Caching introduces a product question: how long may yesterday’s answer remain visible? Set that tolerance for each public resource instead of choosing one convenient lifetime for the whole site.

For a job listing, have the recruiter describe the consequence of showing a closed role as open. For a security policy, have the security lead identify which changes require urgent publication. A new contact address and a cosmetic wording correction may deserve different treatment. These are decisions for the proposed review, not universal expiry recommendations.

Cloudflare’s cache-control documentation explains that origin headers, configured overrides, cookies, and stale-serving behavior interact. Test the effective response at the deployed edge. Do not assume a header declaration in application code establishes what visitors actually receive.

Use a dummy job to rehearse a state change. Read it through the public route, close it, and check when the public representation changes. Then attempt the relevant action using the earlier page. The application should make its acceptance decision from current state, rather than treating a cached description as permission to proceed.

Keep reporting information current

A reporting policy needs its own freshness check. RFC 9116 defines security.txt, including its Expires field and reporting contacts. Expired information should not be used. Contacts can include web, email, or phone alternatives, but the file concerns vulnerability reporting, not a general incident-response hotline.

In your exercise, follow every published reporting route with harmless test content through an approved test process. Confirm who receives it and how the sender learns what happened. A policy that loads quickly is useful only if its instructions lead to a maintained reporting channel.

If you are still establishing that process, start with the vulnerability disclosure program guide. Keep public instructions distinct from the private report they help someone submit.

How do you keep traffic challenges from blocking submissions?

Match protection rules to the clients and actions they affect. A browser viewing a page and an integration sending a structured request may respond very differently to the same challenge.

Cloudflare’s challenge-page documentation explains that these pages return HTML. A client expecting JSON can therefore receive a response it cannot use. Browser pre-clearance can help suitable browser flows, but it is not a general fix for APIs or webhooks.

For the proposed test, list the requests made after the page opens. Include submission, upload, authentication, and any callback your integration uses. Record the expected response format next to each request. Then exercise the flow with the actual protection rule enabled in a suitable test environment.

Do not stop when the initial browser challenge succeeds. Submit the form, follow the next link, and check the stored result. If an upload fails, inspect the response format before blaming the file. If a callback fails, inspect it as a separate client rather than assuming the browser’s successful journey covers it.

Review false positives with the people affected

Ask the recruiter and security lead what a blocked legitimate user would see. Can that person tell whether anything was received? Is the next step understandable? Does retrying risk confusion about whether a submission already exists?

Use dummy submissions to inspect those states without creating unexpected work in production queues. Agree on an alternate contact route appropriate to your organization and keep confidential details out of public status pages. Do not label a fallback page as a successful submission unless the underlying action was accepted.

Rate limits deserve the same scrutiny. Cloudflare documents NAT-aware rate-limit options with cookie-related caveats; features also depend on the plan. Its request-rate guidance explains that counters are not shared globally across every data center. An edge rule is therefore not a strict global transactional quota.

Do not choose a numerical limit simply because another company uses it. Observe your legitimate flow and identify what a repeated action means. A burst of page reads, a large upload, and repeated form submissions have different consequences. Write down the rule’s intended purpose and the evidence that would make you change it.

How should you test the complete candidate and researcher journey?

Test success, rejection, and recovery through the deployed protection path. Availability means that an authorized person can complete the intended task and understand the result, not simply that a monitor receives a successful homepage response.

Use this proposed release exercise before a broad cache or traffic-rule change. Run it with synthetic information, agreed owners, and a clear rollback decision. It is a functional review, not a substitute for a separately planned load test.

  1. Read the public information. Open the role or policy through its real entry route. Check the customer, language, current status, and contact details. Repeat through an old public link where one exists.
  2. Enter the private journey. Use separate test identities. Check that each person sees only their own information and that an anonymous request does not inherit a previous visitor’s response.
  3. Complete the action. Submit the dummy application or report and upload a harmless file if supported. Verify the accepted record through the appropriate internal interface.
  4. Trigger an ordinary failure. Use an invalid field or an expired test link. Check that the explanation is useful and does not reveal another person’s information.
  5. Change the public state. Close the dummy role or revise the test policy. Inspect freshness and repeat the relevant action from an older page.
  6. Inspect every client. Check browser requests and integrations separately. Record content types, challenge behavior, and whether the client can recover.

Keep the exercise usable for people who navigate without a mouse. Our keyboard-accessible candidate portal checklist covers that part of the journey. A challenge or recovery screen added during an incident should receive the same attention as the original form.

Define what allows the change to ship

Before testing, agree on the evidence needed to proceed. For the fictional team, a sensible proposed gate is that public information remains correct, private responses remain isolated, intended submissions succeed, and rejected actions produce truthful feedback. Assign each failure to an owner instead of collapsing everything into an uptime percentage.

Retain a concise record of the rule changed, the test states, the observed results, and the rollback steps. Compare edge behavior with application behavior where you have visibility. If a gap remains, describe it precisely: an untested callback is different from a failed candidate submission.

Repeat the affected checks when you change the rule or the journey. There is little value in repeatedly testing an unchanged homepage while a new upload route goes unexamined. Match the scope of the review to the change.

Where does Kit separate public information from private work?

A single product can contain public information and confidential workflows that require different treatment. Inspect the actual response before making a cache decision, including when the controller or route has “public” in its name.

In Kit’s source inspected on September 10, the JSON response for a job accepting applications declares a five-minute public cache lifetime. An active security program’s security.txt response declares a one-hour public lifetime. These are narrow application declarations, not measurements of deployed CDN behavior or submission availability.

The candidate journey is different. A magic-link token resolves the candidate and their applications, interviews, offers, and related state. The public job HTML path can also resolve a candidate grant from the session. Those facts prevent treating every anonymously reachable page as interchangeable public content.

Kit also includes submission rate limits in application middleware. That is one layer of the request path, not proof that upstream traffic cannot exhaust resources. This article includes no production response audit, load test, or DDoS guarantee. Referrer and indexing protections likewise do not establish that a response sends Cache-Control: no-store.

Bring the same response inventory to your own portal. Keep verified public information inexpensive to serve, give private journeys a separate policy, and test the acknowledgement a real person depends on.

Review the journeys your team depends on. Explore how Kit brings hiring and security reporting into one product.

Start a free trial

Related articles

Ready to hire smarter?

Start free for 30 days. Cancel before it ends and you pay nothing. Set up your first hiring pipeline in minutes.

Start hiring free