Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve MITM detection during session establishment: #4395

Closed
wants to merge 2 commits into from
Closed

Improve MITM detection during session establishment: #4395

wants to merge 2 commits into from

Conversation

nbougalis
Copy link
Contributor

@nbougalis nbougalis commented Jan 23, 2023

Even with TLS encrypted connections, it is possible for a determined attacker to mount certain types of relatively easy man-in-the-middle attacks which, if successful, could allow an attacker to tamper with messages exchanged between endpoints.

The risk can be mitigated if each side has a certificate issued by a CA that the other side trusts. In the context of a decentralized and permissionless network, this is neither reasonable nor desirable.

To prevent this problem all we need is to allow the two endpoints, A and B, to be able to independently verify that they are connected to each other over a single end-to-end TLS session, instead of separate TLS sessions with the attacker bridges.

The protocol level handshake implements this security check by using digital signatures: each endpoint derives a fingerprint from the TLS session, which it signs with the private key associated with its own node identity. This strongly binds the TLS session to the identities of the two endpoints of the session.

This commit introduces a new fingerprint derivation that uses modern and standardized TLS exporter functionality, instead of the existing derivation whch uses OpenSSL APIs that are non-standard.

The change is backwards compatible and servers with this commit will still generate and verify old-style fingerprints, in addition to the new style fingerprints.

For a fuller discussion on this topic, please see:
openssl/openssl#5509
#2413

This commit was previously introduced as #3929, which was closed. If merged, it also fixes #2413 (which had been closed as a 'WONTFIX').

High Level Overview of Change

Context of Change

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (non-breaking change that only restructures code)
  • Tests (You added tests for code that already exists, or your new feature included in this PR)
  • Documentation Updates
  • Release

Test Plan

Running this against servers with and without this change and verifying that peer connections are established (e.g. by using the peers command) should be sufficient. Ideally, in addition to Linux, this should also be tested against servers running on the "compiles-on-but-it's-not supported" platforms: MacOS and Windows.

Copy link
Collaborator

@gregtatcam gregtatcam left a comment

Choose a reason for hiding this comment

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

👍 LGTM

@intelliot intelliot added Request for Comments Feature Request Used to indicate requests to add new features Tech Debt Non-urgent improvements Needs Review Testable labels Feb 3, 2023
@intelliot
Copy link
Collaborator

Testable: See Test Plan in the PR description.

@intelliot intelliot changed the base branch from develop to next February 24, 2023 20:35
@intelliot intelliot changed the base branch from next to develop February 24, 2023 20:35
@seelabs seelabs self-assigned this Feb 24, 2023
Even with TLS encrypted connections, it is possible for a determined
attacker to mount certain types of relatively easy man-in-the-middle
attacks which, if successful, could allow an attacker to tamper with
messages exchanged between endpoints.

The risk can be mitigated if each side has a certificate issued by a
CA that the other side trusts. In the context of a decentralized and
permissionless network, this is neither reasonable nor desirable.

To prevent this problem all we need is to allow the two endpoints, A
and B, to be able to independently verify that they are connected to
each other over a single end-to-end TLS session, instead of separate
TLS sessions with the attacker bridges.

The protocol level handshake implements this security check by using
digital signatures: each endpoint derives a fingerprint from the TLS
session, which it signs with the private key associated with its own
node identity. This strongly binds the TLS session to the identities
of the two endpoints of the session.

This commit introduces a new fingerprint derivation that uses modern
and standardized TLS exporter functionality, instead of the existing
derivation whch uses OpenSSL APIs that are non-standard, and derives
different "incoming" and "outgoing" security cookies.

Lastly, this commit refines the "self-connection" check to allow for
the detection of accidental instances of node identity sharing. This
check was first introduced with #4195 but was partially reverted due
to a bug with #4438. By using distinct security cookies for incoming
and outgoing connections, an attacker is no longer able to claim the
identity of its peer by echoing its security cookie.

The change is backwards compatible and servers with this commit will
still generate and verify old-style fingerprints, in addition to the
new style fingerprints.

For a fuller discussion on this topic, please see:
    openssl/openssl#5509
    #2413

This commit was previously introduced as #3929, which was closed. If
merged, it also fixes #2413 (which had been closed as a 'WONTFIX').
@nbougalis
Copy link
Contributor Author

Updated this branch to introduce directional cookies and to strongly bind the Instance-Cookie. It's ready for a review and, if approved, merging.

@nbougalis nbougalis mentioned this pull request May 4, 2023
Copy link
Collaborator

@ximinez ximinez left a comment

Choose a reason for hiding this comment

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

Couple of simple fix suggestions.

Comment on lines +284 to +285
It is used to secure the peer link against certain types of attack. For more
details see the section titled "Session Signature" below.
Copy link
Collaborator

Choose a reason for hiding this comment

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

There is no section titled "Session Signature" anymore. Should probably be "Session Security".


{
auto const sig = signDigest(
app.nodeIdentity().first, app.nodeIdentity().second, sharedValue);
h.insert("Session-Signature", base64_encode(sig.data(), sig.size()));
}

h.insert("FOO", to_string(ekm));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Did you mean to include the raw ekm?

Copy link
Collaborator

Choose a reason for hiding this comment

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

This looks like some temporary/debug code that survived into the final build.

Copy link
Collaborator

Choose a reason for hiding this comment

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

That was my assumption, too. But it does need to be removed.


This value is generated in a secure fashion and is never communicated over
the wire, even over an encrypted connection. Used properly, it can help to
detect and prevent preventing active MITM attacks.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Typo: prevent preventing -> prevent

@JoelKatz
Copy link
Collaborator

LGTM. There's the reference to a renamed section by the old section name and the line of debug code that got left in, but other than that, no issues except:

This code currently violates RFC 5705:

Label values beginning with "EXPERIMENTAL" MAY be used for private use without registration. All other label values MUST be registered via Specification Required as described by RFC 5226

We can register our two labels, use experimental labels, or use existing registered labels whose uses do not conflict with ours.

@intelliot
Copy link
Collaborator

@nbougalis at your convenience, please respond to the suggestions by ximinez

@intelliot intelliot added this to the refactors milestone Jul 19, 2023
@nbougalis nbougalis closed this Oct 16, 2023
@nbougalis nbougalis deleted the antimitm branch October 16, 2023 06:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature Request Used to indicate requests to add new features Request for Comments Tech Debt Non-urgent improvements Testable
Projects
Status: 📋 Backlog
Development

Successfully merging this pull request may close these issues.

peer handshake violates TLS transparency
6 participants