Skip to content

Conversation

@TrueCarry
Copy link
Contributor

@TrueCarry TrueCarry commented Aug 11, 2025

Proposal: Enhancing End-User Security in TonConnect with origin information

1. Summary

We are introducing a verification step in TonConnect that allows wallets to confirm the true source of both connection and transaction requests, and allows users to further assess the legitimacy of the transaction by following best practices from other fields (e.g., Google, Apple, Telegram).
Just like these platforms, wallets will be able to show users where the request came from and what device or environment initiated it, giving them clear context before approving.
This protects users from phishing and impersonation attacks while requiring no changes from dApps and keeping backward compatibility.


2. Problem

Today, wallets have no reliable way to know if a request truly comes from the dApp the user sees. Attackers can impersonate legitimate dApps, send requests through their backend, and trick users into connecting or signing malicious transactions.


3. Solution

We will have the TonConnect bridge capture the origin, User-Agent and IP address for each connection and message request.

  • Connects: Wallets will call a verification endpoint to confirm the request matches the expected source.
  • Messages: The bridge will send encrypted metadata to the wallet so it can check everything locally.

4. Benefits

  • User Safety: Detects phishing and impersonation attacks early.
  • Transparency: Users are explicitly alerted to environmental mismatches.
  • Backward Compatibility: dApps require no changes. Non-updated wallets still function normally.
  • Trust Signals: Verified mark for trusted dApps when ok result comes from a whitelisted domain.

5. Wallet Implementation Effort Estimate

Task Time Estimate
Implement /verify for connects 1–2 days
Encrypted metadata decryption & local checks 1–2 days
UI for warnings & verification marks 1–2 days
QA & Security Review 1–2 days
Total (approx.): 4–8 developer-days

6. Technical Details

6.1 Connect Verification

  • The TonConnect bridge stores:

    • Origin (protocol + domain)
    • IP address
    • Client ID
  • Wallet sends:

    POST ${TonConnectBridgeUrl}/verify

    {
      "type": "connect",
      "client_id": "<id>",
      "origin": "<protocol+domain>"
    }
  • Statuses returned:

    • Phase 1 (first 6 months): ok, unknown
    • Phase 2 (after 6 months): ok, danger, warning
  • If status is ok and the domain is on the whitelist → wallet shows verification mark.

6.2 Transaction Verification

When the bridge receives a message, it collects the request source data into the following struct:

type BridgeRequestSource struct {
    Origin    string `json:"origin"`
    IP        string `json:"ip"`
    Time      string `json:"time"`
    UserAgent string `json:"user_agent"`
}

Process:

  1. Serialize the BridgeRequestSource struct to JSON.
  2. Encrypt it using the recipient wallet’s Curve25519 public key (to field in message) with:
    box.SealAnonymous(nil, data, receiverSessionPublicKey, rand.Reader)
  3. Base64 encode the encrypted bytes.
  4. Attach it to the outgoing bridge message as:
    BridgeRequestSource string `json:"request_source"`

Wallet handling:

  1. Base64-decode the request_source.
  2. Decrypt it using the wallet’s private key.
  3. Parse the BridgeRequestSource JSON.
  4. Compare origin, IP, and user-agent to stored connection details.
  5. Display warnings if mismatches are found.

6.3 Rollout Plan

Phase 1 – First 6 months

  • /verify for connects: only ok and unknown.
  • Transactions: verified locally using encrypted BridgeRequestSource.
  • ok + whitelisted domain → verification mark shown.

Phase 2 – Following 6 months

  • /verify for connects: ok, danger, warning.
  • Full warnings displayed for connect mismatches.

6.4 Wallet Integration Process Standard

Connection Verification

  1. Bridge logs: client_id, origin, IP.
  2. Wallet sends POST /verify with type connect.
  3. Bridge returns status according to rollout phase.
  4. Wallet shows:
    • ok + whitelisted → verification mark.
    • danger → strong warning.
    • warning → caution.
    • unknown → no message.

Transaction Verification

  1. Bridge includes request_source (base64-encoded encrypted BridgeRequestSource) in the message payload.
  2. Wallet decrypts and parses the struct.
  3. Wallet obtains current IP address using bridge's POST /myip (can be cached) endpoint for comparison
  4. Compares metadata to stored connection info.
  5. Shows warnings if mismatches are found.

6.5 Sample Wallet Messages

  • Danger:

    ⚠️ This request could not be verified and may be fraudulent. Do not proceed unless you are certain of the source.

  • Warning:

    ⚠️ This request’s details differ from your current connection. This could be due to a network change or other unusual event. Proceed with caution.

  • Verification Mark (ok + whitelisted):

    ✅ Verified dApp — confirmed request from a trusted source.


**Response statuses:**

- **Phase 1** (first 6 months): `ok`, `unknown`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s not obvious to a future reader whether we’re in Phase 1 or Phase 2 right now. Could we add something to make the current phase clear? Add dates?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can only add dates after we start the rollout.


3) **Rollout Phase Awareness**

- **Phase 1 (first 6 months)**: Only `ok` and `unknown` statuses returned
Copy link

@callmedenchick callmedenchick Aug 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the one hand, this should be obvious, but still — why do we need to split the rollout into two phases? Why can’t we just show the statuses right away?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we need time to update sdk on the dapps side, otherwise we don't have guarantees that client connects to the bridge before opening wallet.

- `ok` + whitelisted domain → show verification mark ✅
- `danger` → display strong warning, recommend declining
- `warning` → display caution message
- `unknown` → proceed without special indicators

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if /verify endpoint is not available or wallet gets an error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be treated as danger

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants