Representative interview topic

Frontend Interview: How Do You Design Safe Local Network Access?

FrontendHard
Offer.cc Editorial TeamPublished Updated

Question

A public HTTPS dashboard configures a printer and a developer agent on the user's network. Design the frontend flow for local and loopback requests, including permission prompts, Permissions Policy in iframes, mixed-content handling, address-space checks, browser fallback, and tests that prevent an accidental production scan.

Question and scope

The dashboard is served from a public HTTPS origin. It sometimes calls a printer at a private address and a helper on localhost; it also embeds a vendor iframe that should not reach the local network. Explain how the browser distinguishes public, local, and loopback address spaces, when a user permission is required, and how the page should recover from denial.

Keep application authorization, CORS, and device authentication in scope as separate layers. The browser permission is a user-consent boundary, not proof that a printer belongs to the current account. Assume the product can offer a manual configuration path when a browser does not implement Local Network Access.

What the interviewer is testing

The key signal is whether you recognize a public page calling a private endpoint as a security boundary. A strong answer names CSRF-style attacks against routers and printers, then constrains the flow with secure context, address-space classification, permission state, and an allowlist for embedded content.

The interviewer will also probe whether you confuse local-network with loopback-network, or assume that a successful CORS preflight grants access. A good answer keeps policy, permission, mixed content, CORS, and device authentication as separate gates.

Questions to clarify before answering

  • Are all targets known in advance, or may users enter arbitrary IP addresses? Arbitrary scanning needs a different product boundary and should not be hidden behind a generic “connect” button.
  • Is the helper only on localhost, or can it be reached through a private subnet? This changes whether loopback or local-network permission is needed.
  • Can a vendor iframe or nested frame make the request? If yes, every frame boundary must explicitly delegate the feature and its possible navigation origins.
  • Which browsers and enterprise policies are supported? Rollout timing differs, so a compatibility path must be observable rather than silently weakening security.

A 30-second answer framework

“I would keep the dashboard on HTTPS, classify each destination as public, local, or loopback, and request only the corresponding browser permission when required. The response policy would deny local access to the vendor iframe; if an iframe must connect, its allow list would name exact origins and all navigation targets. I would check permission state before the action, show why access is needed, handle mixed-content and CORS failures separately, and provide a manual setup path for unsupported browsers. Tests would assert that arbitrary hosts and production ad frames never trigger a local-network request.”

Step-by-step deep answer

Step 1: Define the trust boundary and address spaces

A public website must not silently send state-changing requests to a user's router, printer, or development service. Model three destination classes: public addresses are globally reachable, local addresses are reachable only on the user's network, and loopback addresses target the same device. localhost is not equivalent to every private subnet.

The request inventory should include fetch, subresource loads, WebSockets, WebTransport, WebRTC, service-worker requests, and frame navigation. A library that opens a socket can cross the same boundary even when application code contains no direct fetch call.

Step 2: Require a secure context and explicit permission

Use an HTTPS top-level page. In supporting browsers, query the relevant permission before attempting the device action:

js
const localState = await navigator.permissions.query({ name: "local-network" });
const loopbackState = await navigator.permissions.query({ name: "loopback-network" });

Treat granted, prompt, and denied as product states. Explain the purpose before triggering a prompt; on denial, show a repair link or manual setup rather than retrying in a loop. An HTTP page must be considered unsupported for this flow even if a target happens to answer.

Step 3: Constrain embedded documents

The top-level response can delegate only the feature and origins that need it. A vendor frame gets no local-network capability:

http
Permissions-Policy: local-network=(self "https://dashboard.example"), loopback-network=(self "https://dashboard.example")

If a trusted setup frame must connect, delegate narrowly:

html
<iframe src="https://setup.example" allow="local-network https://setup.example; loopback-network https://setup.example"></iframe>

The header and iframe policy intersect. A frame cannot widen a parent denial. If the frame navigates to another origin that also makes local requests, list that origin explicitly or deny access after navigation. Nested frames need the policy at every boundary.

Step 4: Separate permission from mixed content and CORS

Permission does not make an insecure request universally valid. Some browser implementations permit selected local HTTP endpoints after consent, while other mixed-content checks still apply. Use the request's target address-space metadata only when the browser and endpoint contract support it; do not use it as a bypass for a public destination.

CORS answers whether the target permits the web origin to read a response. It does not authorize a public page to reach a printer, and it cannot replace device authentication. For a state-changing command, use a device-specific challenge or pairing code and make the command idempotent.

Step 5: Design fallback and telemetry

Unsupported browsers should expose a manual IP, a native helper, or a user-guided pairing route. Record destination class, permission state, policy result, browser capability, CORS result, and device-auth result without logging credentials or raw local responses. A production alarm should fire if a release causes a new host class to request local access or if an ad frame attempts it.

Step 6: Test the negative matrix

Test localhost, a private IP, a public hostname resolving publicly, a public hostname resolving locally, an HTTP page, a missing permission, a denied permission, a missing iframe delegation, a nested frame, a navigation to an unlisted origin, a blocked CORS response, a device-auth failure, and an address that changes class during DNS resolution. Verify that only the intended user action can trigger a prompt and that no background retry scans a range.

High-quality sample answer

“I would treat public-to-local requests as a capability that must be requested and scoped. The dashboard stays HTTPS, classifies printer and helper destinations separately, checks local-network or loopback-network state, and explains the prompt before making one bounded request. The response policy denies both features to the vendor iframe. If a trusted setup iframe is required, its allow list contains only the setup origin and every origin it may navigate to.

I would keep browser permission, mixed-content checks, CORS, and device authentication as separate gates. A denied or unsupported browser gets manual pairing instead of repeated requests. Tests cover local, loopback, public, DNS reclassification, nested frames, missing delegation, denied permission, CORS failure, and device-auth failure. The release stops if an ad or arbitrary host can trigger a request or prompt.”

Common mistakes

  • Treating every private IP as loopback → loopback and local network have different permission semantics → classify the destination before selecting the permission.
  • Retrying after denial until a prompt appears → this creates surprise and scan-like behavior → show context once and provide remediation.
  • Assuming CORS makes a printer trustworthy → CORS controls response sharing, not device identity → pair the device and authenticate commands.
  • Granting local-network * to a vendor frame → redirects and nested documents can expand the trust set → list exact origins or deny delegation.
  • Relying on a localhost-only test → it may not exercise the public-to-local boundary → test from a public HTTPS origin against each address class.

Follow-up questions and responses

Follow-up 1: Why did localhost work in development but fail in production?

Development may run from a loopback origin or a browser without the new restrictions. Production is a public origin crossing into loopback or local space, so secure context, permission, policy, mixed-content, and CORS gates all become relevant. Reproduce from a public HTTPS test origin.

Follow-up 2: Can an iframe inherit the top-level permission automatically?

Only within the policy and delegation rules. A cross-origin frame needs an explicit feature grant, and nested frames need their own delegation. The user decision is tied to the embedding context, but it does not bypass an absent allow or an unlisted navigation origin.

Follow-up 3: What if DNS for agent.example changes from public to private?

Reclassify the resolved address and require the appropriate permission and secure-context path. Do not cache a public classification forever. Log the classification transition and fail closed if the destination is not in the product's approved target set.

Follow-up 4: Why is a permission prompt not enough for a printer command?

The prompt says the user allowed network access from the site; it does not authenticate the device or authorize the requested operation. Pair the device, bind commands to an account and nonce, and make retries idempotent.

Public sources

Related questions