- A browser script cannot reliably prove that every visitor is or is not using a VPN.
- Collect visit evidence in the browser; keep API credentials and enforcement on your server.
- WebRTC addresses and timezone differences are not standalone VPN verdicts.
- Handle incomplete checks separately, and do not treat VPN use alone as proof of fraud.
On this page
JavaScript alone cannot reliably tell whether every visitor uses a VPN. A browser script can collect evidence, but a useful VPN detection flow needs a server-side assessment and a clear response to missing data. Maskbreak is a VPN, proxy and fake-browser detection API that combines live visit evidence with an allow, review or block recommendation.
This guide is for developers protecting a signup, login or checkout in a JavaScript application. It explains the boundary between browser collection and backend enforcement. If you only need to inspect an address, start with visit evaluation versus IP lookup; they do not provide the same evidence.
What can browser JavaScript actually see?
The browser exposes information about its environment and can communicate with your server. It does not give your page a trustworthy list of the visitor’s installed VPN apps or a universal “VPN enabled” flag. A timezone difference, unusual browser configuration or address classification can support an investigation, but each has ordinary explanations too.
| Clue | Why it is insufficient | What to do instead |
|---|---|---|
| Timezone and IP location differ | A device setting or travel can explain the difference. | Consider it alongside the connection and the protected action. |
| The address belongs to a cloud network | Cloud hosting does not establish a specific VPN or proxy service. | Keep hosting classification separate from tunnel evidence. |
| No suspicious browser value appears | A negative observation is not proof that a VPN is absent. | Record which checks completed and which were unavailable. |
Can WebRTC reveal the visitor’s real IP address?
Sometimes WebRTC exposes address information beyond what a visitor expects, but it is not a dependable VPN test. The IETF’s WebRTC address-handling requirements describe how routing, proxies and browser policies affect which addresses are available. MDN documents the privacy implications of candidate addresses and how applications can restrict candidates.
Do not make a customer’s ability to sign in depend on exposing another address. An absent candidate should not become “definitely a VPN,” and matching addresses should not become “definitely safe.” Trying to recover a hidden address also introduces a different privacy question from evaluating the connection your service actually receives.
Wire it into your own app: a free key returns decision, risk_score and reasons for every visit, 1,000 requests an hour, no card.
Get an API keyWhere should the VPN detection check run?
Use three stages: collect evidence in the browser, evaluate it on your server, then enforce your application’s policy before the protected action. The browser must not decide whether the request is allowed. Someone can bypass a disabled button or call an endpoint without using your page.
- Collect: load the Maskbreak SDK on the protected page. For a custom form, call
window.Sentinel.collect()after the SDK is ready. Forward itstoken,fingerprintEventIdand optionaltzto your own backend. - Evaluate: your backend sends that evidence to
POST https://maskbreak.com/v1/evaluate. KeepMASKBREAK_API_KEYin its environment or secret store, never frontend code. - Enforce: examine the decision and evidence availability before running the existing signup, authentication or payment handler. Keep authorization, CSRF protection and rate limits in place.
The following is only the server-side evaluation call, not a complete login route. The evidence object must come from your validated request body; your surrounding handler still needs input limits, authentication where appropriate, response validation and a timeout fallback.
const response = await fetch('https://maskbreak.com/v1/evaluate', {
method: 'POST',
signal: AbortSignal.timeout(5000),
headers: {
Authorization: 'Bearer ' + process.env.MASKBREAK_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
token: evidence.token,
fingerprintEventId: evidence.fingerprintEventId,
tz: evidence.tz
})
});
if (!response.ok) throw new Error('Visit check unavailable');
const result = await response.json();
// Validate result, check availability, then enforce your policy.
// An HTTP 200 alone is not permission to perform the action.Use the full integration guide for the form wiring and API reference for the response contract. For a full-device assessment, inspect device.complete and device.checked_signals; an unchecked boolean is not a verified negative.
Should a detected VPN block the customer?
Not automatically. Under Maskbreak’s base policy, VPN use alone produces review. Account rules and other signals can change the final recommendation. Your application can use a server-verified step, such as existing MFA, when the action warrants it. Read how to avoid rejecting legitimate VPN users.
Handle an incomplete check or timeout separately from a completed check with no detected warning signs. Pick a fallback based on the action: pausing a sensitive change may be reasonable, while a low-risk page view may not need to wait. Show a useful retry or support path instead of an unexplained error.
How do you test it before going live?
First exercise response handling with documented fixtures. Then test live collection on your own normal browser, a VPN connection and a privacy-restricted browser. Confirm that your server receives both evidence fields, and deliberately test what happens when either is absent. Fixture results cannot establish VPN detection coverage.
Maskbreak is free during open beta, with a standard allowance of 1,000 visitor checks per hour and no credit card. Evaluation and authenticated IP lookup share the key’s hourly allowance. Start with a small live test, confirm the deployed endpoint actually enforces its decision, and measure successful customer completion as well as flagged traffic.
Questions people ask
- Can JavaScript detect a VPN without an API?
- JavaScript can collect browser and connection clues, but no browser-only check reliably identifies every VPN. Maskbreak combines live visit evidence with server-side network and device checks; results still depend on the evidence available.
- Should I put my VPN detection API key in frontend JavaScript?
- No. Keep the Maskbreak API key in your backend environment or secret store. Send browser evidence to your own backend, which calls the evaluation API and enforces the result.
- Does a WebRTC IP address reveal every VPN?
- No. Address exposure depends on the browser, permissions, network configuration and routing. A missing address or a different address does not by itself establish whether a VPN is in use.
- Can I try JavaScript VPN detection for free?
- Maskbreak is free during open beta, with no credit card and a standard allowance of 1,000 visitor checks per hour. Check the current pricing and terms before rollout; the public sandbox tests response handling, not live detection accuracy.
Paste it in, then watch the verdicts
The public sk_test_sandbox key returns the documented allow, review and block shapes with no account, so the failure path is testable before you go live. SDKs for Node, Python and PHP, or plain HTTP. The <a href="/api">API reference</a> and the <a href="/pricing">free tier</a> cover the rest.