LAN / Localhost — enable intranet & dev hosts safely
Remote Tab Opener is deny-by-default for local networks. Here is how to allow intranet and localhost in v7.10.0.
Rule of thumb: you need two things — popup flags and allow-list.
2) Why it’s off by default
- Predictability & safety — local services are diverse; an opt-in avoids accidental control of sensitive tools.
- Consent — you choose which hosts are controllable (allow-list) and explicitly toggle LAN/localhost usage.
- HTTPS discipline — keep the same security posture as for public domains.
- Turn on the flags in the popup: Allow intranet (LAN) and/or Allow localhost (dev).
- Add the host(s) to the allow-list (wildcards allowed, HTTPS only).
3) Enable LAN / Localhost (2 steps)
Step 1 — Toggle the flags in the popup
- Open the extension popup.
- Tick Allow intranet (LAN) for hosts like
*.corp.localor10.x.x.x. - Tick Allow localhost (dev) for
localhost/127.0.0.1.
Flags enable the category of hosts; they don’t whitelist specific domains by themselves.
Step 2 — Add the exact host(s) to the allow-list
- In the popup, add your host(s) to the Allow-list.
- Use
https://origins (recommended). Wildcards like*.corp.localare accepted.
Both steps are required. If one is missing, requests will be blocked.
4) Allow-list examples
| Goal | Example entry | Notes |
|---|---|---|
| Single dev app on localhost | https://localhost:5173 |
Port matters. Match your dev server port. |
| Any subdomain in a corp zone | https://*.corp.local |
Wildcard host allowed; scheme is still https://. |
| Numeric intranet IP | https://10.0.1.23 |
Consider using a cert (self-signed or internal CA) in dev. |
| QA farm | https://qa-*.intra.example |
Prefix wildcards are useful for ephemeral stacks. |
about:, chrome:, file:, moz-extension: are restricted by the browser — content scripts don’t inject there.
5) Quick Start (copy & paste)
5.1 Helper + detect (works on LAN/localhost too)
Canonical envelope with requestId. Keep a single instance on your page.
<script>
const ADMIN_ORIGIN='admin', EXT_ORIGIN='extension';
let _seq=0, _waiters=new Map();
addEventListener('message', (e) => {
const d=e.data; if(!d||typeof d!=='object') return;
if(d.origin!==EXT_ORIGIN) return;
if(d.requestId && _waiters.has(d.requestId)) { _waiters.get(d.requestId)(d); _waiters.delete(d.requestId); }
});
function ask(action, args={}, timeoutMs=12000){
const requestId='r'+(++_seq);
postMessage({ origin:ADMIN_ORIGIN, type:'RTO_REQUEST', requestId, action, args }, '*');
return new Promise((resolve,reject)=>{
const t=setTimeout(()=>{ _waiters.delete(requestId); reject(Object.assign(new Error('timeout'),{code:'TIMEOUT'})); }, timeoutMs);
_waiters.set(requestId, (resp)=>{ clearTimeout(t); resolve(resp); });
});
}
(async () => {
const det = await ask('detect');
console.log('RTO present?', det.ok);
})();
</script>
5.2 Open an intranet (LAN) tab and act
Prereqs: Allow intranet (LAN) checked + host added to the Allow-list.
<script type="module">
const det = await ask('detect'); if (!det.ok) throw new Error('RTO not detected');
await ask('openTab', { url:'https://intranet.corp.local/dashboard', tabKey:'intra', focus:true });
await ask('domType', { selector:'#q', value:'status', clear:true, tabKey:'intra' });
await ask('domClick', { selector:'form button[type=submit]', tabKey:'intra' });
const page = await ask('getUrl', { tabKey:'intra' });
console.log('Intranet at:', page.ok ? page.data.url : '(unknown)');
</script>
5.3 Localhost (dev server)
Prereqs: Allow localhost (dev) checked + https://localhost:<port> in the Allow-list.
<script type="module">
await ask('openTab', { url:'https://localhost:5173', tabKey:'dev', focus:true });
// Simple highlighter using runJs (to show we're in control):
await ask('runJs', { tabKey:'dev', code:`(function(){
const el=document.querySelector('body'); if(!el) return false;
el.scrollIntoView({behavior:'smooth',block:'center'});
el.style.transition='box-shadow .2s';
el.style.boxShadow='0 0 0 4px rgba(13,110,253,.35)';
setTimeout(()=>el.style.boxShadow='', 800);
return true;
})()` });
await ask('navigate', { url:'https://localhost:5173/docs', tabKey:'dev' });
</script>
6) Troubleshooting
| Symptom / Error | Likely cause | Fix (beginner checklist) |
|---|---|---|
DOMAIN_NOT_ALLOWED |
Host not on Allow-list or LAN/localhost flag off |
|
NO_CONTROLLED_TAB |
No tab opened/adopted yet | Run openTab first, or adoptTab an existing tab (see examples). |
| Security banner not visible | Content script not injected | Check scheme (https:// required), host permission, and CSP/iframe constraints. |
| Dev server is HTTP only | No HTTPS on localhost | Use HTTPS/dev certs or a tunnel; many dev stacks offer an HTTPS option. |
| Selectors fail on SPA | Elements render late | Use waits or retry; prefer stable id / data-* selectors. |
7) FAQ
Is LAN/localhost safe? Yes. They’re disabled by default and require both flags and allow-list entries.
Do I need a server or proxy? No. Everything runs locally in the browser.
Can I target IP ranges? You can allow specific IPs (e.g., https://10.0.1.23). Hostname wildcards work on names, not raw IP ranges.
Does this bypass SOP? No. Actions execute inside the page via content scripts on authorized hosts.
Next Pages
| Page | Description |
|---|---|
| Start | Overview, how it works, setup, quick start, and links to all sections. |
| Detect the Extension | Detection contract (ping/pong), install prompts, and graceful fallbacks when the extension isn’t present. |
| Allow-list & Permissions | Deny-by-default model, domain allow-list via popup, and suggested UX to guide users to enable hosts. |
| LAN / Localhost | How to safely enable intranet/localhost (flags + allow-list). |
| Remote Tab Control | Open/navigate/focus the controlled tab, read URL/title, select an existing tab, lifecycle & restore patterns. |
| DOM & Automation | Action catalog (type, setValue, click, select, submit, waitFor) and safe interaction tips. |
| Recipes & Flows | Copy-paste flows: resilient login, dashboard checks, table waits, filters, playlists, and allow-list banners. |
| Events | Event stream reference, subscription helpers, live logger widget, and basic metrics/durations collection. |
| Diagnostics | Inline console, error cookbook, QA self-check, and performance tips for troubleshooting flows quickly. |
| Full API Reference | Canonical message envelopes, request/response schemas, error codes, and return shapes for every action. |
| Compatibility | Supported browsers/versions, permissions nuances, CSP/iframe notes, and known limitations or workarounds. |
| Advanced Patterns | Idempotent flows, retries/backoff, state restore after reload, playlist strategies, and robust selectors. |
| Favorites | Star and group URLs, quick actions (open/focus/navigate), export/import sets, and playlist runs from favorites. |
| Real-World Flows (E2E) | Run end-to-end flows from your admin page: helper setup, modern message contract, copy-paste journeys (login, multi-tab, extract), lightweight assertions, best practices, and troubleshooting. |