[SECURITY] Test XSS in wiki last commit information
On the wiki and revisions page, information is shown about the last commit that modified that wiki page. This includes the time it was last edited and by whom. Verify it is sanitized.
This commit is contained in:
parent
2f5b266cca
commit
565e331238
1 changed files with 75 additions and 0 deletions
|
@ -4,14 +4,24 @@
|
||||||
package integration
|
package integration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/tests"
|
"code.gitea.io/gitea/tests"
|
||||||
|
|
||||||
|
gogit "github.com/go-git/go-git/v5"
|
||||||
|
"github.com/go-git/go-git/v5/plumbing/object"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestXSSUserFullName(t *testing.T) {
|
func TestXSSUserFullName(t *testing.T) {
|
||||||
|
@ -37,3 +47,68 @@ func TestXSSUserFullName(t *testing.T) {
|
||||||
htmlDoc.doc.Find("div.content").Find(".header.text.center").Text(),
|
htmlDoc.doc.Find("div.content").Find(".header.text.center").Text(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestXSSWikiLastCommitInfo(t *testing.T) {
|
||||||
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
|
// Prepare the environment.
|
||||||
|
dstPath := t.TempDir()
|
||||||
|
r := fmt.Sprintf("%suser2/repo1.wiki.git", u.String())
|
||||||
|
u, err := url.Parse(r)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
u.User = url.UserPassword("user2", userPassword)
|
||||||
|
assert.NoError(t, git.CloneWithArgs(context.Background(), git.AllowLFSFiltersArgs(), u.String(), dstPath, git.CloneRepoOptions{}))
|
||||||
|
|
||||||
|
// Use go-git here, because using git wouldn't work, it has code to remove
|
||||||
|
// `<`, `>` and `\n` in user names. Even though this is permitted and
|
||||||
|
// wouldn't result in a error by a Git server.
|
||||||
|
gitRepo, err := gogit.PlainOpen(dstPath)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
w, err := gitRepo.Worktree()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
filename := filepath.Join(dstPath, "Home.md")
|
||||||
|
err = os.WriteFile(filename, []byte("Oh, a XSS attack?"), 0o644)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
_, err = w.Add("Home.md")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
_, err = w.Commit("Yay XSS", &gogit.CommitOptions{
|
||||||
|
Author: &object.Signature{
|
||||||
|
Name: `Gusted<script class="evil">alert('Oh no!');</script>`,
|
||||||
|
Email: "valid@example.org",
|
||||||
|
When: time.Date(2024, time.January, 31, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Push.
|
||||||
|
_, _, err = git.NewCommand(git.DefaultContext, "push").AddArguments(git.ToTrustedCmdArgs([]string{"origin", "master"})...).RunStdString(&git.RunOpts{Dir: dstPath})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Check on page view.
|
||||||
|
t.Run("Page view", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
req := NewRequest(t, http.MethodGet, "/user2/repo1/wiki/Home")
|
||||||
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||||
|
|
||||||
|
htmlDoc.AssertElement(t, "script.evil", false)
|
||||||
|
assert.Contains(t, htmlDoc.Find(".ui.sub.header").Text(), `Gusted<script class="evil">alert('Oh no!');</script> edited this page 2024-01-31`)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Check on revisions page.
|
||||||
|
t.Run("Revision page", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
req := NewRequest(t, http.MethodGet, "/user2/repo1/wiki/Home?action=_revision")
|
||||||
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||||
|
|
||||||
|
htmlDoc.AssertElement(t, "script.evil", false)
|
||||||
|
assert.Contains(t, htmlDoc.Find(".ui.sub.header").Text(), `Gusted<script class="evil">alert('Oh no!');</script> edited this page 2024-01-31`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue