MM-15889 Add unit tests for CSRF checks (#11058)

* MM-15889 Add unit tests for CSRF checks

* Moved CSRF token test to login tests

* Remove empty test

* Remove debug messages
Этот коммит содержится в:
Harrison Healey
2019-06-11 15:09:00 -04:00
коммит произвёл GitHub
родитель 28cf642ccb
Коммит 803ce61ef8
8 изменённых файлов: 300 добавлений и 80 удалений

Просмотреть файл

@@ -8,6 +8,7 @@ import (
"net/http/httptest"
"testing"
"github.com/mattermost/mattermost-server/app"
"github.com/mattermost/mattermost-server/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -337,3 +338,178 @@ func TestHandlerServeInvalidToken(t *testing.T) {
})
}
}
func TestCheckCSRFToken(t *testing.T) {
t.Run("should allow a POST request with a valid CSRF token header", func(t *testing.T) {
th := Setup()
defer th.TearDown()
h := &Handler{
RequireSession: true,
TrustRequester: false,
}
token := "token"
tokenLocation := app.TokenLocationCookie
c := &Context{
App: th.App,
}
r, _ := http.NewRequest(http.MethodPost, "", nil)
r.Header.Set(model.HEADER_CSRF_TOKEN, token)
session := &model.Session{
Props: map[string]string{
"csrf": token,
},
}
checked, passed := h.checkCSRFToken(c, r, token, tokenLocation, session)
assert.True(t, checked)
assert.True(t, passed)
assert.Nil(t, c.Err)
})
t.Run("should allow a POST request with an X-Requested-With header", func(t *testing.T) {
th := Setup()
defer th.TearDown()
h := &Handler{
RequireSession: true,
TrustRequester: false,
}
token := "token"
tokenLocation := app.TokenLocationCookie
c := &Context{
App: th.App,
Log: th.App.Log,
}
r, _ := http.NewRequest(http.MethodPost, "", nil)
r.Header.Set(model.HEADER_REQUESTED_WITH, model.HEADER_REQUESTED_WITH_XML)
session := &model.Session{
Props: map[string]string{
"csrf": token,
},
}
checked, passed := h.checkCSRFToken(c, r, token, tokenLocation, session)
assert.True(t, checked)
assert.True(t, passed)
assert.Nil(t, c.Err)
})
t.Run("should not allow a POST request with an X-Requested-With header with strict CSRF enforcement enabled", func(t *testing.T) {
th := Setup()
defer th.TearDown()
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.ExperimentalStrictCSRFEnforcement = true
})
h := &Handler{
RequireSession: true,
TrustRequester: false,
}
token := "token"
tokenLocation := app.TokenLocationCookie
c := &Context{
App: th.App,
Log: th.App.Log,
}
r, _ := http.NewRequest(http.MethodPost, "", nil)
r.Header.Set(model.HEADER_REQUESTED_WITH, model.HEADER_REQUESTED_WITH_XML)
session := &model.Session{
Props: map[string]string{
"csrf": token,
},
}
checked, passed := h.checkCSRFToken(c, r, token, tokenLocation, session)
assert.True(t, checked)
assert.False(t, passed)
assert.NotNil(t, c.Err)
})
t.Run("should not allow a POST request without either header", func(t *testing.T) {
th := Setup()
defer th.TearDown()
h := &Handler{
RequireSession: true,
TrustRequester: false,
}
token := "token"
tokenLocation := app.TokenLocationCookie
c := &Context{
App: th.App,
}
r, _ := http.NewRequest(http.MethodPost, "", nil)
session := &model.Session{
Props: map[string]string{
"csrf": token,
},
}
checked, passed := h.checkCSRFToken(c, r, token, tokenLocation, session)
assert.True(t, checked)
assert.False(t, passed)
assert.NotNil(t, c.Err)
})
t.Run("should not check GET requests", func(t *testing.T) {
th := Setup()
defer th.TearDown()
h := &Handler{
RequireSession: true,
TrustRequester: false,
}
token := "token"
tokenLocation := app.TokenLocationCookie
c := &Context{
App: th.App,
}
r, _ := http.NewRequest(http.MethodGet, "", nil)
checked, passed := h.checkCSRFToken(c, r, token, tokenLocation, nil)
assert.False(t, checked)
assert.False(t, passed)
assert.Nil(t, c.Err)
})
t.Run("should not check a request passing the auth token in a header", func(t *testing.T) {
th := Setup()
defer th.TearDown()
h := &Handler{
RequireSession: true,
TrustRequester: false,
}
token := "token"
tokenLocation := app.TokenLocationHeader
c := &Context{
App: th.App,
}
r, _ := http.NewRequest(http.MethodPost, "", nil)
checked, passed := h.checkCSRFToken(c, r, token, tokenLocation, nil)
assert.False(t, checked)
assert.False(t, passed)
assert.Nil(t, c.Err)
})
}