query unescape more routes

fixes #447. Went through all routes with components in the path to check
if they needed escaping, quite a few did.
This commit is contained in:
Harvey Tindall
2025-12-06 20:04:30 +00:00
parent e5315095be
commit fcfd5f4981
4 changed files with 40 additions and 9 deletions

View File

@@ -1,6 +1,7 @@
package main package main
import ( import (
"net/url"
"os" "os"
"path/filepath" "path/filepath"
"sort" "sort"
@@ -29,10 +30,15 @@ func (app *appContext) CreateBackup(gc *gin.Context) {
// @Security Bearer // @Security Bearer
// @tags Backups // @tags Backups
func (app *appContext) GetBackup(gc *gin.Context) { func (app *appContext) GetBackup(gc *gin.Context) {
fname := gc.Param("fname") escapedFName := gc.Param("fname")
fname, err := url.QueryUnescape(escapedFName)
if err != nil {
respondBool(400, false, gc)
return
}
// Hopefully this is enough to ensure the path isn't malicious. Hidden behind bearer auth anyway so shouldn't matter too much I guess. // Hopefully this is enough to ensure the path isn't malicious. Hidden behind bearer auth anyway so shouldn't matter too much I guess.
b := Backup{} b := Backup{}
err := b.FromString(fname) err = b.FromString(fname)
if err != nil || b.Date.IsZero() { if err != nil || b.Date.IsZero() {
app.debug.Printf(lm.IgnoreInvalidFilename, fname, err) app.debug.Printf(lm.IgnoreInvalidFilename, fname, err)
respondBool(400, false, gc) respondBool(400, false, gc)

View File

@@ -1,6 +1,7 @@
package main package main
import ( import (
"net/url"
"time" "time"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@@ -584,8 +585,9 @@ func (app *appContext) MatrixConnect(gc *gin.Context) {
// @Security Bearer // @Security Bearer
// @tags Other // @tags Other
func (app *appContext) DiscordGetUsers(gc *gin.Context) { func (app *appContext) DiscordGetUsers(gc *gin.Context) {
name := gc.Param("username") escapedName := gc.Param("username")
if name == "" { name, err := url.QueryUnescape(escapedName)
if err != nil || name == "" {
respondBool(400, false, gc) respondBool(400, false, gc)
return return
} }

View File

@@ -247,7 +247,13 @@ func (app *appContext) DeleteProfile(gc *gin.Context) {
// @Security Bearer // @Security Bearer
// @tags Profiles & Settings // @tags Profiles & Settings
func (app *appContext) EnableReferralForProfile(gc *gin.Context) { func (app *appContext) EnableReferralForProfile(gc *gin.Context) {
profileName := gc.Param("profile") escapedProfileName := gc.Param("profile")
profileName, err := url.QueryUnescape(escapedProfileName)
if err != nil {
respond(400, "Invalid profile", gc)
app.err.Printf(lm.FailedGetProfile, profileName)
return
}
invCode := gc.Param("invite") invCode := gc.Param("invite")
useExpiry := gc.Param("useExpiry") == "with-expiry" useExpiry := gc.Param("useExpiry") == "with-expiry"
inv, ok := app.storage.GetInvitesKey(invCode) inv, ok := app.storage.GetInvitesKey(invCode)
@@ -294,7 +300,13 @@ func (app *appContext) EnableReferralForProfile(gc *gin.Context) {
// @Security Bearer // @Security Bearer
// @tags Profiles & Settings // @tags Profiles & Settings
func (app *appContext) DisableReferralForProfile(gc *gin.Context) { func (app *appContext) DisableReferralForProfile(gc *gin.Context) {
profileName := gc.Param("profile") escapedProfileName := gc.Param("profile")
profileName, err := url.QueryUnescape(escapedProfileName)
if err != nil {
respond(400, "Invalid profile", gc)
app.err.Printf(lm.FailedGetProfile, profileName)
return
}
profile, ok := app.storage.GetProfileKey(profileName) profile, ok := app.storage.GetProfileKey(profileName)
if !ok { if !ok {
respondBool(200, true, gc) respondBool(200, true, gc)

View File

@@ -625,7 +625,12 @@ func (app *appContext) EnableReferralForUsers(gc *gin.Context) {
gc.BindJSON(&req) gc.BindJSON(&req)
mode := gc.Param("mode") mode := gc.Param("mode")
source := gc.Param("source") escapedSource := gc.Param("source")
source, err := url.QueryUnescape(escapedSource)
if err != nil {
respondBool(400, false, gc)
return
}
useExpiry := gc.Param("useExpiry") == "with-expiry" useExpiry := gc.Param("useExpiry") == "with-expiry"
baseInv := Invite{} baseInv := Invite{}
if mode == "profile" { if mode == "profile" {
@@ -813,13 +818,19 @@ func (app *appContext) GetAnnounceTemplate(gc *gin.Context) {
// @Summary Delete an announcement template. // @Summary Delete an announcement template.
// @Produce json // @Produce json
// @Success 200 {object} boolResponse // @Success 200 {object} boolResponse
// @Failure 400 {object} boolResponse
// @Failure 500 {object} boolResponse // @Failure 500 {object} boolResponse
// @Param name path string true "name of template" // @Param name path string true "name of template (url encoded if necessary)"
// @Router /users/announce/template/{name} [delete] // @Router /users/announce/template/{name} [delete]
// @Security Bearer // @Security Bearer
// @tags Users // @tags Users
func (app *appContext) DeleteAnnounceTemplate(gc *gin.Context) { func (app *appContext) DeleteAnnounceTemplate(gc *gin.Context) {
name := gc.Param("name") escapedName := gc.Param("name")
name, err := url.QueryUnescape(escapedName)
if err != nil {
respondBool(400, false, gc)
return
}
app.storage.DeleteAnnouncementsKey(name) app.storage.DeleteAnnouncementsKey(name)
respondBool(200, false, gc) respondBool(200, false, gc)
} }