diff options
author | Daniel Schalla <daniel@schalla.me> | 2018-08-02 00:16:04 +0200 |
---|---|---|
committer | Christopher Speller <crspeller@gmail.com> | 2018-08-01 15:16:04 -0700 |
commit | 2936dc87d074e6d83147c9e6cf4ae8bac4e4af8d (patch) | |
tree | 2e843f8fdf8382b13fe0a902e7b6183f1f4475bd /app/plugin_requests.go | |
parent | 90e84d76efa775cdf7c54363218bf6817cd1bf33 (diff) | |
download | chat-2936dc87d074e6d83147c9e6cf4ae8bac4e4af8d.tar.gz chat-2936dc87d074e6d83147c9e6cf4ae8bac4e4af8d.tar.bz2 chat-2936dc87d074e6d83147c9e6cf4ae8bac4e4af8d.zip |
CSRF Token Implementation for Plugins (#9192)
deleted test config
fix test config
Dont wipe the session token for plugins
Simplified Tokens; Generate CSRF for other sessions
Remove CSRF from Access Token; Remove Getter/Setter from Context
fix removed setter
remove getcsrf helper from plugin api
enforce csrf only for cookie auth
Diffstat (limited to 'app/plugin_requests.go')
-rw-r--r-- | app/plugin_requests.go | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/app/plugin_requests.go b/app/plugin_requests.go index 2f9ac1476..ec6091017 100644 --- a/app/plugin_requests.go +++ b/app/plugin_requests.go @@ -8,11 +8,13 @@ import ( "path" "strings" + "bytes" "github.com/gorilla/mux" "github.com/mattermost/mattermost-server/mlog" "github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/plugin" "github.com/mattermost/mattermost-server/utils" + "io/ioutil" ) func (a *App) ServePluginRequest(w http.ResponseWriter, r *http.Request) { @@ -38,22 +40,44 @@ func (a *App) ServePluginRequest(w http.ResponseWriter, r *http.Request) { func (a *App) servePluginRequest(w http.ResponseWriter, r *http.Request, handler func(*plugin.Context, http.ResponseWriter, *http.Request)) { token := "" + context := &plugin.Context{} + cookieAuth := false authHeader := r.Header.Get(model.HEADER_AUTH) if strings.HasPrefix(strings.ToUpper(authHeader), model.HEADER_BEARER+" ") { token = authHeader[len(model.HEADER_BEARER)+1:] } else if strings.HasPrefix(strings.ToLower(authHeader), model.HEADER_TOKEN+" ") { token = authHeader[len(model.HEADER_TOKEN)+1:] - } else if cookie, _ := r.Cookie(model.SESSION_COOKIE_TOKEN); cookie != nil && (r.Method == "GET" || r.Header.Get(model.HEADER_REQUESTED_WITH) == model.HEADER_REQUESTED_WITH_XML) { + } else if cookie, _ := r.Cookie(model.SESSION_COOKIE_TOKEN); cookie != nil { token = cookie.Value + cookieAuth = true } else { token = r.URL.Query().Get("access_token") } r.Header.Del("Mattermost-User-Id") if token != "" { - if session, err := a.GetSession(token); session != nil && err == nil { + session, err := a.GetSession(token) + csrfCheckPassed := true + + if err == nil && cookieAuth && r.Method != "GET" && r.Header.Get(model.HEADER_REQUESTED_WITH) != model.HEADER_REQUESTED_WITH_XML { + bodyBytes, _ := ioutil.ReadAll(r.Body) + r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) + r.ParseForm() + sentToken := r.FormValue("csrf") + expectedToken := session.GetCSRF() + + if sentToken != expectedToken { + csrfCheckPassed = false + } + + // Set Request Body again, since otherwise form values aren't accessible in plugin handler + r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) + } + + if session != nil && err == nil && csrfCheckPassed { r.Header.Set("Mattermost-User-Id", session.UserId) + context.SessionId = session.Id } } @@ -76,5 +100,5 @@ func (a *App) servePluginRequest(w http.ResponseWriter, r *http.Request, handler r.URL.RawQuery = newQuery.Encode() r.URL.Path = strings.TrimPrefix(r.URL.Path, path.Join(subpath, "plugins", params["plugin_id"])) - handler(&plugin.Context{}, w, r) + handler(context, w, r) } |