Skip to content

Commit 14ce7f3

Browse files
jhildenbiddlesy-recordsKoooooo-7
authored
fix: Prevent loading remote content via URL hash (#1489)
* Prevent loading remote content via URL hash Fixes #1477. Fixes #1126. * Restore ability to execute remote content scripts Co-authored-by: 沈唁 <52o@qq52o.cn> Co-authored-by: Koy <koy@ko8e24.top>
1 parent 8968a74 commit 14ce7f3

File tree

3 files changed

+49
-36
lines changed

3 files changed

+49
-36
lines changed

packages/docsify-server-renderer/index.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ export default class Renderer {
123123
this._renderHtml('cover', await this._render(coverFile), 'cover');
124124
}
125125

126-
const html = this.isRemoteUrl ? DOMPurify.sanitize(this.html) : this.html;
126+
const html = this.isRemoteUrl
127+
? DOMPurify.sanitize(this.html, { ADD_TAGS: ['script'] })
128+
: this.html;
127129
this.html = this.template;
128130
return html;
129131
}

src/core/fetch/index.js

+43-34
Original file line numberDiff line numberDiff line change
@@ -102,41 +102,50 @@ export function fetchMixin(proto) {
102102
};
103103

104104
proto._fetch = function(cb = noop) {
105-
const { path, query } = this.route;
106-
const qs = stringifyQuery(query, ['id']);
107-
const { loadNavbar, requestHeaders, loadSidebar } = this.config;
108-
// Abort last request
109-
110-
const file = this.router.getFile(path);
111-
const req = request(file + qs, true, requestHeaders);
112-
113-
this.isRemoteUrl = isExternal(file);
114-
// Current page is html
115-
this.isHTML = /\.html$/g.test(file);
116-
117-
// Load main content
118-
req.then(
119-
(text, opt) =>
120-
this._renderMain(
121-
text,
122-
opt,
123-
this._loadSideAndNav(path, qs, loadSidebar, cb)
124-
),
125-
_ => {
126-
this._fetchFallbackPage(path, qs, cb) || this._fetch404(file, qs, cb);
127-
}
128-
);
129-
130-
// Load nav
131-
loadNavbar &&
132-
loadNested(
133-
path,
134-
qs,
135-
loadNavbar,
136-
text => this._renderNav(text),
137-
this,
138-
true
105+
const { query } = this.route;
106+
let { path } = this.route;
107+
108+
// Prevent loading remote content via URL hash
109+
// Ex: https://foo.com/#//bar.com/file.md
110+
if (isExternal(path)) {
111+
history.replaceState(null, '', '#');
112+
this.router.normalize();
113+
} else {
114+
const qs = stringifyQuery(query, ['id']);
115+
const { loadNavbar, requestHeaders, loadSidebar } = this.config;
116+
// Abort last request
117+
118+
const file = this.router.getFile(path);
119+
const req = request(file + qs, true, requestHeaders);
120+
121+
this.isRemoteUrl = isExternal(file);
122+
// Current page is html
123+
this.isHTML = /\.html$/g.test(file);
124+
125+
// Load main content
126+
req.then(
127+
(text, opt) =>
128+
this._renderMain(
129+
text,
130+
opt,
131+
this._loadSideAndNav(path, qs, loadSidebar, cb)
132+
),
133+
_ => {
134+
this._fetchFallbackPage(path, qs, cb) || this._fetch404(file, qs, cb);
135+
}
139136
);
137+
138+
// Load nav
139+
loadNavbar &&
140+
loadNested(
141+
path,
142+
qs,
143+
loadNavbar,
144+
text => this._renderNav(text),
145+
this,
146+
true
147+
);
148+
}
140149
};
141150

142151
proto._fetchCover = function() {

src/core/render/index.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,9 @@ export function renderMixin(proto) {
330330
},
331331
tokens => {
332332
html = this.compiler.compile(tokens);
333-
html = this.isRemoteUrl ? DOMPurify.sanitize(html) : html;
333+
html = this.isRemoteUrl
334+
? DOMPurify.sanitize(html, { ADD_TAGS: ['script'] })
335+
: html;
334336
callback();
335337
next();
336338
}

0 commit comments

Comments
 (0)