Skip to content

Commit a1634b2

Browse files
authored
fix: roll out bluemonday Sanitize more widely (#3794)
* initial pass: roll out bluemonday sanitization more widely Signed-off-by: Dave Lee <[email protected]> * add one additional sanitize - the overall modelslist used by the docs site Signed-off-by: Dave Lee <[email protected]> --------- Signed-off-by: Dave Lee <[email protected]>
1 parent 6257e2f commit a1634b2

File tree

6 files changed

+37
-29
lines changed

6 files changed

+37
-29
lines changed

.github/ci/modelslist.go

+7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"io/ioutil"
77
"os"
88

9+
"github.com/microcosm-cc/bluemonday"
910
"gopkg.in/yaml.v3"
1011
)
1112

@@ -279,6 +280,12 @@ func main() {
279280
return
280281
}
281282

283+
// Ensure that all arbitrary text content is sanitized before display
284+
for i, m := range models {
285+
models[i].Name = bluemonday.StrictPolicy().Sanitize(m.Name)
286+
models[i].Description = bluemonday.StrictPolicy().Sanitize(m.Description)
287+
}
288+
282289
// render the template
283290
data := struct {
284291
Models []*GalleryModel

core/http/elements/gallery.go

+10-13
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/chasefleming/elem-go"
88
"github.com/chasefleming/elem-go/attrs"
9+
"github.com/microcosm-cc/bluemonday"
910
"github.com/mudler/LocalAI/core/gallery"
1011
"github.com/mudler/LocalAI/core/p2p"
1112
"github.com/mudler/LocalAI/core/services"
@@ -41,7 +42,7 @@ func DoneProgress(galleryID, text string, showDelete bool) string {
4142
"tabindex": "-1",
4243
"autofocus": "",
4344
},
44-
elem.Text(text),
45+
elem.Text(bluemonday.StrictPolicy().Sanitize(text)),
4546
),
4647
elem.If(showDelete, deleteButton(galleryID, modelName), reInstallButton(galleryID)),
4748
).Render()
@@ -57,7 +58,7 @@ func ErrorProgress(err, galleryName string) string {
5758
"tabindex": "-1",
5859
"autofocus": "",
5960
},
60-
elem.Text("Error "+err),
61+
elem.Text("Error "+bluemonday.StrictPolicy().Sanitize(err)),
6162
),
6263
installButton(galleryName),
6364
).Render()
@@ -170,7 +171,7 @@ func P2PNodeBoxes(nodes []p2p.NodeData) string {
170171
attrs.Props{
171172
"class": "text-gray-200 font-semibold ml-2 mr-1",
172173
},
173-
elem.Text(n.ID),
174+
elem.Text(bluemonday.StrictPolicy().Sanitize(n.ID)),
174175
),
175176
elem.Text("Status: "),
176177
elem.If(
@@ -227,7 +228,7 @@ func StartProgressBar(uid, progress, text string) string {
227228
"tabindex": "-1",
228229
"autofocus": "",
229230
},
230-
elem.Text(text),
231+
elem.Text(bluemonday.StrictPolicy().Sanitize(text)), //Perhaps overly defensive
231232
elem.Div(attrs.Props{
232233
"hx-get": "/browse/job/progress/" + uid,
233234
"hx-trigger": "every 600ms",
@@ -249,9 +250,7 @@ func cardSpan(text, icon string) elem.Node {
249250
"class": icon + " pr-2",
250251
}),
251252

252-
elem.Text(text),
253-
254-
//elem.Text(text),
253+
elem.Text(bluemonday.StrictPolicy().Sanitize(text)),
255254
)
256255
}
257256

@@ -285,11 +284,9 @@ func searchableElement(text, icon string) elem.Node {
285284
elem.I(attrs.Props{
286285
"class": icon + " pr-2",
287286
}),
288-
elem.Text(text),
287+
elem.Text(bluemonday.StrictPolicy().Sanitize(text)),
289288
),
290289
),
291-
292-
//elem.Text(text),
293290
)
294291
}
295292

@@ -303,7 +300,7 @@ func link(text, url string) elem.Node {
303300
elem.I(attrs.Props{
304301
"class": "fas fa-link pr-2",
305302
}),
306-
elem.Text(text),
303+
elem.Text(bluemonday.StrictPolicy().Sanitize(text)),
307304
)
308305
}
309306
func installButton(galleryName string) elem.Node {
@@ -387,13 +384,13 @@ func ListModels(models []*gallery.GalleryModel, processTracker ProcessTracker, g
387384
attrs.Props{
388385
"class": "mb-2 text-xl font-bold leading-tight",
389386
},
390-
elem.Text(m.Name),
387+
elem.Text(bluemonday.StrictPolicy().Sanitize(m.Name)),
391388
),
392389
elem.P(
393390
attrs.Props{
394391
"class": "mb-4 text-sm [&:not(:hover)]:truncate text-base",
395392
},
396-
elem.Text(m.Description),
393+
elem.Text(bluemonday.StrictPolicy().Sanitize(m.Description)),
397394
),
398395
)
399396
}

