From f5ce2ed292a90041abd749a8db26671645648a43 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Fri, 19 May 2023 18:17:07 +0300 Subject: [PATCH] Allow all URL schemes in Markdown links by default (#24805) - Closes #21146 - Closes #16721 ## :warning: BREAKING :warning: This changes the default behavior to now create links for any URL scheme when the user uses the markdown form for links (`[label](URL)`), this doesn't affect the rendering of inline links. To opt-out set the `markdown.CUSTOM_URL_SCHEMES` setting to a list of allowed schemes, all other schemes (except `http` and `https`) won't be allowed. # Before ![image](https://github.com/go-gitea/gitea/assets/20454870/35fa18ce-7dda-4995-b5b3-3f360f38296d) # After ![image](https://github.com/go-gitea/gitea/assets/20454870/0922216b-0b35-4b77-9919-21a5c21dd5d0) --------- Signed-off-by: Yarden Shoham Co-authored-by: Giteabot --- custom/conf/app.example.ini | 1 + .../doc/administration/config-cheat-sheet.en-us.md | 2 +- go.mod | 5 ++--- go.sum | 8 ++++---- modules/markup/sanitizer.go | 7 ++++++- modules/markup/sanitizer_test.go | 4 ++++ 6 files changed, 18 insertions(+), 9 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 9046f54734..91d829c0ca 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1327,6 +1327,7 @@ ROUTER = console ;; Comma separated list of custom URL-Schemes that are allowed as links when rendering Markdown ;; for example git,magnet,ftp (more at https://en.wikipedia.org/wiki/List_of_URI_schemes) ;; URLs starting with http and https are always displayed, whatever is put in this entry. +;; If this entry is empty, all URL schemes are allowed. ;CUSTOM_URL_SCHEMES = ;; ;; List of file extensions that should be rendered/edited as Markdown diff --git a/docs/content/doc/administration/config-cheat-sheet.en-us.md b/docs/content/doc/administration/config-cheat-sheet.en-us.md index 5bf5d6fbf9..fdd1235f89 100644 --- a/docs/content/doc/administration/config-cheat-sheet.en-us.md +++ b/docs/content/doc/administration/config-cheat-sheet.en-us.md @@ -276,7 +276,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a trailing whitespace to paragraphs is not necessary to force a line break. - `CUSTOM_URL_SCHEMES`: Use a comma separated list (ftp,git,svn) to indicate additional URL hyperlinks to be rendered in Markdown. URLs beginning in http and https are - always displayed + always displayed. If this entry is empty, all URL schemes are allowed - `FILE_EXTENSIONS`: **.md,.markdown,.mdown,.mkd,.livemd**: List of file extensions that should be rendered/edited as Markdown. Separate the extensions with a comma. To render files without any extension as markdown, just put a comma. - `ENABLE_MATH`: **true**: Enables detection of `\(...\)`, `\[...\]`, `$...$` and `$$...$$` blocks as math blocks. diff --git a/go.mod b/go.mod index 24765df181..93b8052daf 100644 --- a/go.mod +++ b/go.mod @@ -76,7 +76,7 @@ require ( github.com/mattn/go-sqlite3 v1.14.16 github.com/meilisearch/meilisearch-go v0.24.0 github.com/mholt/archiver/v3 v3.5.1 - github.com/microcosm-cc/bluemonday v1.0.23 + github.com/microcosm-cc/bluemonday v1.0.24 github.com/minio/minio-go/v7 v7.0.52 github.com/minio/sha256-simd v1.0.0 github.com/msteinert/pam v1.1.0 @@ -109,7 +109,7 @@ require ( github.com/yuin/goldmark-meta v1.1.0 golang.org/x/crypto v0.8.0 golang.org/x/image v0.7.0 - golang.org/x/net v0.9.0 + golang.org/x/net v0.10.0 golang.org/x/oauth2 v0.7.0 golang.org/x/sys v0.8.0 golang.org/x/text v0.9.0 @@ -288,7 +288,6 @@ require ( go.uber.org/zap v1.24.0 // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/sync v0.2.0 // indirect - golang.org/x/term v0.8.0 // indirect golang.org/x/time v0.3.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect diff --git a/go.sum b/go.sum index 62c01c690a..8e5b728aac 100644 --- a/go.sum +++ b/go.sum @@ -876,8 +876,8 @@ github.com/mholt/acmez v1.1.0 h1:IQ9CGHKOHokorxnffsqDvmmE30mDenO1lptYZ1AYkHY= github.com/mholt/acmez v1.1.0/go.mod h1:zwo5+fbLLTowAX8o8ETfQzbDtwGEXnPhkmGdKIP+bgs= github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo= github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= -github.com/microcosm-cc/bluemonday v1.0.23 h1:SMZe2IGa0NuHvnVNAZ+6B38gsTbi5e4sViiWJyDDqFY= -github.com/microcosm-cc/bluemonday v1.0.23/go.mod h1:mN70sk7UkkF8TUr2IGBpNN0jAgStuPzlK76QuruE/z4= +github.com/microcosm-cc/bluemonday v1.0.24 h1:NGQoPtwGVcbGkKfvyYk1yRqknzBuoMiUrO6R7uFTPlw= +github.com/microcosm-cc/bluemonday v1.0.24/go.mod h1:ArQySAMps0790cHSkdPEJ7bGkF2VePWH773hsJNSHf8= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= @@ -1418,8 +1418,9 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1543,7 +1544,6 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/modules/markup/sanitizer.go b/modules/markup/sanitizer.go index 600ccbf3c6..a0c9ee171f 100644 --- a/modules/markup/sanitizer.go +++ b/modules/markup/sanitizer.go @@ -22,7 +22,10 @@ type Sanitizer struct { init sync.Once } -var sanitizer = &Sanitizer{} +var ( + sanitizer = &Sanitizer{} + allowAllRegex = regexp.MustCompile(".+") +) // NewSanitizer initializes sanitizer with allowed attributes based on settings. // Multiple calls to this function will only create one instance of Sanitizer during @@ -74,6 +77,8 @@ func createDefaultPolicy() *bluemonday.Policy { // Custom URL-Schemes if len(setting.Markdown.CustomURLSchemes) > 0 { policy.AllowURLSchemes(setting.Markdown.CustomURLSchemes...) + } else { + policy.AllowURLSchemesMatching(allowAllRegex) } // Allow classes for anchors diff --git a/modules/markup/sanitizer_test.go b/modules/markup/sanitizer_test.go index c792ec2dc6..0c22ce3ba0 100644 --- a/modules/markup/sanitizer_test.go +++ b/modules/markup/sanitizer_test.go @@ -52,6 +52,10 @@ func Test_Sanitizer(t *testing.T) { `Hello World`, `Hello World`, `

Hello World

`, `

Hello World

`, `Hello World`, `Hello World`, + + // URLs + `[my custom URL scheme](cbthunderlink://somebase64string)`, `[my custom URL scheme](cbthunderlink://somebase64string)`, + `[my custom URL scheme](matrix:roomid/psumPMeAfzgAeQpXMG:feneas.org?action=join)`, `[my custom URL scheme](matrix:roomid/psumPMeAfzgAeQpXMG:feneas.org?action=join)`, } for i := 0; i < len(testCases); i += 2 {