diff options
| author | 2023-02-24 07:34:18 +0200 | |
|---|---|---|
| committer | 2023-02-24 08:05:25 +0200 | |
| commit | 5ae9ca83b735804f2bd405592983a73d7fcc42f4 (patch) | |
| tree | befda719e241e690df2bf0cea80b7af45bbe7a57 | |
| parent | app/keywords list: fix commit counting for edge cases (diff) | |
| download | soko-5ae9ca83b735804f2bd405592983a73d7fcc42f4.tar.gz soko-5ae9ca83b735804f2bd405592983a73d7fcc42f4.tar.bz2 soko-5ae9ca83b735804f2bd405592983a73d7fcc42f4.zip | |
index: fix DoS attack based on SQL Injection
If the user enables another view of the index page, using the "Recently
Visited Packages" page (in user preferences), the index page uses the
value of the `search_history` cookie as base64-encoded comma-separated
list of atoms. Those atoms are string loaded directly into the SQL query
with `atom = '%s'` format string. This allows the user to inject SQL
queries into the query, which can be used to DoS the server (for example
truncate all the tables, inject erroneous data, etc). In some time I'll
open a full report of this solved vulnerability.
Fix it by using parameterized queries with `pg.In` function, which is
safer and faster.
Signed-off-by: Arthur Zamarin <arthurzam@gentoo.org>
| -rw-r--r-- | pkg/app/handler/index/utils.go | 34 |
1 files changed, 14 insertions, 20 deletions
diff --git a/pkg/app/handler/index/utils.go b/pkg/app/handler/index/utils.go index 779fae1..23f8a25 100644 --- a/pkg/app/handler/index/utils.go +++ b/pkg/app/handler/index/utils.go @@ -33,20 +33,22 @@ func getAddedPackages(n int) []models.Package { } func getSearchHistoryPackages(r *http.Request) []models.Package { - var cookie, err = r.Cookie("search_history") var searchedPackages []models.Package - if err == nil { - packagesList := getSearchHistoryFromCookie(cookie) - err := database.DBCon.Model(&searchedPackages). - Where(getSearchHistoryQuery(packagesList)). - Relation("Versions"). - Select() - return getSortedSearchHistory(packagesList, searchedPackages) - if err != nil { - return searchedPackages - } + cookie, err := r.Cookie("search_history") + if err != nil { + return searchedPackages + } + packagesList := getSearchHistoryFromCookie(cookie) + + err = database.DBCon.Model(&searchedPackages). + Where("atom in (?)", pg.In(packagesList)). + Relation("Versions"). + Select() + if err != nil { + return searchedPackages } - return searchedPackages + + return getSortedSearchHistory(packagesList, searchedPackages) } func getSortedSearchHistory(sortedPackagesList []string, packagesList []models.Package) []models.Package { @@ -82,14 +84,6 @@ func getSearchHistoryFromCookie(cookie *http.Cookie) []string { return packagesList } -func getSearchHistoryQuery(packagesList []string) string { - var queryParts []string - for _, gpackage := range packagesList { - queryParts = append(queryParts, "atom = '"+gpackage+"'") - } - return strings.Join(queryParts, " OR ") -} - // getUpdatedVersions returns a list of a // given number of recently updated Versions func getUpdatedVersions(n int) []*models.Version { |
