diff --git a/sei-tendermint/light/verifier.go b/sei-tendermint/light/verifier.go index 59431251ac..407032e221 100644 --- a/sei-tendermint/light/verifier.go +++ b/sei-tendermint/light/verifier.go @@ -53,9 +53,9 @@ func VerifyNonAdjacent( return err } - // check if the untrusted header is within the trust period - if HeaderExpired(untrustedHeader, trustingPeriod, now) { - return ErrOldHeaderExpired{untrustedHeader.Time.Add(trustingPeriod), now} + // check if the trusted header has expired past the trusting period + if HeaderExpired(trustedHeader, trustingPeriod, now) { + return ErrOldHeaderExpired{trustedHeader.Time.Add(trustingPeriod), now} } if err := verifyNewHeaderAndVals( @@ -124,9 +124,9 @@ func VerifyAdjacent( return errors.New("headers must be adjacent in height") } - // check if the untrusted header is within the trust period - if HeaderExpired(untrustedHeader, trustingPeriod, now) { - return ErrOldHeaderExpired{untrustedHeader.Time.Add(trustingPeriod), now} + // check if the trusted header has expired past the trusting period + if HeaderExpired(trustedHeader, trustingPeriod, now) { + return ErrOldHeaderExpired{trustedHeader.Time.Add(trustingPeriod), now} } if err := verifyNewHeaderAndVals( diff --git a/sei-tendermint/light/verifier_test.go b/sei-tendermint/light/verifier_test.go index 6587364d7c..cbeb6cbdd5 100644 --- a/sei-tendermint/light/verifier_test.go +++ b/sei-tendermint/light/verifier_test.go @@ -150,6 +150,18 @@ func TestVerifyAdjacentHeaders(t *testing.T) { nil, "old header has expired", }, + // trusted header expired but untrusted header is fresh -> error + // (regression: trusting period must be checked against the trusted header, + // not the untrusted header; an attacker can always supply a fresh untrusted header) + 11: { + keys.GenSignedHeader(t, chainID, nextHeight, bTime.Add(1*time.Hour), nil, vals, vals, + hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys)), + vals, + 1 * time.Hour, + bTime.Add(1*time.Hour + 30*time.Minute), + nil, + "old header has expired", + }, } for i, tc := range testCases { @@ -263,6 +275,18 @@ func TestVerifyNonAdjacentHeaders(t *testing.T) { light.ErrNewValSetCantBeTrusted{types.ErrNotEnoughVotingPowerSigned{Got: 20, Needed: 46}}, "", }, + // trusted header expired but untrusted header is fresh -> error + // (regression: trusting period must be checked against the trusted header, + // not the untrusted header; an attacker can always supply a fresh untrusted header) + 6: { + keys.GenSignedHeader(t, chainID, 3, bTime.Add(1*time.Hour), nil, vals, vals, + hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys)), + vals, + 1 * time.Hour, + bTime.Add(1*time.Hour + 30*time.Minute), + nil, + "old header has expired", + }, } for i, tc := range testCases {