core/http/endpoints/openai/assistant.go

+9-8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"time"
1111

1212
"github.com/gofiber/fiber/v2"
13+
"github.com/microcosm-cc/bluemonday"
1314
"github.com/mudler/LocalAI/core/config"
1415
"github.com/mudler/LocalAI/core/schema"
1516
"github.com/mudler/LocalAI/core/services"
@@ -83,7 +84,7 @@ func CreateAssistantEndpoint(cl *config.BackendConfigLoader, ml *model.ModelLoad
8384

8485
if !modelExists(cl, ml, request.Model) {
8586
log.Warn().Msgf("Model: %s was not found in list of models.", request.Model)
86-
return c.Status(fiber.StatusBadRequest).SendString("Model " + request.Model + " not found")
87+
return c.Status(fiber.StatusBadRequest).SendString(bluemonday.StrictPolicy().Sanitize(fmt.Sprintf("Model %q not found", request.Model)))
8788
}
8889

8990
if request.Tools == nil {
@@ -147,7 +148,7 @@ func ListAssistantsEndpoint(cl *config.BackendConfigLoader, ml *model.ModelLoade
147148
// Convert string limit to integer
148149
limit, err := strconv.Atoi(limitQuery)
149150
if err != nil {
150-
return c.Status(http.StatusBadRequest).SendString(fmt.Sprintf("Invalid limit query value: %s", limitQuery))
151+
return c.Status(http.StatusBadRequest).SendString(bluemonday.StrictPolicy().Sanitize(fmt.Sprintf("Invalid limit query value: %s", limitQuery)))
151152
}
152153

153154
// Sort assistants
@@ -288,7 +289,7 @@ func GetAssistantEndpoint(cl *config.BackendConfigLoader, ml *model.ModelLoader,
288289
}
289290
}
290291

291-
return c.Status(fiber.StatusNotFound).SendString(fmt.Sprintf("Unable to find assistant with id: %s", assistantID))
292+
return c.Status(fiber.StatusNotFound).SendString(bluemonday.StrictPolicy().Sanitize(fmt.Sprintf("Unable to find assistant with id: %s", assistantID)))
292293
}
293294
}
294295

@@ -337,11 +338,11 @@ func CreateAssistantFileEndpoint(cl *config.BackendConfigLoader, ml *model.Model
337338
}
338339
}
339340

340-
return c.Status(fiber.StatusNotFound).SendString(fmt.Sprintf("Unable to find file_id: %s", request.FileID))
341+
return c.Status(fiber.StatusNotFound).SendString(bluemonday.StrictPolicy().Sanitize(fmt.Sprintf("Unable to find file_id: %s", request.FileID)))
341342
}
342343
}
343344

344-
return c.Status(fiber.StatusNotFound).SendString(fmt.Sprintf("Unable to find %q", assistantID))
345+
return c.Status(fiber.StatusNotFound).SendString(bluemonday.StrictPolicy().Sanitize(fmt.Sprintf("Unable to find %q", assistantID)))
345346
}
346347
}
347348

@@ -442,7 +443,7 @@ func ModifyAssistantEndpoint(cl *config.BackendConfigLoader, ml *model.ModelLoad
442443
return c.Status(fiber.StatusOK).JSON(newAssistant)
443444
}
444445
}
445-
return c.Status(fiber.StatusNotFound).SendString(fmt.Sprintf("Unable to find assistant with id: %s", assistantID))
446+
return c.Status(fiber.StatusNotFound).SendString(bluemonday.StrictPolicy().Sanitize(fmt.Sprintf("Unable to find assistant with id: %s", assistantID)))
446447
}
447448
}
448449

@@ -513,9 +514,9 @@ func GetAssistantFileEndpoint(cl *config.BackendConfigLoader, ml *model.ModelLoa
513514
if assistantFile.ID == fileId {
514515
return c.Status(fiber.StatusOK).JSON(assistantFile)
515516
}
516-
return c.Status(fiber.StatusNotFound).SendString(fmt.Sprintf("Unable to find assistant file with file_id: %s", fileId))
517+
return c.Status(fiber.StatusNotFound).SendString(bluemonday.StrictPolicy().Sanitize(fmt.Sprintf("Unable to find assistant file with file_id: %s", fileId)))
517518
}
518519
}
519-
return c.Status(fiber.StatusNotFound).SendString(fmt.Sprintf("Unable to find assistant file with assistant_id: %s", assistantID))
520+
return c.Status(fiber.StatusNotFound).SendString(bluemonday.StrictPolicy().Sanitize(fmt.Sprintf("Unable to find assistant file with assistant_id: %s", assistantID)))
520521
}
521522
}

