From 2d5936817a9377868c341d5ea4ee8ea01632eb7b Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 30 Jun 2022 16:01:09 +0800 Subject: [PATCH 1/8] Add new RENDER_CONTENT_MODE value iframe-allow-same-origin to allow load html --- custom/conf/app.example.ini | 1 + modules/markup/external/external.go | 9 ++- modules/markup/renderer.go | 95 ++++++++++++++++------------- modules/setting/markup.go | 10 +-- routers/web/repo/render.go | 32 +++++++--- 5 files changed, 90 insertions(+), 57 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 3646dfc71e844..7314fa533f360 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -2174,6 +2174,7 @@ PATH = ;; * sanitized: Sanitize the content and render it inside current page, default to only allow a few HTML tags and attributes. Customized sanitizer rules can be defined in [markup.sanitizer.*] . ;; * no-sanitizer: Disable the sanitizer and render the content inside current page. It's **insecure** and may lead to XSS attack if the content contains malicious code. ;; * iframe: Render the content in a separate standalone page and embed it into current page by iframe. The iframe is in sandbox mode with same-origin disabled, and the JS code are safely isolated from parent page. +;; * iframe-allow-same-origin: Render the content in a separate standalone page and embed it into current page by iframe. The iframe is in sandbox mode with same-origin enabled so don't use this except you know what it means. ;RENDER_CONTENT_MODE=sanitized ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/modules/markup/external/external.go b/modules/markup/external/external.go index 23dd45ba0a1f2..17e33f5082d26 100644 --- a/modules/markup/external/external.go +++ b/modules/markup/external/external.go @@ -61,7 +61,9 @@ func (p *Renderer) SanitizerRules() []setting.MarkupSanitizerRule { // SanitizerDisabled disabled sanitize if return true func (p *Renderer) SanitizerDisabled() bool { - return p.RenderContentMode == setting.RenderContentModeNoSanitizer || p.RenderContentMode == setting.RenderContentModeIframe + return p.RenderContentMode == setting.RenderContentModeNoSanitizer || + p.RenderContentMode == setting.RenderContentModeIframe || + p.RenderContentMode == setting.RenderContentModeIframeAllowSameOrigin } // DisplayInIFrame represents whether render the content with an iframe @@ -69,6 +71,11 @@ func (p *Renderer) DisplayInIFrame() bool { return p.RenderContentMode == setting.RenderContentModeIframe } +// AllowSameOrigin represents whether render allow same origin +func (p *Renderer) AllowSameOrigin() bool { + return p.RenderContentMode == setting.RenderContentModeIframeAllowSameOrigin +} + func envMark(envName string) string { if runtime.GOOS == "windows" { return "%" + envName + "%" diff --git a/modules/markup/renderer.go b/modules/markup/renderer.go index e88fa311875d5..ccbccf050b65a 100644 --- a/modules/markup/renderer.go +++ b/modules/markup/renderer.go @@ -44,18 +44,17 @@ type Header struct { // RenderContext represents a render context type RenderContext struct { - Ctx context.Context - RelativePath string // relative path from tree root of the branch - Type string - IsWiki bool - URLPrefix string - Metas map[string]string - DefaultLink string - GitRepo *git.Repository - ShaExistCache map[string]bool - cancelFn func() - TableOfContents []Header - InStandalonePage bool // used by external render. the router "/org/repo/render/..." will output the rendered content in a standalone page + Ctx context.Context + RelativePath string // relative path from tree root of the branch + Type string + IsWiki bool + URLPrefix string + Metas map[string]string + DefaultLink string + GitRepo *git.Repository + ShaExistCache map[string]bool + cancelFn func() + TableOfContents []Header } // Cancel runs any cleanup functions that have been registered for this Ctx @@ -106,6 +105,9 @@ type ExternalRenderer interface { // DisplayInIFrame represents whether render the content with an iframe DisplayInIFrame() bool + + // AllowSameOrigin represents whether render allow same origin + AllowSameOrigin() bool } // RendererContentDetector detects if the content can be rendered @@ -152,14 +154,39 @@ func DetectRendererType(filename string, input io.Reader) string { return "" } +// GetRenderer returned the renderer according type or relativepath +func GetRenderer(tp, relativePath string) (Renderer, error) { + if tp != "" { + if renderer, ok := renderers[tp]; ok { + return renderer, nil + } + return nil, ErrUnsupportedRenderType{tp} + } + + if relativePath != "" { + extension := strings.ToLower(filepath.Ext(relativePath)) + if renderer, ok := extRenderers[extension]; ok { + return renderer, nil + } + return nil, ErrUnsupportedRenderExtension{extension} + } + return nil, errors.New("Render options both filename and type missing") +} + // Render renders markup file to HTML with all specific handling stuff. func Render(ctx *RenderContext, input io.Reader, output io.Writer) error { - if ctx.Type != "" { - return renderByType(ctx, input, output) - } else if ctx.RelativePath != "" { - return renderFile(ctx, input, output) + renderer, err := GetRenderer(ctx.Type, ctx.RelativePath) + if err != nil { + return err + } + + if r, ok := renderer.(ExternalRenderer); ok && (r.DisplayInIFrame() || r.AllowSameOrigin()) { + // for an external render, it could only output its content in a standalone page + // otherwise, a `, setting.AppSubURL, url.PathEscape(ctx.Metas["user"]), url.PathEscape(ctx.Metas["repo"]), ctx.Metas["BranchNameSubURL"], url.PathEscape(ctx.RelativePath), + allowSameOriginStr, )) return err } -func render(ctx *RenderContext, renderer Renderer, input io.Reader, output io.Writer) error { +// RenderDirect renders markup file to HTML with all specific handling stuff. +func RenderDirect(ctx *RenderContext, renderer Renderer, input io.Reader, output io.Writer) error { var wg sync.WaitGroup var err error pr, pw := io.Pipe() @@ -262,13 +295,6 @@ func (err ErrUnsupportedRenderType) Error() string { return fmt.Sprintf("Unsupported render type: %s", err.Type) } -func renderByType(ctx *RenderContext, input io.Reader, output io.Writer) error { - if renderer, ok := renderers[ctx.Type]; ok { - return render(ctx, renderer, input, output) - } - return ErrUnsupportedRenderType{ctx.Type} -} - // ErrUnsupportedRenderExtension represents the error when extension doesn't supported to render type ErrUnsupportedRenderExtension struct { Extension string @@ -278,21 +304,6 @@ func (err ErrUnsupportedRenderExtension) Error() string { return fmt.Sprintf("Unsupported render extension: %s", err.Extension) } -func renderFile(ctx *RenderContext, input io.Reader, output io.Writer) error { - extension := strings.ToLower(filepath.Ext(ctx.RelativePath)) - if renderer, ok := extRenderers[extension]; ok { - if r, ok := renderer.(ExternalRenderer); ok && r.DisplayInIFrame() { - if !ctx.InStandalonePage { - // for an external render, it could only output its content in a standalone page - // otherwise, a `, setting.AppSubURL, url.PathEscape(ctx.Metas["user"]), url.PathEscape(ctx.Metas["repo"]), ctx.Metas["BranchNameSubURL"], url.PathEscape(ctx.RelativePath), - allowSameOriginStr, + iframeSandbox, )) return err } diff --git a/modules/setting/markup.go b/modules/setting/markup.go index ced2d1a5304cc..af79d6fb1ff94 100644 --- a/modules/setting/markup.go +++ b/modules/setting/markup.go @@ -21,22 +21,23 @@ var ( ) const ( - RenderContentModeSanitized = "sanitized" - RenderContentModeNoSanitizer = "no-sanitizer" - RenderContentModeIframe = "iframe" - RenderContentModeIframeAllowSameOrigin = "iframe-allow-same-origin" + RenderContentModeSanitized = "sanitized" + RenderContentModeNoSanitizer = "no-sanitizer" + RenderContentModeIframe = "iframe" ) // MarkupRenderer defines the external parser configured in ini type MarkupRenderer struct { - Enabled bool - MarkupName string - Command string - FileExtensions []string - IsInputFile bool - NeedPostProcess bool - MarkupSanitizerRules []MarkupSanitizerRule - RenderContentMode string + Enabled bool + MarkupName string + Command string + FileExtensions []string + IsInputFile bool + NeedPostProcess bool + MarkupSanitizerRules []MarkupSanitizerRule + RenderContentMode string + RenderContentIframeSandbox string // allow-scripts + RenderContentExternalCSP string } // MarkupSanitizerRule defines the policy for whitelisting attributes on @@ -159,21 +160,23 @@ func newMarkupRenderer(name string, sec *ini.Section) { if !sec.HasKey("RENDER_CONTENT_MODE") && sec.Key("DISABLE_SANITIZER").MustBool(false) { renderContentMode = RenderContentModeNoSanitizer // if only the legacy DISABLE_SANITIZER exists, use it } + if renderContentMode != RenderContentModeSanitized && renderContentMode != RenderContentModeNoSanitizer && - renderContentMode != RenderContentModeIframe && - renderContentMode != RenderContentModeIframeAllowSameOrigin { + renderContentMode != RenderContentModeIframe { log.Error("invalid RENDER_CONTENT_MODE: %q, default to %q", renderContentMode, RenderContentModeSanitized) renderContentMode = RenderContentModeSanitized } ExternalMarkupRenderers = append(ExternalMarkupRenderers, &MarkupRenderer{ - Enabled: sec.Key("ENABLED").MustBool(false), - MarkupName: name, - FileExtensions: exts, - Command: command, - IsInputFile: sec.Key("IS_INPUT_FILE").MustBool(false), - NeedPostProcess: sec.Key("NEED_POSTPROCESS").MustBool(true), - RenderContentMode: renderContentMode, + Enabled: sec.Key("ENABLED").MustBool(false), + MarkupName: name, + FileExtensions: exts, + Command: command, + IsInputFile: sec.Key("IS_INPUT_FILE").MustBool(false), + NeedPostProcess: sec.Key("NEED_POSTPROCESS").MustBool(true), + RenderContentMode: renderContentMode, + RenderContentIframeSandbox: sec.Key("RENDER_CONTENT_IFRAME_SANDBOX").MustString("allow-scripts"), + RenderContentExternalCSP: sec.Key("RENDER_CONTENT_EXTERNAL_CSP").MustString("sandbox allow-scripts"), }) } diff --git a/routers/web/repo/render.go b/routers/web/repo/render.go index 15c47445b81ef..b2abf45051274 100644 --- a/routers/web/repo/render.go +++ b/routers/web/repo/render.go @@ -72,11 +72,11 @@ func RenderFile(ctx *context.Context) { return } - if r, ok := renderer.(markup.ExternalRenderer); ok && r.AllowSameOrigin() { - allowSameOriginStr = " allow-same-origin" + if r, ok := renderer.(markup.ExternalRenderer); ok { + allowSameOriginStr = r.ExternalCSP() } - ctx.Resp.Header().Add("Content-Security-Policy", fmt.Sprintf("frame-src 'self'; sandbox%s allow-scripts", allowSameOriginStr)) + ctx.Resp.Header().Add("Content-Security-Policy", fmt.Sprintf("frame-src 'self'; %s", allowSameOriginStr)) if err = markup.RenderDirect(&markup.RenderContext{ Ctx: ctx, From eecfe9b5118916644de15a4714e75b20f6a7f8e9 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 1 Aug 2022 20:31:40 +0800 Subject: [PATCH 3/8] fix --- custom/conf/app.example.ini | 6 +- .../doc/advanced/config-cheat-sheet.en-us.md | 4 +- modules/markup/renderer.go | 32 ++++++++--- modules/setting/markup.go | 4 +- routers/web/repo/render.go | 57 +++++++------------ 5 files changed, 49 insertions(+), 54 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 1ea9f2d782eb9..06fedb81fb12c 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -2182,10 +2182,10 @@ ROUTER = console ;; * no-sanitizer: Disable the sanitizer and render the content inside current page. It's **insecure** and may lead to XSS attack if the content contains malicious code. ;; * iframe: Render the content in a separate standalone page and embed it into current page by iframe. The iframe is in sandbox mode with same-origin disabled, and the JS code are safely isolated from parent page. ;RENDER_CONTENT_MODE=sanitized -;; when RENDER_CONTENT_MODE is iframe, below two items will be avaible ;; -;RENDER_CONTENT_IFRAME_SANDBOX=allow-scripts -;RENDER_CONTENT_EXTERNAL_CSP=sandbox allow-scripts +;; When RENDER_CONTENT_MODE is iframe, these two options are available +;RENDER_CONTENT_IFRAME_SANDBOX="allow-scripts" +;RENDER_CONTENT_EXTERNAL_CSP="iframe-src 'self'; sandbox allow-scripts" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 292af5f7da8f0..f1bbd49cfd244 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -1044,8 +1044,8 @@ IS_INPUT_FILE = false - sanitized: Sanitize the content and render it inside current page, default to only allow a few HTML tags and attributes. Customized sanitizer rules can be defined in `[markup.sanitizer.*]`. - no-sanitizer: Disable the sanitizer and render the content inside current page. It's **insecure** and may lead to XSS attack if the content contains malicious code. - iframe: Render the content in a separate standalone page and embed it into current page by iframe. The iframe is in sandbox mode with same-origin disabled, and the JS code are safely isolated from parent page. -- RENDER_CONTENT_IFRAME_SANDBOX: **allow-scripts** When `RENDER_CONTENT_MODE` is `iframe`, this will be the allowed sandbox of iframe properties. -- RENDER_CONTENT_EXTERNAL_CSP: **sandbox allow-scripts** When `RENDER_CONTENT_MODE` is `iframe`, this will be the allowed CSP of external renderer response. +- RENDER_CONTENT_IFRAME_SANDBOX: **"allow-scripts"** When `RENDER_CONTENT_MODE` is `iframe`, this will be the allowed sandbox of iframe properties. +- RENDER_CONTENT_EXTERNAL_CSP: **"iframe-src 'self'; sandbox allow-scripts"** When `RENDER_CONTENT_MODE` is `iframe`, this will be the allowed CSP of external renderer response. Two special environment variables are passed to the render command: diff --git a/modules/markup/renderer.go b/modules/markup/renderer.go index 6634fb7f55c04..d61a083dbb41d 100644 --- a/modules/markup/renderer.go +++ b/modules/markup/renderer.go @@ -55,6 +55,11 @@ type RenderContext struct { ShaExistCache map[string]bool cancelFn func() TableOfContents []Header + + // InStandalonePage is used by external render. the router "/org/repo/render/..." will output the rendered content in a standalone page + // It is for maintenance and security purpose, to avoid rendering external JS into embedded page unexpectedly. + // The caller of the Render must set security headers correctly before setting it to true + InStandalonePage bool } // Cancel runs any cleanup functions that have been registered for this Ctx @@ -98,7 +103,7 @@ type PostProcessRenderer interface { NeedPostProcess() bool } -// PostProcessRenderer defines an interface for external renderers +// ExternalRenderer defines an interface for external renderers type ExternalRenderer interface { // SanitizerDisabled disabled sanitize if return true SanitizerDisabled() bool @@ -106,10 +111,10 @@ type ExternalRenderer interface { // DisplayInIFrame represents whether render the content with an iframe DisplayInIFrame() bool - // IframeSandbox represents iframe sandbox allowed options + // IframeSandbox represents iframe sandbox attribute for the `, setting.AppSubURL, @@ -300,24 +285,6 @@ func RenderDirect(ctx *RenderContext, renderer Renderer, input io.Reader, output return err } -// ErrUnsupportedRenderType represents -type ErrUnsupportedRenderType struct { - Type string -} - -func (err ErrUnsupportedRenderType) Error() string { - return fmt.Sprintf("Unsupported render type: %s", err.Type) -} - -// ErrUnsupportedRenderExtension represents the error when extension doesn't supported to render -type ErrUnsupportedRenderExtension struct { - Extension string -} - -func (err ErrUnsupportedRenderExtension) Error() string { - return fmt.Sprintf("Unsupported render extension: %s", err.Extension) -} - // Type returns if markup format via the filename func Type(filename string) string { if parser := GetRendererByFileName(filename); parser != nil { diff --git a/modules/setting/markup.go b/modules/setting/markup.go index c74df43c6722f..5cbb13b7eacfd 100644 --- a/modules/setting/markup.go +++ b/modules/setting/markup.go @@ -177,6 +177,6 @@ func newMarkupRenderer(name string, sec *ini.Section) { NeedPostProcess: sec.Key("NEED_POSTPROCESS").MustBool(true), RenderContentMode: renderContentMode, RenderContentIframeSandbox: sec.Key("RENDER_CONTENT_IFRAME_SANDBOX").MustString("allow-scripts"), - RenderContentExternalCSP: sec.Key("RENDER_CONTENT_EXTERNAL_CSP").MustString("iframe-src 'self'; sandbox allow-scripts"), + RenderContentExternalCSP: sec.Key("RENDER_CONTENT_EXTERNAL_CSP").MustString("frame-src 'self'; sandbox allow-scripts"), }) } diff --git a/routers/web/repo/render.go b/routers/web/repo/render.go index 642e74bda8f93..2cd29b9c32626 100644 --- a/routers/web/repo/render.go +++ b/routers/web/repo/render.go @@ -38,9 +38,9 @@ func RenderFile(ctx *context.Context) { treeLink += "/" + util.PathEscapeSegments(ctx.Repo.TreePath) } - renderer, err := markup.GetRenderer("", ctx.Repo.TreePath) - if err != nil { - ctx.ServerError("GetRenderer", err) + renderer := markup.GetRendererByFileName(ctx.Repo.TreePath) + if renderer == nil { + ctx.Error(http.StatusBadRequest, "No renderer") return } From 779d8aeaef019af2814ae59faa8f7321ff8376c8 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 8 Aug 2022 17:07:58 +0800 Subject: [PATCH 6/8] perfect resize --- modules/markup/renderer.go | 43 ++++++++++++++++++++++++++++---------- routers/web/repo/render.go | 12 +++++++++++ 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/modules/markup/renderer.go b/modules/markup/renderer.go index f72316a1ee551..5f0fafc84255b 100644 --- a/modules/markup/renderer.go +++ b/modules/markup/renderer.go @@ -205,20 +205,41 @@ func renderIFrame(ctx *RenderContext, output io.Writer, iframeSandbox string) er // "allow-same-origin" should never be used, it leads to XSS attack, and it makes the JS in iframe can access parent window's config and CSRF token // when there is a strict CORS policy, the "onload" script can not read the loaded height at the moment. // TODO: when using dark theme, if the rendered content doesn't have proper style, the default text color is black, which is not easy to read - _, err := io.WriteString(output, fmt.Sprintf(` -`, - setting.AppSubURL, - url.PathEscape(ctx.Metas["user"]), - url.PathEscape(ctx.Metas["repo"]), - ctx.Metas["BranchNameSubURL"], - url.PathEscape(ctx.RelativePath), - html.EscapeString(iframeSandbox), - )) + setting.AppSubURL, + url.PathEscape(ctx.Metas["user"]), + url.PathEscape(ctx.Metas["repo"]), + ctx.Metas["BranchNameSubURL"], + url.PathEscape(ctx.RelativePath), + html.EscapeString(iframeSandbox), + )) return err } diff --git a/routers/web/repo/render.go b/routers/web/repo/render.go index 2cd29b9c32626..b59de71ec25dd 100644 --- a/routers/web/repo/render.go +++ b/routers/web/repo/render.go @@ -7,6 +7,7 @@ package repo import ( "net/http" "path" + "strings" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" @@ -57,6 +58,7 @@ func RenderFile(ctx *context.Context) { } ctx.Resp.Header().Add("Content-Security-Policy", externalCSP) + ctx.Resp.Header().Add("Content-Type", "text/html") if err = markup.RenderDirect(&markup.RenderContext{ Ctx: ctx, @@ -69,4 +71,14 @@ func RenderFile(ctx *context.Context) { ctx.ServerError("RenderDirect", err) return } + + if strings.HasPrefix(ctx.Resp.Header().Get("Content-Type"), "text/html") { + _, _ = ctx.Resp.Write([]byte(` + +`)) + } } From 73dde8bccf2aded45b187ea66e2f63847a47e99b Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 8 Aug 2022 18:36:14 +0800 Subject: [PATCH 7/8] fix open new window --- modules/setting/markup.go | 4 ++-- routers/web/repo/render.go | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/setting/markup.go b/modules/setting/markup.go index 5cbb13b7eacfd..18098f744c7bc 100644 --- a/modules/setting/markup.go +++ b/modules/setting/markup.go @@ -176,7 +176,7 @@ func newMarkupRenderer(name string, sec *ini.Section) { IsInputFile: sec.Key("IS_INPUT_FILE").MustBool(false), NeedPostProcess: sec.Key("NEED_POSTPROCESS").MustBool(true), RenderContentMode: renderContentMode, - RenderContentIframeSandbox: sec.Key("RENDER_CONTENT_IFRAME_SANDBOX").MustString("allow-scripts"), - RenderContentExternalCSP: sec.Key("RENDER_CONTENT_EXTERNAL_CSP").MustString("frame-src 'self'; sandbox allow-scripts"), + RenderContentIframeSandbox: sec.Key("RENDER_CONTENT_IFRAME_SANDBOX").MustString("allow-scripts allow-popups"), + RenderContentExternalCSP: sec.Key("RENDER_CONTENT_EXTERNAL_CSP").MustString("frame-src 'self'; sandbox allow-scripts allow-popups"), }) } diff --git a/routers/web/repo/render.go b/routers/web/repo/render.go index b59de71ec25dd..f8013649e5eb5 100644 --- a/routers/web/repo/render.go +++ b/routers/web/repo/render.go @@ -75,9 +75,17 @@ func RenderFile(ctx *context.Context) { if strings.HasPrefix(ctx.Resp.Header().Get("Content-Type"), "text/html") { _, _ = ctx.Resp.Write([]byte(` `)) } From 2c42c8a72077e28e4667fbc388a07ec87bce0d08 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 9 Aug 2022 10:37:38 +0800 Subject: [PATCH 8/8] Apply suggestions from code review --- custom/conf/app.example.ini | 2 +- docs/content/doc/advanced/config-cheat-sheet.en-us.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 06fedb81fb12c..3f0edf2c6641f 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -2185,7 +2185,7 @@ ROUTER = console ;; ;; When RENDER_CONTENT_MODE is iframe, these two options are available ;RENDER_CONTENT_IFRAME_SANDBOX="allow-scripts" -;RENDER_CONTENT_EXTERNAL_CSP="iframe-src 'self'; sandbox allow-scripts" +;RENDER_CONTENT_EXTERNAL_CSP="frame-src 'self'; sandbox allow-scripts" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index f1bbd49cfd244..c08960f50a6aa 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -1045,7 +1045,7 @@ IS_INPUT_FILE = false - no-sanitizer: Disable the sanitizer and render the content inside current page. It's **insecure** and may lead to XSS attack if the content contains malicious code. - iframe: Render the content in a separate standalone page and embed it into current page by iframe. The iframe is in sandbox mode with same-origin disabled, and the JS code are safely isolated from parent page. - RENDER_CONTENT_IFRAME_SANDBOX: **"allow-scripts"** When `RENDER_CONTENT_MODE` is `iframe`, this will be the allowed sandbox of iframe properties. -- RENDER_CONTENT_EXTERNAL_CSP: **"iframe-src 'self'; sandbox allow-scripts"** When `RENDER_CONTENT_MODE` is `iframe`, this will be the allowed CSP of external renderer response. +- RENDER_CONTENT_EXTERNAL_CSP: **"frame-src 'self'; sandbox allow-scripts"** When `RENDER_CONTENT_MODE` is `iframe`, this will be the allowed CSP of external renderer response. Two special environment variables are passed to the render command: