2017-04-13 02:52:24 +00:00
// Copyright 2017 The Gitea Authors. All rights reserved.
// Copyright 2017 The Gogs Authors. All rights reserved.
2022-11-27 18:20:29 +00:00
// SPDX-License-Identifier: MIT
2017-04-13 02:52:24 +00:00
2017-09-16 17:17:57 +00:00
package markup
2017-04-13 02:52:24 +00:00
import (
2021-04-05 21:38:31 +00:00
"html/template"
"strings"
2017-04-13 02:52:24 +00:00
"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" > & nbsp ; < / 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 & nbsp ; < 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>" ,
2019-12-03 19:02:41 +00:00
// <kbd> tags
` <kbd>Ctrl + C</kbd> ` , ` <kbd>Ctrl + C</kbd> ` ,
2020-05-03 20:17:24 +00:00
` <i class="dropdown icon">NAUGHTY</i> ` , ` <i>NAUGHTY</i> ` ,
` <i class="icon dropdown"></i> ` , ` <i class="icon dropdown"></i> ` ,
2020-12-13 01:05:50 +00:00
` <input type="checkbox" disabled=""/>unchecked ` , ` <input type="checkbox" disabled=""/>unchecked ` ,
2020-05-03 20:17:24 +00:00
` <span class="emoji dropdown">NAUGHTY</span> ` , ` <span>NAUGHTY</span> ` ,
` <span class="emoji">contents</span> ` , ` <span class="emoji">contents</span> ` ,
2022-07-15 06:38:10 +00:00
// Color property
` <span style="color: red">Hello World</span> ` , ` <span style="color: red">Hello World</span> ` ,
2024-07-31 18:48:46 +00:00
` <p style="color: red; background-color: red">Hello World</p> ` , ` <p style="color: red; background-color: red">Hello World</p> ` ,
` <table><tr><th style="color: red">TH1</th><th style="background-color: red">TH2</th><th style="color: red; background-color: red">TH3</th></tr><tr><td style="color: red">TD1</td><td style="background-color: red">TD2</td><td style="color: red; background-color: red">TD3</td></tr></table> ` , ` <table><tr><th style="color: red">TH1</th><th style="background-color: red">TH2</th><th style="color: red; background-color: red">TH3</th></tr><tr><td style="color: red">TD1</td><td style="background-color: red">TD2</td><td style="color: red; background-color: red">TD3</td></tr></table> ` ,
2022-07-15 06:38:10 +00:00
` <code style="color: red">Hello World</code> ` , ` <code>Hello World</code> ` ,
2024-07-31 18:48:46 +00:00
` <code style="background-color: red">Hello World</code> ` , ` <code>Hello World</code> ` ,
2022-07-15 06:38:10 +00:00
` <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> ` ,
2023-05-19 15:17:07 +00:00
2023-07-27 14:15:31 +00:00
// 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> ` ,
2023-05-19 15:17:07 +00:00
// URLs
2023-07-18 15:18:37 +00:00
` <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 ` ,
2024-10-23 23:07:53 +00:00
// Mention
` <a href="/org/forgejo/teams/UI" class="mention" rel="nofollow">@forgejo/UI</a> ` , ` <a href="/org/forgejo/teams/UI" class="mention" rel="nofollow">@forgejo/UI</a> ` ,
// Emoji
` <span class="emoji" aria-label="thumbs up" data-alias="+1">THUMBS UP</span> ` , ` <span class="emoji" aria-label="thumbs up" data-alias="+1">THUMBS UP</span> ` ,
` <span class="emoji" aria-label="thumbs up" data-alias="(+!)">THUMBS UP</span> ` , ` <span class="emoji" aria-label="thumbs up">THUMBS UP</span> ` ,
2017-04-13 02:52:24 +00:00
}
for i := 0 ; i < len ( testCases ) ; i += 2 {
assert . Equal ( t , testCases [ i + 1 ] , Sanitize ( testCases [ i ] ) )
}
}
2021-04-05 21:38:31 +00:00
2023-11-23 16:34:25 +00:00
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> ` , ` ` ,
2024-08-07 15:04:03 +00:00
` <a href="https://example.com" target="_blank" rel="noopener noreferrer">https://example.com</a> ` , ` <a href="https://example.com" target="_blank" rel="noopener noreferrer nofollow">https://example.com</a> ` ,
2023-11-23 16:34:25 +00:00
` <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 ` ,
2024-08-07 15:04:03 +00:00
` <a href="javascript:alert('xss')">Click me</a>. ` , ` Click me. ` ,
` <a href="data:text/html,<script>alert('xss')</script>">Click me</a>. ` , ` Click me. ` ,
` <a href="vbscript:msgbox("xss")">Click me</a>. ` , ` Click me. ` ,
2023-11-23 16:34:25 +00:00
}
for i := 0 ; i < len ( testCases ) ; i += 2 {
assert . Equal ( t , testCases [ i + 1 ] , SanitizeDescription ( testCases [ i ] ) )
}
}
2021-04-05 21:38:31 +00:00
func TestSanitizeNonEscape ( t * testing . T ) {
descStr := "<scrİpt><script>alert(document.domain)</script></scrİpt>"
2022-06-20 10:02:49 +00:00
output := template . HTML ( Sanitize ( descStr ) )
2021-04-05 21:38:31 +00:00
if strings . Contains ( string ( output ) , "<script>" ) {
t . Errorf ( "un-escaped <script> in output: %q" , output )
}
}