Skip to content

Commit

Permalink
[security] prevent XSS markup viz (#3211)
Browse files Browse the repository at this point in the history
* Prevent XSS in Markup viz

We protect the browser by sandboxing the user code inside an iframe

* Helvetica
  • Loading branch information
mistercrunch authored Aug 11, 2017
1 parent bd4a4c2 commit 0c5db55
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 20 deletions.
27 changes: 20 additions & 7 deletions superset/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,35 @@
app.config.from_object(CONFIG_MODULE)
conf = app.config

#################################################################
# Handling manifest file logic at app start
#################################################################
MANIFEST_FILE = APP_DIR + '/static/assets/dist/manifest.json'
get_manifest_file = lambda x: x
manifest = {}
try:
with open(MANIFEST_FILE, 'r') as f:
manifest = json.load(f)
get_manifest_file = lambda x: '/static/assets/dist/' + manifest.get(x, '')
except Exception:
print("no manifest file found at " + MANIFEST_FILE)


def parse_manifest_json():
global manifest
try:
with open(MANIFEST_FILE, 'r') as f:
manifest = json.load(f)
except Exception:
print("no manifest file found at " + MANIFEST_FILE)


def get_manifest_file(filename):
if app.debug:
parse_manifest_json()
return '/static/assets/dist/' + manifest.get(filename, '')

parse_manifest_json()

@app.context_processor
def get_js_manifest():
return dict(js_manifest=get_manifest_file)

#################################################################


for bp in conf.get('BLUEPRINTS'):
try:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export default class TextAreaControl extends React.Component {
modalTitle={controlHeader}
triggerNode={
<Button bsSize="small" className="m-t-5">
Edit <b>{this.props.language}</b> in modal
Edit <strong>{this.props.language}</strong> in modal
</Button>
}
modalBody={this.renderEditor(true)}
Expand Down
2 changes: 1 addition & 1 deletion superset/assets/stylesheets/less/cosmo/variables.less
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
//
//## Font, line-height, and color for body text, headings, and more.

@font-family-sans-serif: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif;
@font-family-sans-serif: Helvetica, Arial;

@font-family-serif: Georgia, "Times New Roman", Times, serif;
//** Default monospace fonts for `<code>`, `<kbd>`, and `<pre>`.
Expand Down
12 changes: 5 additions & 7 deletions superset/assets/stylesheets/superset.less
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
@font-face {
font-family: "Roboto";
src: url("./fonts/Roboto-Regular.woff2") format("woff2"),
url("./fonts/Roboto-Regular.woff") format("woff");
}

body {
margin: 0px !important;
}
Expand Down Expand Up @@ -255,4 +249,8 @@ div.widget .slice_container {
.panel .table-responsive{
width: 98%;
}
}
}
iframe {
border: none;
width: 100%;
}
22 changes: 20 additions & 2 deletions superset/assets/visualizations/markup.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,29 @@ require('./markup.css');

function markupWidget(slice, payload) {
$('#code').attr('rows', '15');
slice.container.css({
const jqdiv = slice.container;
jqdiv.css({
overflow: 'auto',
height: slice.container.height(),
});
slice.container.html(payload.data.html);

const iframeId = `if__${slice.containerId}`;
const html = `
<html>
<head>
<link rel="stylesheet" type="text/css" href="${payload.data.theme_css}" />
</head>
<body style="background-color: transparent;">
${payload.data.html}
</body>
</html>`;
jqdiv.html(`
<iframe id="${iframeId}"
frameborder="0"
height="${slice.height()}"
sandbox="allow-scripts">
</iframe>`);
$('#' + iframeId)[0].srcdoc = html;
}

module.exports = markupWidget;
4 changes: 2 additions & 2 deletions superset/viz.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from six import string_types, PY3
from dateutil import relativedelta as rdelta

from superset import app, utils, cache
from superset import app, utils, cache, get_manifest_file
from superset.utils import DTTM_ALIAS

config = app.config
Expand Down Expand Up @@ -439,7 +439,7 @@ def get_data(self, df):
code = self.form_data.get("code", '')
if markup_type == "markdown":
code = markdown(code)
return dict(html=code)
return dict(html=code, theme_css=get_manifest_file('theme.css'))


class SeparatorViz(MarkupViz):
Expand Down

0 comments on commit 0c5db55

Please sign in to comment.