Security
This application runs elevated and modifies machine-wide network state. That deserves scrutiny, so this page sets out exactly what privileges it takes, what it protects against, what it explicitly does not, and how to report a problem.
Privileges, and why each is needed
The application requests administrator rights once at launch rather than prompting repeatedly. Here is everything that privilege is used for — there is nothing else.
| Operation | Why | Reversed by |
|---|---|---|
| Register WFP filters | Holding an application on its assigned adapter by blocking it on the others | Deleted on exit; Windows discards them if the process is killed |
| Set an adapter’s interface metric | Deprioritising a whole adapter (“isolate”) | Original value journalled first, restored on exit or on next launch |
| Read adapter configuration and counters | Listing adapters, judging routability, throughput figures | Read-only; nothing to reverse |
| Read the running process list | Letting you pick a running application, and finding its PIDs | Read-only; nothing to reverse |
| Subscribe to WMI process events | Keeping the process list current without polling | Subscription dropped on exit |
| Read the uninstall registry key | Listing installed applications, and reading the install date | Read-only; nothing to reverse |
| Create a scheduled task | “Start with Windows”, elevated and without a UAC prompt | Removed when you turn the setting off |
There is no monitoring-only mode. Elevation is required, not optional: without it the application says so and closes, rather than opening a window whose controls would all fail. On a machine where you are not permitted to elevate, it cannot do its job.
Threat model
What the design actively protects against, and how.
Leaving the machine in a broken state
The most likely real harm from a routing tool is not an attacker — it is a bug that leaves the forwarding table wrong and the machine off the network. The forwarding table is serialised before the first modification of a session, restored on clean exit, reconciled after adapter changes, and recovered on next launch if the process died. The uninstaller runs the same restore. Every rule is validated against a live adapter before it is applied, and application is transactional: a profile either applies entirely or not at all.
Tampering with licence state
Licence keys are signature-verified against an embedded public key before use, so a modified key cannot elevate a tier and a forged one does not verify at all. When a licence server is configured the app re-validates periodically — daily by default — and keeps working through a bounded offline grace window, so a lost connection does not lock you out mid-session. With no server configured it relies on the local signature check alone.
Disclosure through local artefacts
The log directory records which applications you route and over which adapters, which describes your setup to anyone who can read your user profile. The diagnostics summary is produced only when you press the button, is plain text on your clipboard, and can be read and edited before you send it anywhere.
Unintended traffic exposure after a failure
When an assigned adapter goes down, the filters holding an application to it stay in place, so that application loses connectivity rather than falling back to another line. That is the intended behaviour and it is what a leak-conscious setup wants — but it is a consequence of blocking, not a configurable kill switch, and it applies to every rule. The app raises a notification naming the adapter, because otherwise the only symptom is an application that cannot connect.
What it does not defend against
Stated plainly, because a tool that implies protection it does not provide is worse than one that provides none.
This is traffic management, not a containment boundary
Filters act on the process that owns the socket. Software that gets a different process to do its networking — a shared host service, an injected thread — is attributed to that process, and a rule naming the original will not match. If your requirement is enforcement against hostile code rather than organisation of cooperative code, you need firewall policy and network segmentation, not this.
- A local administrator. Anyone with administrator rights on the machine can stop the service, change rules, or read the database. Routing is machine-wide state and there is no per-user policy model in 1.0.
- Content confidentiality. No encryption is added to your traffic. Routing changes which interface a connection leaves through, nothing else. If you need confidentiality, that is a VPN's job, and a VPN adapter works fine as a routing target.
- Malicious profile files. An imported profile is configuration, and importing one you did not write means accepting its routing decisions. Import validates schema and structure but cannot know whether a rule is one you wanted. Review the JSON — it is designed to be readable for this reason.
- Upstream network attacks. On-path interception, DNS spoofing by a hostile resolver, or a compromised ISP are all outside what a host-side routing tool can address. This application does not configure DNS at all — each adapter keeps whatever resolver Windows gave it.
Code signing and supply chain
- The MSI and every executable inside it are Authenticode-signed. Verify with
Get-AuthenticodeSignaturebefore installing. - A SHA-256 checksum for the installer is published on the download page.
- Dependencies are pinned to exact versions and restored from the official NuGet feed. The dependency list is short and deliberately conservative; every entry appears in the third-party notices.
- The version is stamped into the binary at build time — check it in file properties, or in Licence & about inside the application.
SmartScreen may warn on a fresh release because reputation accrues per signed build. The correct check is the signature status and signer identity, not the absence of a warning.
Data at rest
Everything the application stores is local. Nothing is transmitted except the requests you configure, which are enumerated in the privacy policy.
| Artefact | Contents | Access |
|---|---|---|
| SQLite database | Profiles and rules | Your user profile, under %LocalAppData%\DualInternet |
| settings.json | Your preferences | Your user profile; written atomically |
| Isolation journal | Original interface metric of any adapter still isolated | Your user profile; needed to restore an adapter |
| Log files | Routing and isolation operations, with the rule that caused them | Your user profile; rolling, capped in size and count |
| Licence state | Activation record and trial anchors, machine-bound with AES-GCM | Your profile and %ProgramData%; useless if copied elsewhere |
| Diagnostics summary | Whatever you copied, wherever you pasted it | Yours to control |
Resolved hostnames from destination rules appear in the database and, if enabled, the audit log. Setting history retention to zero and leaving audit logging off minimises what exists on disk.
Hardening guidance
For managed or sensitive environments:
- Verify the signature before deploying.
Get-AuthenticodeSignatureon the MSI, and check the signer is Fable Labs rather than relying on the absence of a SmartScreen warning. - Leave “Clear rules on exit” on. It is the default. Turning it off means enforcement outlives the process that can explain it.
- Leave confirmation prompts on so a mistaken click cannot clear every rule on a machine you are relying on.
- Decide about “Re-apply rules on launch” deliberately. It changes how the machine routes traffic before anyone has looked at it, which is why it is off by default.
- Treat imported profiles as untrusted input. A profile file decides which applications use which line; read the JSON before importing one you did not write.
- Collect the log directory if you need a record. Every routing and isolation operation is written there with the rule that caused it.
- Test the failure case deliberately. Disable an assigned adapter and confirm the applications you expect to lose connectivity actually do — there is no failover, and you should see that for yourself before depending on it.
Coordinated disclosure policy
Please report privately first. Email security@fablelabs.in with enough detail to reproduce — a proof of concept, affected version, and the impact you believe it has.
What you can expect
| Stage | Target |
|---|---|
| Acknowledgement of receipt | 2 business days |
| Initial assessment and severity | 5 business days |
| Fix for a critical issue | Target 14 days, sooner where practical |
| Fix for a lower-severity issue | Next scheduled release |
| Public disclosure | Coordinated with you, after a fix ships |
Scope
In scope: the desktop application, the installer, the licence verification path, the licence server, and this website.
Out of scope: anything requiring administrator rights the reporter already has (an administrator changing routing is the product working as designed); social engineering; denial of service against your own machine; findings in third-party dependencies that should go to that project first; and reports that amount to "the application needs elevation", which is documented above.
Recognition
There is no paid bounty programme — this is a one-person product and pretending otherwise would be dishonest. Valid reports get credit in the changelog if you want it, a direct line for future reports, and a complimentary Pro licence.
Good-faith research will not be pursued
Testing against your own installation, staying within the scope above, and reporting privately before disclosing — no legal action, no complaints to your employer. If you are unsure whether something is in scope, ask first and you will get a straight answer.