Skip to content

Commit b60707e

Browse files
Rollup merge of #120250 - chadnorvell:rustdoc-xss, r=notriddle
rustdoc: Prevent JS injection from localStorage It turns out that you can execute arbitrary JavaScript on the rustdocs settings page. Here's how: 1. Open `settings.html` on a rustdocs site. 2. Set "preferred light theme" to "dark" to initialize the corresponding localStorage value. 3. Plant a payload by executing this in your browser's dev console: ``Object.keys(localStorage).forEach(key=>localStorage.setItem(key,`javascript:alert()//*/javascript:javascript:"/*'/*\`/*--></noscript></title></textarea></style></template></noembed></script><html " onmouseover=/*&lt;svg/*/onload=alert()onload=alert()//><svg onload=alert()><svg onload=alert()>*/</style><script>alert()</script><style>`));`` 4. Refresh the page -- you should see an alert. This could be particularly dangerous if rustdocs are deployed on a domain hosting some other application. Malicious code could circumvent `same-origin` policies and do mischievous things with user data. This change ensures that only defined themes can actually be selected (arbitrary strings from localStorage will not be written to the document), and for good measure sanitizes the theme name.
2 parents d3d621b + 32a0afe commit b60707e

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

src/librustdoc/html/static/js/storage.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,14 @@ const getVar = (function getVar(name) {
101101
});
102102

103103
function switchTheme(newThemeName, saveTheme) {
104+
const themeNames = getVar("themes").split(",").filter(t => t);
105+
themeNames.push(...builtinThemes);
106+
107+
// Ensure that the new theme name is among the defined themes
108+
if (themeNames.indexOf(newThemeName) === -1) {
109+
return;
110+
}
111+
104112
// If this new value comes from a system setting or from the previously
105113
// saved theme, no need to save it.
106114
if (saveTheme) {
@@ -115,7 +123,7 @@ function switchTheme(newThemeName, saveTheme) {
115123
window.currentTheme = null;
116124
}
117125
} else {
118-
const newHref = getVar("root-path") + newThemeName +
126+
const newHref = getVar("root-path") + encodeURIComponent(newThemeName) +
119127
getVar("resource-suffix") + ".css";
120128
if (!window.currentTheme) {
121129
// If we're in the middle of loading, document.write blocks

0 commit comments

Comments
 (0)