Verifying server authenticity on local setup #20

Open
opened 2026-02-24 12:36:02 +00:00 by Skipper · 5 comments
Owner

We have found design fault in specification: server can't be trusted when unsealing.

sequenceDiagram
    actor User
    participant UA as User Agent
    participant FS as Fake Server
    participant S as Server
    FS-->>S: Steal TLS Key
    destroy S
    FS-->>S: Intercept Socket creation
    critical Identity check pass
        UA->>FS: Connects
    end
    FS->>UA: Report "Sealed" state
    User->>UA: Entry password
    UA->>FS: Password sent with x25519 <br> key negotiation
    Note over UA, FS: User key is stolen now

This attack vector is applicable only on local-setup: when daemon and user agent are co-located on same host.

Possible solutions

It's much harder to solve because we have to support multiple platforms:

  • On MacOS it might be the easiest and securest to solve: they provide API's that grant access to keys only to specific program signatures. There is also a way to attest program running behind IPC. Moreover: they have hardened runtime option that forbids code injection. Damn Apple...
  • Windows is less lucky one, there is no option to gate keys behind signature (sadly :( ). There is also increased risk of code injection. We would probably need to implement our own attestation process, when User Agent remotely reads memory to calculate checksum for signature. Not sure how would this interact with out memory protection...
  • Linux is the worst one to solve: as there is no Central Authority embedded into hardware (except TPM), there is no way to rely on some company's signature.

The TPM is not a solution, because it protects only from key extraction. A malicious process could still request signing by that particular key.

We have found design fault in specification: server can't be trusted when unsealing. ```mermaid sequenceDiagram actor User participant UA as User Agent participant FS as Fake Server participant S as Server FS-->>S: Steal TLS Key destroy S FS-->>S: Intercept Socket creation critical Identity check pass UA->>FS: Connects end FS->>UA: Report "Sealed" state User->>UA: Entry password UA->>FS: Password sent with x25519 <br> key negotiation Note over UA, FS: User key is stolen now ``` This attack vector is applicable only on local-setup: when daemon and user agent are co-located on same host. ## Possible solutions It's much harder to solve because we have to support multiple platforms: - On MacOS it might be the easiest and securest to solve: they provide API's that grant access to keys only to specific program signatures. There is also a way to attest program running behind IPC. Moreover: they have hardened runtime option that forbids code injection. Damn Apple... - Windows is less lucky one, there is no option to gate keys behind signature (sadly :( ). There is also increased risk of code injection. We would probably need to implement our own attestation process, when User Agent remotely reads memory to calculate checksum for signature. Not sure how would this interact with out memory protection... - Linux is the worst one to solve: as there is no Central Authority embedded into hardware (except TPM), there is no way to rely on some company's signature. The TPM is not a solution, because it protects only from key extraction. A malicious process could still request signing by that particular key.
Member

This funny diagram shows how the OPAQUE protocol closes the vulnerability with server spoofing by intercepting the TLS key or intercepting the socket. But this solution requires that at the time of the handshake, both the client and the server have the corresponding parts of the cryptographic key.

sequenceDiagram
    actor User
    participant UA as User Agent (Verif Key)
    participant FS as Fake Server
    participant S as Server (Sign Key)
    FS-->>S: Steal TLS Key
    FS-->>S: Intercept Socket
    UA->>FS: Connects (Identity check)
    Note over UA, FS: OPAQUE Handshake Starts
    UA->>FS: OPAQUE Login Step 1 (Nonce sent)
    FS-->>UA: OPAQUE Step 2 (Bad signed nonce)
    Note over UA: OPAQUE Handshake FAILS via invalid signer
    UA-->>User: Error: Server Authentication Failed
    Note right of FS: Attacker got nothing
This funny diagram shows how the OPAQUE protocol closes the vulnerability with server spoofing by intercepting the TLS key or intercepting the socket. But this solution requires that at the time of the handshake, both the client and the server have the corresponding parts of the cryptographic key. ```mermaid sequenceDiagram actor User participant UA as User Agent (Verif Key) participant FS as Fake Server participant S as Server (Sign Key) FS-->>S: Steal TLS Key FS-->>S: Intercept Socket UA->>FS: Connects (Identity check) Note over UA, FS: OPAQUE Handshake Starts UA->>FS: OPAQUE Login Step 1 (Nonce sent) FS-->>UA: OPAQUE Step 2 (Bad signed nonce) Note over UA: OPAQUE Handshake FAILS via invalid signer UA-->>User: Error: Server Authentication Failed Note right of FS: Attacker got nothing ```
Author
Owner

how does server store sign key for opaque in such way, so that server can access it, but fake server is not?

how does server store sign key for opaque in such way, so that server can access it, but fake server is not?
Author
Owner
@CleverWild ping
Member

When the server starts, it identifies itself to the Windows CNG (Cryptography Next Generation) API.
It set a PCP_PLATFORM_BINDING_PCR policy.
And finally, the Magic: Windows checks the Code Integrity (CI). If the fake_server.exe has a different hash or is unsigned, the TPM refuses to perform the signature.
Virtualization-Based Security (VBS) enclave does brrrrt.

When the server starts, it identifies itself to the Windows CNG (Cryptography Next Generation) API. It set a PCP_PLATFORM_BINDING_PCR policy. And finally, the Magic: Windows checks the Code Integrity (CI). If the fake_server.exe has a different hash or is unsigned, the TPM refuses to perform the signature. Virtualization-Based Security (VBS) enclave does brrrrt.
Author
Owner
image.png
<img width="1091" alt="image.png" src="attachments/d313fc60-7479-4ed0-8316-a08fddf06707">
147 KiB
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: MarketTakers/arbiter#20