Skip to content

Commit de15e64

Browse files
committed
Use two different options when renderer in iframe
1 parent 8b113a4 commit de15e64

File tree

6 files changed

+52
-41
lines changed

6 files changed

+52
-41
lines changed

custom/conf/app.example.ini

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2177,8 +2177,11 @@ ROUTER = console
21772177
;; * 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.*] .
21782178
;; * 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.
21792179
;; * 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.
2180-
;; * 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.
21812180
;RENDER_CONTENT_MODE=sanitized
2181+
;; when RENDER_CONTENT_MODE is iframe, below two items will be avaible
2182+
;;
2183+
;RENDER_CONTENT_IFRAME_SANDBOX=allow-scripts
2184+
;RENDER_CONTENT_EXTERNAL_CSP=sandbox allow-scripts
21822185

21832186
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21842187
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

docs/content/doc/advanced/config-cheat-sheet.en-us.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,8 @@ IS_INPUT_FILE = false
10301030
- 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.*]`.
10311031
- 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.
10321032
- 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.
1033+
- RENDER_CONTENT_IFRAME_SANDBOX: **allow-scripts** When `RENDER_CONTENT_MODE` is `iframe`, this will be the allowed sandbox of iframe properties.
1034+
- RENDER_CONTENT_EXTERNAL_CSP: **sandbox allow-scripts** When `RENDER_CONTENT_MODE` is `iframe`, this will be the allowed CSP of external renderer response.
10331035

10341036
Two special environment variables are passed to the render command:
10351037
- `GITEA_PREFIX_SRC`, which contains the current URL prefix in the `src` path tree. To be used as prefix for links.

modules/markup/external/external.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,22 @@ func (p *Renderer) SanitizerRules() []setting.MarkupSanitizerRule {
6262
// SanitizerDisabled disabled sanitize if return true
6363
func (p *Renderer) SanitizerDisabled() bool {
6464
return p.RenderContentMode == setting.RenderContentModeNoSanitizer ||
65-
p.RenderContentMode == setting.RenderContentModeIframe ||
66-
p.RenderContentMode == setting.RenderContentModeIframeAllowSameOrigin
65+
p.RenderContentMode == setting.RenderContentModeIframe
6766
}
6867

6968
// DisplayInIFrame represents whether render the content with an iframe
7069
func (p *Renderer) DisplayInIFrame() bool {
7170
return p.RenderContentMode == setting.RenderContentModeIframe
7271
}
7372

74-
// AllowSameOrigin represents whether render allow same origin
75-
func (p *Renderer) AllowSameOrigin() bool {
76-
return p.RenderContentMode == setting.RenderContentModeIframeAllowSameOrigin
73+
// IframeSandbox represents iframe sandbox
74+
func (p *Renderer) IframeSandbox() string {
75+
return p.RenderContentIframeSandbox
76+
}
77+
78+
// ExternalCSP represents external render CSP
79+
func (p *Renderer) ExternalCSP() string {
80+
return p.RenderContentExternalCSP
7781
}
7882

7983
func envMark(envName string) string {

modules/markup/renderer.go

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,11 @@ type ExternalRenderer interface {
106106
// DisplayInIFrame represents whether render the content with an iframe
107107
DisplayInIFrame() bool
108108

109-
// AllowSameOrigin represents whether render allow same origin
110-
AllowSameOrigin() bool
109+
// IframeSandbox represents iframe sandbox allowed options
110+
IframeSandbox() string
111+
112+
// ExternalCSP represents external render CSP
113+
ExternalCSP() string
111114
}
112115

113116
// RendererContentDetector detects if the content can be rendered
@@ -180,10 +183,10 @@ func Render(ctx *RenderContext, input io.Reader, output io.Writer) error {
180183
return err
181184
}
182185

183-
if r, ok := renderer.(ExternalRenderer); ok && (r.DisplayInIFrame() || r.AllowSameOrigin()) {
186+
if r, ok := renderer.(ExternalRenderer); ok && r.DisplayInIFrame() {
184187
// for an external render, it could only output its content in a standalone page
185188
// otherwise, a <iframe> should be outputted to embed the external rendered page
186-
return renderIFrame(ctx, output, r.AllowSameOrigin())
189+
return renderIFrame(ctx, output, r.IframeSandbox())
187190
}
188191

189192
return RenderDirect(ctx, renderer, input, output)
@@ -204,11 +207,7 @@ type nopCloser struct {
204207

205208
func (nopCloser) Close() error { return nil }
206209

207-
func renderIFrame(ctx *RenderContext, output io.Writer, allowSameOrigin bool) error {
208-
var allowSameOriginStr string
209-
if allowSameOrigin {
210-
allowSameOriginStr = " allow-same-origin"
211-
}
210+
func renderIFrame(ctx *RenderContext, output io.Writer, iframeSandbox string) error {
212211
// set height="0" ahead, otherwise the scrollHeight would be max(150, realHeight)
213212
// at the moment, only "allow-scripts" is allowed for sandbox mode.
214213
// "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
@@ -218,14 +217,14 @@ func renderIFrame(ctx *RenderContext, output io.Writer, allowSameOrigin bool) er
218217
name="giteaExternalRender"
219218
onload="this.height=giteaExternalRender.document.documentElement.scrollHeight"
220219
width="100%%" height="0" scrolling="no" frameborder="0" style="overflow: hidden"
221-
sandbox="allow-scripts%s"
220+
sandbox="%s"
222221
></iframe>`,
223222
setting.AppSubURL,
224223
url.PathEscape(ctx.Metas["user"]),
225224
url.PathEscape(ctx.Metas["repo"]),
226225
ctx.Metas["BranchNameSubURL"],
227226
url.PathEscape(ctx.RelativePath),
228-
allowSameOriginStr,
227+
iframeSandbox,
229228
))
230229
return err
231230
}

