Skip to content

Commit d1939de

Browse files
reject empty oauth2 state
1 parent f02ac63 commit d1939de

2 files changed

Lines changed: 45 additions & 0 deletions

File tree

oauth2/sessions.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,9 @@ func (s *SessionStateStore) VerifyState(r *http.Request, expected string) (bool,
5252
return false, err
5353
}
5454

55+
if state == "" {
56+
return false, nil
57+
}
58+
5559
return subtle.ConstantTimeCompare([]byte(expected), []byte(state)) == 1, nil
5660
}

oauth2/sessions_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2026 Palantir Technologies, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package oauth2
16+
17+
import (
18+
"net/http"
19+
"net/http/httptest"
20+
"testing"
21+
22+
"github.com/alexedwards/scs"
23+
"github.com/alexedwards/scs/stores/memstore"
24+
)
25+
26+
// An empty state means no OAuth flow was initiated.
27+
// VerifyState must reject it before comparing state values,
28+
// since the comparison treats two empty strings as a match.
29+
func TestSessionStateStore_VerifyState_RejectsEmptyState(t *testing.T) {
30+
store := &SessionStateStore{Sessions: scs.NewManager(memstore.New(0))}
31+
32+
r := httptest.NewRequest(http.MethodGet, "/callback?state=", nil)
33+
34+
ok, err := store.VerifyState(r, r.FormValue("state"))
35+
if err != nil {
36+
t.Fatalf("unexpected error: %v", err)
37+
}
38+
if ok {
39+
t.Fatal("VerifyState accepted an empty/unstored state")
40+
}
41+
}

0 commit comments

Comments
 (0)