fix: social images are validated on the API, MCP, batch and import paths (WR-16)

Only the admin seoimage field refused values that are not a path or an
http(s) URL; SetURLSEO, SaveRule and SaveSettings stored javascript:,
data: or protocol-relative values, which /resolve then served as
og:image. All three now refuse them with image.url_invalid.
This commit is contained in:
2026-10-27 15:35:02 +01:00
parent cab1b9aef4
commit c8e0961740
4 changed files with 27 additions and 2 deletions

View File

@@ -145,6 +145,9 @@ func (s *Service) SetURLSEO(ctx context.Context, tx *gorm.DB, in URLSEOWrite) (U
case column == "canonical" && v != "" && !ValidURLRef(v):
problems[column] = append(problems[column], models.Problem{Key: "golem15.seo::lang.api.canonical_invalid"})
continue
case column == "og_image" && !ValidImageURL(v):
problems[column] = append(problems[column], models.Problem{Key: errImageURL})
continue
}
values[column] = v
}

View File

@@ -28,8 +28,8 @@ func LoadRule(db *gorm.DB, id uint) (models.Rule, error) {
// SaveRule validates and stores r inside tx and records it in history: the
// address is trimmed and the match normalised, robots values are brought
// to the C5 grammar and a canonical must be a path or an http(s) URL. Field
// problems are refused with a *ProblemsError.
// to the C5 grammar, and a canonical and the social image must be a path
// or an http(s) URL. Field problems are refused with a *ProblemsError.
func (s *Service) SaveRule(ctx context.Context, tx *gorm.DB, r *models.Rule) error {
if r == nil {
return errors.New("golem15.seo: no rule")
@@ -47,6 +47,10 @@ func (s *Service) SaveRule(ctx context.Context, tx *gorm.DB, r *models.Rule) err
if v := strings.TrimSpace(r.Canonical); v != "" && !ValidURLRef(v) {
problems["canonical"] = append(problems["canonical"], models.Problem{Key: "golem15.seo::lang.api.canonical_invalid"})
}
r.OGImage = strings.TrimSpace(r.OGImage)
if !ValidImageURL(r.OGImage) {
problems["og_image"] = append(problems["og_image"], models.Problem{Key: errImageURL})
}
if len(problems) > 0 {
return &ProblemsError{Problems: problems}
}

View File

@@ -202,6 +202,9 @@ func (s *Service) SaveSettings(ctx context.Context, tx *gorm.DB, in SettingsWrit
oneOf("url_host", row.URLHost, models.HostKeep, models.HostWWW, models.HostBare)
oneOf("url_slash", row.URLSlash, models.SlashKeep, models.SlashAdd, models.SlashDrop)
oneOf("csv_delimiter", row.CSVDelimiter, "", ",", ";")
if _, sent := in.Values["default_og_image"]; sent && !ValidImageURL(row.DefaultOGImage) {
problems["default_og_image"] = append(problems["default_og_image"], models.Problem{Key: errImageURL})
}
for field, list := range row.Problems() {
problems[field] = append(problems[field], list...)
}