mirror of
https://github.com/drakkan/sftpgo.git
synced 2024-11-21 23:20:24 +00:00
httpd: validate reference also for CSRF token in headers
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
14cabda5c2
commit
6896d2bfb1
4 changed files with 23 additions and 2 deletions
|
@ -468,6 +468,10 @@ func verifyCSRFToken(r *http.Request, csrfTokenAuth *jwtauth.JWTAuth) error {
|
||||||
logger.Debug(logSender, "", "error validating CSRF token IP audience")
|
logger.Debug(logSender, "", "error validating CSRF token IP audience")
|
||||||
return errors.New("the form token is not valid")
|
return errors.New("the form token is not valid")
|
||||||
}
|
}
|
||||||
|
return checkCSRFTokenRef(r, token)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkCSRFTokenRef(r *http.Request, token jwt.Token) error {
|
||||||
claims, err := getTokenClaims(r)
|
claims, err := getTokenClaims(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Debug(logSender, "", "error getting token claims for CSRF validation: %v", err)
|
logger.Debug(logSender, "", "error getting token claims for CSRF validation: %v", err)
|
||||||
|
|
|
@ -20705,6 +20705,17 @@ func TestWebAdminBasicMock(t *testing.T) {
|
||||||
checkResponseCode(t, http.StatusForbidden, rr)
|
checkResponseCode(t, http.StatusForbidden, rr)
|
||||||
assert.Contains(t, rr.Body.String(), "Invalid token")
|
assert.Contains(t, rr.Body.String(), "Invalid token")
|
||||||
|
|
||||||
|
req, err = http.NewRequest(http.MethodPost, webAdminTOTPSavePath, bytes.NewBuffer(asJSON))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
setJWTCookieForReq(req, altToken)
|
||||||
|
setCSRFHeaderForReq(req, csrfToken) // invalid CSRF token
|
||||||
|
req.RemoteAddr = defaultRemoteAddr
|
||||||
|
rr = executeRequest(req)
|
||||||
|
checkResponseCode(t, http.StatusForbidden, rr)
|
||||||
|
assert.Contains(t, rr.Body.String(), "the token is not valid")
|
||||||
|
|
||||||
|
csrfToken, err = getCSRFTokenFromInternalPageMock(webAdminPath, altToken)
|
||||||
|
assert.NoError(t, err)
|
||||||
req, err = http.NewRequest(http.MethodPost, webAdminTOTPSavePath, bytes.NewBuffer(asJSON))
|
req, err = http.NewRequest(http.MethodPost, webAdminTOTPSavePath, bytes.NewBuffer(asJSON))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
setJWTCookieForReq(req, altToken)
|
setJWTCookieForReq(req, altToken)
|
||||||
|
@ -20781,7 +20792,7 @@ func TestWebAdminBasicMock(t *testing.T) {
|
||||||
rr = executeRequest(req)
|
rr = executeRequest(req)
|
||||||
checkResponseCode(t, http.StatusSeeOther, rr)
|
checkResponseCode(t, http.StatusSeeOther, rr)
|
||||||
|
|
||||||
form.Set(csrfFormToken, "invalid csrf")
|
form.Set(csrfFormToken, csrfToken) // associated to altToken
|
||||||
req, _ = http.NewRequest(http.MethodPost, path.Join(webAdminPath, altAdminUsername), bytes.NewBuffer([]byte(form.Encode())))
|
req, _ = http.NewRequest(http.MethodPost, path.Join(webAdminPath, altAdminUsername), bytes.NewBuffer([]byte(form.Encode())))
|
||||||
req.RemoteAddr = defaultRemoteAddr
|
req.RemoteAddr = defaultRemoteAddr
|
||||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
@ -20790,6 +20801,8 @@ func TestWebAdminBasicMock(t *testing.T) {
|
||||||
checkResponseCode(t, http.StatusForbidden, rr)
|
checkResponseCode(t, http.StatusForbidden, rr)
|
||||||
assert.Contains(t, rr.Body.String(), util.I18nErrorInvalidCSRF)
|
assert.Contains(t, rr.Body.String(), util.I18nErrorInvalidCSRF)
|
||||||
|
|
||||||
|
csrfToken, err = getCSRFTokenFromInternalPageMock(webAdminPath, token)
|
||||||
|
assert.NoError(t, err)
|
||||||
form.Set(csrfFormToken, csrfToken)
|
form.Set(csrfFormToken, csrfToken)
|
||||||
form.Set("email", "not-an-email")
|
form.Set("email", "not-an-email")
|
||||||
req, _ = http.NewRequest(http.MethodPost, path.Join(webAdminPath, altAdminUsername), bytes.NewBuffer([]byte(form.Encode())))
|
req, _ = http.NewRequest(http.MethodPost, path.Join(webAdminPath, altAdminUsername), bytes.NewBuffer([]byte(form.Encode())))
|
||||||
|
|
|
@ -343,6 +343,10 @@ func (s *httpdServer) verifyCSRFHeader(next http.Handler) http.Handler {
|
||||||
sendAPIResponse(w, r, errors.New("the token is not valid"), "", http.StatusForbidden)
|
sendAPIResponse(w, r, errors.New("the token is not valid"), "", http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if err := checkCSRFTokenRef(r, token); err != nil {
|
||||||
|
sendAPIResponse(w, r, errors.New("the token is not valid"), "", http.StatusForbidden)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
next.ServeHTTP(w, r)
|
next.ServeHTTP(w, r)
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
NFPM_VERSION=2.39.0
|
NFPM_VERSION=2.40.0
|
||||||
NFPM_ARCH=${NFPM_ARCH:-amd64}
|
NFPM_ARCH=${NFPM_ARCH:-amd64}
|
||||||
if [ -z ${SFTPGO_VERSION} ]
|
if [ -z ${SFTPGO_VERSION} ]
|
||||||
then
|
then
|
||||||
|
|
Loading…
Reference in a new issue