A url item stored as javascript://%0aalert(1)%0a//x passed Url::to and reached <loc>, which sitemap.xsl renders as a link on the site origin. - The definitions form refuses, per row, a url that is not a path or an http(s) URL (classes.AllowedItemURL) and a urlPattern that is not a path (signpost.ValidItemPattern), keyed data.<i>.url / .urlPattern. - Generator.addItem drops a loc or alternate that is not http(s). - sitemap:import-winter drops such url items and clears such patterns with a report line; sitemap:import refuses such an entry.
40 lines
1.3 KiB
Go
40 lines
1.3 KiB
Go
package controllers
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
|
|
"git.golem15.com/golem15/sm-sitemap-plugin/models"
|
|
"git.golem15.com/golem15/summercms/modules/cabana"
|
|
)
|
|
|
|
func ptr(s string) *string { return &s }
|
|
|
|
// TestCheckItems pins the CR-01 save check: per row, a url outside
|
|
// classes.AllowedItemURL and a URL pattern that is not a path are refused
|
|
// under data.<i>.url and data.<i>.urlPattern.
|
|
func TestCheckItems(t *testing.T) {
|
|
c := definitionsAdminController{}
|
|
def := &models.Definition{}
|
|
def.SetItems([]models.DefinitionItem{
|
|
{Type: models.ItemTypeURL, URL: ptr("/about")},
|
|
{Type: models.ItemTypeURL, URL: ptr("javascript://%0aalert(1)%0a//x")},
|
|
{Type: "acme-post", URLPattern: ptr("//evil.test/:slug")},
|
|
{Type: "acme-post", URLPattern: ptr("/blog/:slug")},
|
|
})
|
|
err := c.checkItems(def)
|
|
var verr *cabana.ValidationError
|
|
if !errors.As(err, &verr) {
|
|
t.Fatalf("checkItems = %v, want a validation error", err)
|
|
}
|
|
if len(verr.Details) != 2 || verr.Details["data.1.url"] == nil || verr.Details["data.2.urlPattern"] == nil {
|
|
t.Fatalf("details = %v", verr.Details)
|
|
}
|
|
|
|
ok := &models.Definition{}
|
|
ok.SetItems([]models.DefinitionItem{{Type: models.ItemTypeURL, URL: ptr("https://example.test/")}})
|
|
if err := c.checkItems(ok); err != nil {
|
|
t.Fatalf("a valid definition was refused: %v", err)
|
|
}
|
|
}
|