1
Fork 0
In order to prevent SQL injections and , reveal information about the database tables avoid passing MySQL functions as GQL sorting parameters, I refactored the FormatSQL() function.
Additionally, the old approach with using regex to filter the orderBy parameter was not effective and prevented using column.table annotations.
This commit is contained in:
stz184 2020-10-13 18:27:28 +03:00
parent f14bdd6b3f
commit 53b323640f
4 changed files with 22 additions and 19 deletions

View File

@ -3,32 +3,35 @@ package models
import (
"fmt"
"log"
"regexp"
"strings"
)
func (filter *Filter) FormatSQL() (string, error) {
func (filter *Filter) FormatSQL(context string) (string, error) {
if filter == nil {
return "", nil
}
orderByMap := make(map[string]string)
orderByMap["media_date_shot"] = "media.date_shot"
orderByMap["media_date_imported"] = "media.date_imported"
orderByMap["media_title"] = "media.title"
orderByMap["media_kind"] = "media.media_type, SUBSTRING_INDEX(media.path, '.', -1)"
orderByMap["album_title"] = "album.title"
result := ""
if filter.OrderBy != nil {
order_by := filter.OrderBy
match, err := regexp.MatchString("^(\\w+(?:\\.\\w+)?(,\\s)?)+$", strings.TrimSpace(*filter.OrderBy))
if err != nil {
return "", err
order_by, ok := orderByMap[context+"_"+*filter.OrderBy]
if !ok {
log.Printf("Invalid order column: '%s'\n", *filter.OrderBy)
return "", nil
}
if match {
direction := "ASC"
if filter.OrderDirection != nil && filter.OrderDirection.IsValid() {
direction = filter.OrderDirection.String()
}
result += fmt.Sprintf(" ORDER BY %s %s", *order_by, direction)
direction := "ASC"
if filter.OrderDirection != nil && filter.OrderDirection.IsValid() {
direction = filter.OrderDirection.String()
}
result += fmt.Sprintf(" ORDER BY %s %s", order_by, direction)
}
if filter.Limit != nil {

View File

@ -15,7 +15,7 @@ func (r *queryResolver) MyAlbums(ctx context.Context, filter *models.Filter, onl
return nil, auth.ErrUnauthorized
}
filterSQL, err := filter.FormatSQL()
filterSQL, err := filter.FormatSQL("album")
if err != nil {
return nil, err
}
@ -79,7 +79,7 @@ type albumResolver struct{ *Resolver }
func (r *albumResolver) Media(ctx context.Context, obj *models.Album, filter *models.Filter, onlyFavorites *bool) ([]*models.Media, error) {
filterSQL, err := filter.FormatSQL()
filterSQL, err := filter.FormatSQL("media")
if err != nil {
return nil, err
}
@ -138,7 +138,7 @@ func (r *albumResolver) Thumbnail(ctx context.Context, obj *models.Album) (*mode
}
func (r *albumResolver) SubAlbums(ctx context.Context, obj *models.Album, filter *models.Filter) ([]*models.Album, error) {
filterSQL, err := filter.FormatSQL()
filterSQL, err := filter.FormatSQL("album")
if err != nil {
return nil, err
}

View File

@ -18,7 +18,7 @@ func (r *queryResolver) MyMedia(ctx context.Context, filter *models.Filter) ([]*
return nil, errors.New("unauthorized")
}
filterSQL, err := filter.FormatSQL()
filterSQL, err := filter.FormatSQL("media")
if err != nil {
return nil, err
}

View File

@ -18,7 +18,7 @@ import (
func (r *queryResolver) User(ctx context.Context, filter *models.Filter) ([]*models.User, error) {
filterSQL, err := filter.FormatSQL()
filterSQL, err := filter.FormatSQL("user")
if err != nil {
return nil, err
}