modules/setting/markup.go

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,23 @@ var (
2121
)
2222

2323
const (
24-
RenderContentModeSanitized = "sanitized"
25-
RenderContentModeNoSanitizer = "no-sanitizer"
26-
RenderContentModeIframe = "iframe"
27-
RenderContentModeIframeAllowSameOrigin = "iframe-allow-same-origin"
24+
RenderContentModeSanitized = "sanitized"
25+
RenderContentModeNoSanitizer = "no-sanitizer"
26+
RenderContentModeIframe = "iframe"
2827
)
2928

3029
// MarkupRenderer defines the external parser configured in ini
3130
type MarkupRenderer struct {
32-
Enabled bool
33-
MarkupName string
34-
Command string
35-
FileExtensions []string
36-
IsInputFile bool
37-
NeedPostProcess bool
38-
MarkupSanitizerRules []MarkupSanitizerRule
39-
RenderContentMode string
31+
Enabled bool
32+
MarkupName string
33+
Command string
34+
FileExtensions []string
35+
IsInputFile bool
36+
NeedPostProcess bool
37+
MarkupSanitizerRules []MarkupSanitizerRule
38+
RenderContentMode string
39+
RenderContentIframeSandbox string // allow-scripts
40+
RenderContentExternalCSP string
4041
}
4142

4243
// MarkupSanitizerRule defines the policy for whitelisting attributes on
@@ -159,21 +160,23 @@ func newMarkupRenderer(name string, sec *ini.Section) {
159160
if !sec.HasKey("RENDER_CONTENT_MODE") && sec.Key("DISABLE_SANITIZER").MustBool(false) {
160161
renderContentMode = RenderContentModeNoSanitizer // if only the legacy DISABLE_SANITIZER exists, use it
161162
}
163+
162164
if renderContentMode != RenderContentModeSanitized &&
163165
renderContentMode != RenderContentModeNoSanitizer &&
164-
renderContentMode != RenderContentModeIframe &&
165-
renderContentMode != RenderContentModeIframeAllowSameOrigin {
166+
renderContentMode != RenderContentModeIframe {
166167
log.Error("invalid RENDER_CONTENT_MODE: %q, default to %q", renderContentMode, RenderContentModeSanitized)
167168
renderContentMode = RenderContentModeSanitized
168169
}
169170

170171
ExternalMarkupRenderers = append(ExternalMarkupRenderers, &MarkupRenderer{
171-
Enabled: sec.Key("ENABLED").MustBool(false),
172-
MarkupName: name,
173-
FileExtensions: exts,
174-
Command: command,
175-
IsInputFile: sec.Key("IS_INPUT_FILE").MustBool(false),
176-
NeedPostProcess: sec.Key("NEED_POSTPROCESS").MustBool(true),
177-
RenderContentMode: renderContentMode,
172+
Enabled: sec.Key("ENABLED").MustBool(false),
173+
MarkupName: name,
174+
FileExtensions: exts,
175+
Command: command,
176+
IsInputFile: sec.Key("IS_INPUT_FILE").MustBool(false),
177+
NeedPostProcess: sec.Key("NEED_POSTPROCESS").MustBool(true),
178+
RenderContentMode: renderContentMode,
179+
RenderContentIframeSandbox: sec.Key("RENDER_CONTENT_IFRAME_SANDBOX").MustString("allow-scripts"),
180+
RenderContentExternalCSP: sec.Key("RENDER_CONTENT_EXTERNAL_CSP").MustString("sandbox allow-scripts"),
178181
})
179182
}

routers/web/repo/render.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,11 @@ func RenderFile(ctx *context.Context) {
7272
return
7373
}
7474

75-
if r, ok := renderer.(markup.ExternalRenderer); ok && r.AllowSameOrigin() {
76-
allowSameOriginStr = " allow-same-origin"
75+
if r, ok := renderer.(markup.ExternalRenderer); ok {
76+
allowSameOriginStr = r.ExternalCSP()
7777
}
7878

79-
ctx.Resp.Header().Add("Content-Security-Policy", fmt.Sprintf("frame-src 'self'; sandbox%s allow-scripts", allowSameOriginStr))
79+
ctx.Resp.Header().Add("Content-Security-Policy", fmt.Sprintf("frame-src 'self'; %s", allowSameOriginStr))
8080

8181
if err = markup.RenderDirect(&markup.RenderContext{
8282
Ctx: ctx,

0 commit comments

Comments
 (0)