summaryrefslogtreecommitdiffstats
path: root/api4
diff options
context:
space:
mode:
authorMartin Kraft <martinkraft@gmail.com>2018-08-24 08:49:31 -0400
committerGitHub <noreply@github.com>2018-08-24 08:49:31 -0400
commited0fb617ef629a39d27441336951c098b13324d0 (patch)
tree447c0b1053a937fceb942f286fdc4036db36f91b /api4
parentf9dbea6d860a71d8756d69b80a5fc0fe91d6514b (diff)
downloadchat-ed0fb617ef629a39d27441336951c098b13324d0.tar.gz
chat-ed0fb617ef629a39d27441336951c098b13324d0.tar.bz2
chat-ed0fb617ef629a39d27441336951c098b13324d0.zip
MM-11786: Adds API endpoint to retrieve redirect locations. (#9284)
Diffstat (limited to 'api4')
-rw-r--r--api4/system.go32
-rw-r--r--api4/system_test.go34
2 files changed, 66 insertions, 0 deletions
diff --git a/api4/system.go b/api4/system.go
index 9177b8940..65d3b424b 100644
--- a/api4/system.go
+++ b/api4/system.go
@@ -40,6 +40,8 @@ func (api *API) InitSystem() {
api.BaseRoutes.ApiRoot.Handle("/logs", api.ApiHandler(postLog)).Methods("POST")
api.BaseRoutes.ApiRoot.Handle("/analytics/old", api.ApiSessionRequired(getAnalytics)).Methods("GET")
+
+ api.BaseRoutes.ApiRoot.Handle("/redirect_location", api.ApiSessionRequiredTrustRequester(getRedirectLocation)).Methods("GET")
}
func getSystemPing(c *Context, w http.ResponseWriter, r *http.Request) {
@@ -447,3 +449,33 @@ func testS3(c *Context, w http.ResponseWriter, r *http.Request) {
ReturnStatusOK(w)
}
+
+func getRedirectLocation(c *Context, w http.ResponseWriter, r *http.Request) {
+ url := r.URL.Query().Get("url")
+ if len(url) == 0 {
+ c.SetInvalidParam("url")
+ return
+ }
+
+ client := &http.Client{
+ CheckRedirect: func(req *http.Request, via []*http.Request) error {
+ return http.ErrUseLastResponse
+ },
+ }
+
+ m := make(map[string]string)
+ m["location"] = ""
+
+ res, err := client.Head(url)
+ if err != nil {
+ // Always return a success status and a JSON string to limit the amount of information returned to a
+ // hacker attempting to use Mattermost to probe a private network.
+ w.Write([]byte(model.MapToJson(m)))
+ return
+ }
+
+ m["location"] = res.Header.Get("Location")
+
+ w.Write([]byte(model.MapToJson(m)))
+ return
+}
diff --git a/api4/system_test.go b/api4/system_test.go
index 205572cf6..c66e08976 100644
--- a/api4/system_test.go
+++ b/api4/system_test.go
@@ -3,6 +3,7 @@ package api4
import (
"fmt"
"net/http"
+ "net/http/httptest"
"os"
"strings"
"testing"
@@ -700,3 +701,36 @@ func TestSupportedTimezones(t *testing.T) {
CheckNoError(t, resp)
assert.Equal(t, supportedTimezonesFromConfig, supportedTimezones)
}
+
+func TestRedirectLocation(t *testing.T) {
+ expected := "https://mattermost.com/wp-content/themes/mattermostv2/img/logo-light.svg"
+
+ testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
+ res.Header().Set("Location", expected)
+ res.WriteHeader(http.StatusFound)
+ res.Write([]byte("body"))
+ }))
+ defer func() { testServer.Close() }()
+
+ mockBitlyLink := testServer.URL
+
+ th := Setup().InitBasic().InitSystemAdmin()
+ defer th.TearDown()
+ Client := th.Client
+
+ _, resp := th.SystemAdminClient.GetRedirectLocation("https://mattermost.com/", "")
+ CheckNoError(t, resp)
+
+ _, resp = th.SystemAdminClient.GetRedirectLocation("", "")
+ CheckBadRequestStatus(t, resp)
+
+ actual, resp := th.SystemAdminClient.GetRedirectLocation(mockBitlyLink, "")
+ CheckNoError(t, resp)
+ if actual != expected {
+ t.Errorf("Expected %v but got %v.", expected, actual)
+ }
+
+ Client.Logout()
+ _, resp = Client.GetRedirectLocation("", "")
+ CheckUnauthorizedStatus(t, resp)
+}