forked from NYANDEV/forgejo
7798a3d746
- Currently the repository description uses the same sanitizer as a normal markdown document. This means that element such as heading and images are allowed and can be abused. - Create a minimal restricted sanitizer for the repository description, which only allows what the postprocessor currently allows, which are links and emojis. - Added unit testing. - Resolves https://codeberg.org/forgejo/forgejo/issues/1202 - Resolves https://codeberg.org/Codeberg/Community/issues/1122 (cherry picked from commit a8afa4cd181d7c31f73d6a8fae4c6a4b9622a425) (cherry picked from commit 0238587c51e2c749413ca5a63e47590399fe5a2b) (cherry picked from commit a8c7bbf728326b992e000a3d19c8833610f960c9) (cherry picked from commit 80e05a8245092b4158c6c970ca0563181b40f2eb) (cherry picked from commit f5af5050b34891ff16a4ef1f8e3d805fe135238d) (cherry picked from commit 608f981e551db5f38550b622646cc307fe0566b9) (cherry picked from commit f40cff9263c628b634d846511d1274b4257ac90b) (cherry picked from commit 5f113bb61115074bb48f314f71075e228e207bf9)
105 lines
5.3 KiB
Go
105 lines
5.3 KiB
Go
// Copyright 2017 The Gitea Authors. All rights reserved.
|
|
// Copyright 2017 The Gogs Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package markup
|
|
|
|
import (
|
|
"html/template"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func Test_Sanitizer(t *testing.T) {
|
|
NewSanitizer()
|
|
testCases := []string{
|
|
// Regular
|
|
`<a onblur="alert(secret)" href="http://www.google.com">Google</a>`, `<a href="http://www.google.com" rel="nofollow">Google</a>`,
|
|
|
|
// Code highlighting class
|
|
`<code class="random string"></code>`, `<code></code>`,
|
|
`<code class="language-random ui tab active menu attached animating sidebar following bar center"></code>`, `<code></code>`,
|
|
`<code class="language-go"></code>`, `<code class="language-go"></code>`,
|
|
|
|
// Input checkbox
|
|
`<input type="hidden">`, ``,
|
|
`<input type="checkbox">`, `<input type="checkbox">`,
|
|
`<input checked disabled autofocus>`, `<input checked="" disabled="">`,
|
|
|
|
// Code highlight injection
|
|
`<code class="language-random ui tab active menu attached animating sidebar following bar center"></code>`, `<code></code>`,
|
|
`<code class="language-lol ui tab active menu attached animating sidebar following bar center">
|
|
<code class="language-lol ui container input huge basic segment center"> </code>
|
|
<img src="https://try.gogs.io/img/favicon.png" width="200" height="200">
|
|
<code class="language-lol ui container input massive basic segment">Hello there! Something has gone wrong, we are working on it.</code>
|
|
<code class="language-lol ui container input huge basic segment">In the meantime, play a game with us at <a href="http://example.com/">example.com</a>.</code>
|
|
</code>`, "<code>\n<code>\u00a0</code>\n<img src=\"https://try.gogs.io/img/favicon.png\" width=\"200\" height=\"200\">\n<code>Hello there! Something has gone wrong, we are working on it.</code>\n<code>In the meantime, play a game with us at\u00a0<a href=\"http://example.com/\" rel=\"nofollow\">example.com</a>.</code>\n</code>",
|
|
|
|
// <kbd> tags
|
|
`<kbd>Ctrl + C</kbd>`, `<kbd>Ctrl + C</kbd>`,
|
|
`<i class="dropdown icon">NAUGHTY</i>`, `<i>NAUGHTY</i>`,
|
|
`<i class="icon dropdown"></i>`, `<i class="icon dropdown"></i>`,
|
|
`<input type="checkbox" disabled=""/>unchecked`, `<input type="checkbox" disabled=""/>unchecked`,
|
|
`<span class="emoji dropdown">NAUGHTY</span>`, `<span>NAUGHTY</span>`,
|
|
`<span class="emoji">contents</span>`, `<span class="emoji">contents</span>`,
|
|
|
|
// Color property
|
|
`<span style="color: red">Hello World</span>`, `<span style="color: red">Hello World</span>`,
|
|
`<p style="color: red">Hello World</p>`, `<p style="color: red">Hello World</p>`,
|
|
`<code style="color: red">Hello World</code>`, `<code>Hello World</code>`,
|
|
`<span style="bad-color: red">Hello World</span>`, `<span>Hello World</span>`,
|
|
`<p style="bad-color: red">Hello World</p>`, `<p>Hello World</p>`,
|
|
`<code style="bad-color: red">Hello World</code>`, `<code>Hello World</code>`,
|
|
|
|
// Org mode status of list items.
|
|
`<li class="checked"></li>`, `<li class="checked"></li>`,
|
|
`<li class="unchecked"></li>`, `<li class="unchecked"></li>`,
|
|
`<li class="indeterminate"></li>`, `<li class="indeterminate"></li>`,
|
|
|
|
// URLs
|
|
`<a href="cbthunderlink://somebase64string)">my custom URL scheme</a>`, `<a href="cbthunderlink://somebase64string)" rel="nofollow">my custom URL scheme</a>`,
|
|
`<a href="matrix:roomid/psumPMeAfzgAeQpXMG:feneas.org?action=join">my custom URL scheme</a>`, `<a href="matrix:roomid/psumPMeAfzgAeQpXMG:feneas.org?action=join" rel="nofollow">my custom URL scheme</a>`,
|
|
|
|
// Disallow dangerous url schemes
|
|
`<a href="javascript:alert('xss')">bad</a>`, `bad`,
|
|
`<a href="vbscript:no">bad</a>`, `bad`,
|
|
`<a href="data:1234">bad</a>`, `bad`,
|
|
}
|
|
|
|
for i := 0; i < len(testCases); i += 2 {
|
|
assert.Equal(t, testCases[i+1], Sanitize(testCases[i]))
|
|
}
|
|
}
|
|
|
|
func TestDescriptionSanitizer(t *testing.T) {
|
|
NewSanitizer()
|
|
|
|
testCases := []string{
|
|
`<h1>Title</h1>`, `Title`,
|
|
`<img src='img.png' alt='image'>`, ``,
|
|
`<span class="emoji" aria-label="thumbs up">THUMBS UP</span>`, `<span class="emoji" aria-label="thumbs up">THUMBS UP</span>`,
|
|
`<span style="color: red">Hello World</span>`, `<span>Hello World</span>`,
|
|
`<br>`, ``,
|
|
`<a href="https://example.com" target="_blank" rel="noopener noreferrer">https://example.com</a>`, `<a href="https://example.com" target="_blank" rel="noopener noreferrer">https://example.com</a>`,
|
|
`<mark>Important!</mark>`, `Important!`,
|
|
`<details>Click me! <summary>Nothing to see here.</summary></details>`, `Click me! Nothing to see here.`,
|
|
`<input type="hidden">`, ``,
|
|
`<b>I</b> have a <i>strong</i> <strong>opinion</strong> about <em>this</em>.`, `<b>I</b> have a <i>strong</i> <strong>opinion</strong> about <em>this</em>.`,
|
|
`Provides alternative <code>wg(8)</code> tool`, `Provides alternative <code>wg(8)</code> tool`,
|
|
}
|
|
|
|
for i := 0; i < len(testCases); i += 2 {
|
|
assert.Equal(t, testCases[i+1], SanitizeDescription(testCases[i]))
|
|
}
|
|
}
|
|
|
|
func TestSanitizeNonEscape(t *testing.T) {
|
|
descStr := "<scrİpt><script>alert(document.domain)</script></scrİpt>"
|
|
|
|
output := template.HTML(Sanitize(descStr))
|
|
if strings.Contains(string(output), "<script>") {
|
|
t.Errorf("un-escaped <script> in output: %q", output)
|
|
}
|
|
}
|