From 28d7316c6e1f6a878a2c4c6aea8cd5c81da016bd Mon Sep 17 00:00:00 2001 From: Shulhan Date: Sun, 5 Nov 2023 23:57:22 +0700 Subject: [PATCH] email/dkim: set ExpiredAtto MaxInt64 if value is greater than 12 digits According to RFC 6376, To avoid denial-of-service attacks, implementations MAY consider any value longer than 12 digits to be infinite. Since ExpiredAt type is uint64, we cannot set it to infinite, so set it to maximum value int64 (not maximum of uint64). --- lib/email/dkim/signature.go | 21 ++++++++++++++++----- lib/email/dkim/signature_test.go | 5 +++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/lib/email/dkim/signature.go b/lib/email/dkim/signature.go index c69a0519..acb3a73f 100644 --- a/lib/email/dkim/signature.go +++ b/lib/email/dkim/signature.go @@ -14,6 +14,7 @@ import ( "encoding/base64" "errors" "fmt" + "math" "strconv" "time" ) @@ -99,16 +100,20 @@ func Parse(value []byte) (sig *Signature, err error) { return nil, nil } - l := len(value) + var l = len(value) if value[l-2] != '\r' && value[l-1] != '\n' { return nil, errors.New("dkim: value must end with CRLF") } - p := newParser(value) + var ( + p = newParser(value) + + tag *tag + ) sig = &Signature{} for { - tag, err := p.fetchTag() + tag, err = p.fetchTag() if err != nil { return sig, err } @@ -454,7 +459,6 @@ func (sig *Signature) set(t *tag) (err error) { return errors.New("dkim: x=: " + err.Error()) } err = sig.validateTime() - case tagCanon: sig.CanonHeader, sig.CanonBody, err = unpackCanons(t.value) @@ -565,7 +569,14 @@ func (sig *Signature) validateTime() (err error) { if sig.ExpiredAt < sig.CreatedAt { return errCreatedTime } - + if sig.ExpiredAt > math.MaxInt64 { + // According to RFC 6376, + // "To avoid denial-of-service attacks, implementations MAY + // consider any value longer than 12 digits to be + // infinite.". + sig.ExpiredAt = math.MaxInt64 + return nil + } exp := time.Unix(int64(sig.ExpiredAt), 0) now := time.Now().Add(time.Hour * -1).Unix() if uint64(now) > sig.ExpiredAt { diff --git a/lib/email/dkim/signature_test.go b/lib/email/dkim/signature_test.go index ec02f7be..00157d33 100644 --- a/lib/email/dkim/signature_test.go +++ b/lib/email/dkim/signature_test.go @@ -189,6 +189,11 @@ func TestSignatureParse(t *testing.T) { "4bmp/YzhwvcubU4=;" + " c=simple/simple;" + " i=joe@football.example.com; q=dns/txt\r\n", + }, { + desc: `With expired-at more than 12 digits`, + in: "v=1; a=rsa-sha256; d=example.com; s=mykey; h=from; bh=bh; b=b; t=1117574938; x=9223372036854775808\r\n", + expRelaxed: "v=1; a=rsa-sha256; d=example.com; s=mykey; h=from; bh=bh; b=b; t=1117574938; x=9223372036854775807; \r\n", + expSimple: "v=1; a=rsa-sha256; d=example.com; s=mykey; h=from; bh=bh; b=b; t=1117574938; x=9223372036854775808\r\n", }} for _, c := range cases {