core/http/endpoints/openai/files.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"sync/atomic"
99
"time"
1010

11+
"github.com/microcosm-cc/bluemonday"
1112
"github.com/mudler/LocalAI/core/config"
1213
"github.com/mudler/LocalAI/core/schema"
1314

@@ -49,7 +50,7 @@ func UploadFilesEndpoint(cm *config.BackendConfigLoader, appConfig *config.Appli
4950

5051
err = c.SaveFile(file, savePath)
5152
if err != nil {
52-
return c.Status(fiber.StatusInternalServerError).SendString("Failed to save file: " + err.Error())
53+
return c.Status(fiber.StatusInternalServerError).SendString("Failed to save file: " + bluemonday.StrictPolicy().Sanitize(err.Error()))
5354
}
5455

5556
f := schema.File{
@@ -121,7 +122,7 @@ func GetFilesEndpoint(cm *config.BackendConfigLoader, appConfig *config.Applicat
121122
return func(c *fiber.Ctx) error {
122123
file, err := getFileFromRequest(c)
123124
if err != nil {
124-
return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
125+
return c.Status(fiber.StatusInternalServerError).SendString(bluemonday.StrictPolicy().Sanitize(err.Error()))
125126
}
126127

127128
return c.JSON(file)
@@ -143,14 +144,14 @@ func DeleteFilesEndpoint(cm *config.BackendConfigLoader, appConfig *config.Appli
143144
return func(c *fiber.Ctx) error {
144145
file, err := getFileFromRequest(c)
145146
if err != nil {
146-
return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
147+
return c.Status(fiber.StatusInternalServerError).SendString(bluemonday.StrictPolicy().Sanitize(err.Error()))
147148
}
148149

149150
err = os.Remove(filepath.Join(appConfig.UploadDir, file.Filename))
150151
if err != nil {
151152
// If the file doesn't exist then we should just continue to remove it
152153
if !errors.Is(err, os.ErrNotExist) {
153-
return c.Status(fiber.StatusInternalServerError).SendString(fmt.Sprintf("Unable to delete file: %s, %v", file.Filename, err))
154+
return c.Status(fiber.StatusInternalServerError).SendString(bluemonday.StrictPolicy().Sanitize(fmt.Sprintf("Unable to delete file: %s, %v", file.Filename, err)))
154155
}
155156
}
156157

@@ -180,12 +181,12 @@ func GetFilesContentsEndpoint(cm *config.BackendConfigLoader, appConfig *config.
180181
return func(c *fiber.Ctx) error {
181182
file, err := getFileFromRequest(c)
182183
if err != nil {
183-
return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
184+
return c.Status(fiber.StatusInternalServerError).SendString(bluemonday.StrictPolicy().Sanitize(err.Error()))
184185
}
185186

186187
fileContents, err := os.ReadFile(filepath.Join(appConfig.UploadDir, file.Filename))
187188
if err != nil {
188-
return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
189+
return c.Status(fiber.StatusInternalServerError).SendString(bluemonday.StrictPolicy().Sanitize(err.Error()))
189190
}
190191

191192
return c.Send(fileContents)

core/http/middleware/auth.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/dave-gray101/v2keyauth"
88
"github.com/gofiber/fiber/v2"
99
"github.com/gofiber/fiber/v2/middleware/keyauth"
10+
"github.com/microcosm-cc/bluemonday"
1011
"github.com/mudler/LocalAI/core/config"
1112
)
1213

@@ -38,7 +39,7 @@ func getApiKeyErrorHandler(applicationConfig *config.ApplicationConfig) fiber.Er
3839
if applicationConfig.OpaqueErrors {
3940
return ctx.SendStatus(403)
4041
}
41-
return ctx.Status(403).SendString(err.Error())
42+
return ctx.Status(403).SendString(bluemonday.StrictPolicy().Sanitize(err.Error()))
4243
}
4344
if applicationConfig.OpaqueErrors {
4445
return ctx.SendStatus(500)

core/http/routes/ui.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"sort"
77
"strings"
88

9+
"github.com/microcosm-cc/bluemonday"
910
"github.com/mudler/LocalAI/core/config"
1011
"github.com/mudler/LocalAI/core/gallery"
1112
"github.com/mudler/LocalAI/core/http/elements"
@@ -171,7 +172,7 @@ func RegisterUIRoutes(app *fiber.App,
171172
Search string `form:"search"`
172173
}{}
173174
if err := c.BodyParser(&form); err != nil {
174-
return c.Status(fiber.StatusBadRequest).SendString(err.Error())
175+
return c.Status(fiber.StatusBadRequest).SendString(bluemonday.StrictPolicy().Sanitize(err.Error()))
175176
}
176177

177178
models, _ := gallery.AvailableGalleryModels(appConfig.Galleries, appConfig.ModelPath)

0 commit comments

Comments
 (0)