TAGII ยท Upload Mesh
A threat model that lists only strengths is an advertisement. This page lists the attacks this design answers, with the test in the repository that proves each refusal; the attacks it does not defend against, stated as such; and what is known and still open. It is written from the same register as the product page, and the repository's own check refuses a row whose test does not exist.
What this page is not. No security review has run against this code. A test that a specific refusal holds is not a finding that no other path exists. Read every row as "this exact thing was tried and refused", and nothing wider.
| What an attacker tries | What happens | The test, and the file it is in |
|---|---|---|
| A device on your network claims to be one of yours, from the same address. | Each device pinned the other's exact certificate when they paired. A different identity is refused on the transfer path, whatever address it comes from, and a device that swapped its program keeps the identity its peers pinned. | TestTailnetListen (go/internal/meshcore/tailnet_test.go), TestInstallSwapsByRenameAndKeepsIdentity (go/internal/meshcore/install_test.go) |
| A device on your network pairs itself with yours without you. | Pairing needs a window you opened on the device being joined. With no window open it is refused; a window admits one device and expires; a caller that has not authenticated is refused; and a name already paired cannot be rebound by a newcomer. | TestPairingWindowIsOneUseAndExpires (go/internal/meshcore/pairauth_test.go), TestPairRefusesUnauthenticatedCaller (go/internal/meshcore/pairauth_test.go), TestPairRefusesToRebindAName (go/internal/meshcore/pairauth_test.go) |
| The pairing handshake hands a peer the device's permanent token. | A pairing returns a grant for that one peer, never the device's own token, so no peer can act as the device. | TestPairReturnsAPerPeerGrantNotTheDeviceToken (go/internal/meshcore/pairauth_test.go) |
| A device you removed keeps using the credential it had. | Its next request is refused on the wire and the refusal says revoked, on every route. A credential that was rotated is refused as expired, not as unknown, so a failure is never mistaken for a typo. | TestRevokedPeerIsRefusedOnTheWire (go/internal/meshcore/revoke_test.go), TestRotatedPeerOldGrantIsExpiredNotUnknown (go/internal/meshcore/revoke_test.go), TestUnpairPositiveAndUnknownNegative (go/internal/streamhost/streamhost_test.go) |
| A stranger on the network asks a device who it is. | The unauthenticated ping hides the permanent fingerprint, and the diagnostic probe of a port refuses a stranger rather than describing it. | TestPingHidesThePermanentFingerprintFromStrangers (go/internal/meshcore/authpeer_test.go), TestDoctorRefusesAStrangerOnThePort (go/internal/meshcore/doctor_test.go) |
| A request reaches outside a shared folder, with a path that climbs out or a link that points out. | Refused before anything is read or written, on both routes, the same way. A device that has not paired gets nothing, and cannot write. | TestFilesEscapeRefused (go/internal/meshcore/files_test.go), TestFilesUnpairedRefused (go/internal/meshcore/files_test.go), TestWriteRoutesRefuseUnpaired (go/internal/meshcore/filesrw_test.go) |
| Something reaches the node's port from the ordinary network. | The node binds the loopback address and the private network address only, on a computer and on a phone; every wildcard spelling is refused outright, and a dial to the machine's ordinary address is refused by the bind rule, not by a firewall. | TestBindRefusesLAN (go/internal/meshcore/bind_test.go), TestBindSetNeverWildcard (go/internal/meshcore/bind_test.go), TestPhoneNeverBindsTheWildcard (go/internal/meshphone/bind_test.go), TestLanBindSetRefusesAWildcard (go/internal/meshphone/bind_test.go) |
| A device outside your set asks for a picture of the screen. | No content is served to a device with no token or the wrong one, and a view that is paused serves nothing to anyone. | TestViewFramePairedAndUnpaired (go/internal/meshcore/view_test.go), TestViewPauseStopsFrames (go/internal/meshcore/view_test.go), TestStreamOfferEndpointGuards (go/internal/meshcore/stream_test.go) |
| A forged, tampered, replayed or too-young update. | Wrong signature, wrong size, wrong hash, no build for the platform, published too recently, a replayed sequence, or a manifest with a field the verifier cannot check: each refused whole, with the program on disk unchanged. | TestUpdateRefusals (go/internal/meshcore/update_test.go), TestParseEnvelopeStrict (go/internal/meshrelease/meshrelease_test.go), TestVerifyPositiveAndNegatives (go/internal/meshrelease/meshrelease_test.go) |
| A stolen or replayed approval, or one aimed at a different device than asked. | An approval is bound to the device that asked, is single use, and expires; a request from an unpaired or unnamed device is refused; no answer is a no. | TestDecideApprovalBindsToAddressedDeviceNotABodyName (go/internal/meshcore/approval_test.go), TestDecideApprovalIsSingleUse (go/internal/meshcore/approval_test.go), TestDecideApprovalExpires (go/internal/meshcore/approval_test.go), TestRequestApprovalRefusesAnUnpairedOrUnnamedDevice (go/internal/meshcore/approval_test.go) |
| A password or key copied by accident travels to another device, or a credential lands in a diagnostics bundle or on disk in clear. | Text that looks like a secret is withheld and the withholding is logged. The diagnostics bundle is built from a fixed list of fields and carries no credential. The credential a paired device holds is never written to disk in clear. | TestClipWatcherSecretFilter (go/internal/meshcore/watch_test.go), TestDiagBundleCarriesNoSecrets (go/internal/meshcore/settingsapi_test.go), TestPairedTokenNeverWrittenAsCleartext (go/internal/meshcore/tokenseal_test.go) |
| A remote control window is used while the screen is locked, by a device not on its list, or left open. | Refused while the session is locked unless the owner said otherwise when opening it; only the peers on its list are admitted; it expires on its own; and off is the panic key. | TestControlLockGuard (go/internal/meshcore/input_test.go), TestControlPeerAllowlist (go/internal/meshcore/input_test.go), TestControlDeadManTimeout (go/internal/meshcore/input_test.go), TestControlOffIsThePanicKey (go/internal/meshcore/input_test.go) |
| A ring is used to seize a device's volume. | The ring plays at the volume the owner already chose and never touches the mixer. There is a Stop on the device making the noise, and a hard time limit. | TestRingNeverTouchesTheMixer (go/internal/meshcore/ringsafety_test.go), TestStopRingNowActuallyStopsIt (go/internal/meshcore/ringsafety_test.go), TestRingTimeLimitIsShortAndLogged (go/internal/meshcore/ringsafety_test.go) |
| A device on the network announces itself as a KDE Connect peer to get trusted. | It becomes visible and nothing more: no dial back, no pairing, no trust record, however many broadcasts arrive. The listener is off by default. | TestKDEDiscoveryNeverTouchesTheTrustStore (go/internal/meshcore/kdeconnect_discovery_test.go), TestKDEDiscoveryOffByDefault (go/internal/meshcore/kdeconnect_discovery_test.go) |
| Two first starts race and a device ends up serving an identity nobody pinned. | One creator is chosen by a lock, the key is written before the certificate, and the losers wait for a complete pair. | TestCertCreateRace (go/cmd/tagii-mesh/certrace_test.go) |
| A wake is reported because a packet was sent. | A wake is claimed only on an answer from the device. A packet leaving a socket is reported as exactly that. | TestWakeLayersAndMACAtPairing (go/cmd/tagii-mesh/wake_test.go) |
| A file is pushed at your phone without asking. | An incoming file is a question. Nothing is taken until the person taps Accept, Decline takes nothing and the sender is told, and silence expires into a no. | TestAnOfferWaitsForThePersonAndAcceptPullsIt (go/internal/meshphone/offers_test.go), TestAnUnansweredOfferExpiresIntoADecline (go/internal/meshphone/offers_test.go), TestDeclineTakesNothingAndTheSenderKnows (go/internal/meshphone/offers_test.go) |
| The case | What that means | Where it is written |
|---|---|---|
| Somebody already running programs as you on one of your machines. | They can read what you can read, including clipboard items waiting on disk. Nothing in this product is a defence against that and nothing here should be read as if it were. | docs/uploadmesh/21-threat-model.md |
| Somebody watching how much traffic goes where. | A relay in the path sees that two of your devices talk, when, and how much. It cannot see what. Traffic analysis is made harder, never solved. | docs/uploadmesh/19-what-we-can-see.md |
| A phone that is already compromised. | No server design saves it. A protected server raises the cost of an attack on the host and does not make one impossible. | docs/uploadmesh/21-threat-model.md |
| The item | Where it stands | Where it is written |
|---|---|---|
| A third party's relay is in the path today whenever two devices cannot connect directly. | It sees encrypted traffic only. The self hosted relay is written and its configuration validated, and nothing has been applied. | docs/uploadmesh/19-what-we-can-see.md |
| A delivered clipboard item sits unencrypted on disk until it is cleared. | Real, on the receiving device, readable by anything running as you there. Being worked on. | docs/uploadmesh/19-what-we-can-see.md |
| The update manifest carries one signature, and the release signing key is not yet wired into a signed build. | The verifier refuses a manifest that claims a second signature rather than half-checking it. A signed release, published digests and a transparency log are planned and not done. | scripts/upload-mesh/release-build.sh |
| No security review has run against this code, and the current build has not been run between two real machines. | The page claims specific refusals that specific tests demonstrate, and nothing wider. | docs/uploadmesh/21-threat-model.md |
go test ./internal/meshcore -run TestBindRefusesLAN
runs one; the test's own header says what its paired negative is.