Return HTTP errors when trying to kick invalid users (#1221)

Room integrity was never compromised as GMSL does auth checks,
but we would incorrectly 200 OK the request instead of 403ing.
This commit is contained in:
Kegsay 2020-07-27 09:20:09 +01:00 committed by GitHub
parent 61963a74ae
commit c8d476a3cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 12 additions and 4 deletions

View File

@ -96,6 +96,7 @@ func SendKick(
req *http.Request, accountDB accounts.Database, device *userapi.Device, req *http.Request, accountDB accounts.Database, device *userapi.Device,
roomID string, cfg *config.Dendrite, roomID string, cfg *config.Dendrite,
rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI, rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI,
stateAPI currentstateAPI.CurrentStateInternalAPI,
) util.JSONResponse { ) util.JSONResponse {
body, evTime, roomVer, reqErr := extractRequestData(req, roomID, rsAPI) body, evTime, roomVer, reqErr := extractRequestData(req, roomID, rsAPI)
if reqErr != nil { if reqErr != nil {
@ -108,6 +109,11 @@ func SendKick(
} }
} }
errRes := checkMemberInRoom(req.Context(), stateAPI, device.UserID, roomID)
if errRes != nil {
return *errRes
}
var queryRes roomserverAPI.QueryMembershipForUserResponse var queryRes roomserverAPI.QueryMembershipForUserResponse
err := rsAPI.QueryMembershipForUser(req.Context(), &roomserverAPI.QueryMembershipForUserRequest{ err := rsAPI.QueryMembershipForUser(req.Context(), &roomserverAPI.QueryMembershipForUserRequest{
RoomID: roomID, RoomID: roomID,
@ -116,11 +122,11 @@ func SendKick(
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
// kick is only valid if the user is not currently banned // kick is only valid if the user is not currently banned or left (that is, they are joined or invited)
if queryRes.Membership == "ban" { if queryRes.Membership != "join" && queryRes.Membership != "invite" {
return util.JSONResponse{ return util.JSONResponse{
Code: 403, Code: 403,
JSON: jsonerror.Unknown("cannot /kick banned users"), JSON: jsonerror.Unknown("cannot /kick banned or left users"),
} }
} }
// TODO: should we be using SendLeave instead? // TODO: should we be using SendLeave instead?

View File

@ -155,7 +155,7 @@ func Setup(
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
return SendKick(req, accountDB, device, vars["roomID"], cfg, rsAPI, asAPI) return SendKick(req, accountDB, device, vars["roomID"], cfg, rsAPI, asAPI, stateAPI)
}), }),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/unban", r0mux.Handle("/rooms/{roomID}/unban",

View File

@ -413,3 +413,5 @@ A full_state incremental update returns only recent timeline
A prev_batch token can be used in the v1 messages API A prev_batch token can be used in the v1 messages API
We don't send redundant membership state across incremental syncs by default We don't send redundant membership state across incremental syncs by default
Typing notifications don't leak Typing notifications don't leak
Users cannot kick users from a room they are not in
Users cannot kick users who have already left a room