Skip to content

Commit

Permalink
Allowing config flag to turn off javascript controls (apache#4400)
Browse files Browse the repository at this point in the history
* Allowing config flag to turn off javascript controls

* lint

* one line, avoiding mutation

* Setting JS fields as readOnly
  • Loading branch information
mistercrunch authored and michellethomas committed May 23, 2018
1 parent 7e68f4a commit f782ef5
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 2 deletions.
14 changes: 14 additions & 0 deletions superset/assets/javascripts/explore/components/ControlHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const propTypes = {
onClick: PropTypes.func,
hovered: PropTypes.bool,
tooltipOnClick: PropTypes.func,
warning: PropTypes.string,
};

const defaultProps = {
Expand Down Expand Up @@ -75,6 +76,19 @@ export default class ControlHeader extends React.Component {
{this.props.label}
</span>
{' '}
{(this.props.warning) &&
<span>
<OverlayTrigger
placement="top"
overlay={
<Tooltip id={'error-tooltip'}>{this.props.warning}</Tooltip>
}
>
<i className="fa fa-exclamation-circle text-danger" />
</OverlayTrigger>
{' '}
</span>
}
{(this.props.validationErrors.length > 0) &&
<span>
<OverlayTrigger
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const propTypes = {
offerEditInModal: PropTypes.bool,
language: PropTypes.oneOf([null, 'json', 'html', 'sql', 'markdown', 'javascript']),
aboveEditorSection: PropTypes.node,
readOnly: PropTypes.bool,
};

const defaultProps = {
Expand All @@ -34,6 +35,7 @@ const defaultProps = {
minLines: 3,
maxLines: 10,
offerEditInModal: true,
readOnly: false,
};

export default class TextAreaControl extends React.Component {
Expand All @@ -57,6 +59,7 @@ export default class TextAreaControl extends React.Component {
editorProps={{ $blockScrolling: true }}
enableLiveAutocompletion
value={this.props.value}
readOnly={this.props.readOnly}
/>
);
}
Expand All @@ -67,6 +70,7 @@ export default class TextAreaControl extends React.Component {
placeholder={t('textarea')}
onChange={this.onControlChange.bind(this)}
value={this.props.value}
disabled={this.props.readOnly}
style={{ height: this.props.height }}
/>
</FormGroup>);
Expand Down
5 changes: 5 additions & 0 deletions superset/assets/javascripts/explore/stores/controls.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ function jsFunctionControl(label, description, extraDescr = null, height = 100,
{extraDescr}
</div>
),
mapStateToProps: state => ({
warning: !state.common.conf.ENABLE_JAVASCRIPT_CONTROLS ?
t('This functionality is disabled in your environment for security reasons.') : null,
readOnly: !state.common.conf.ENABLE_JAVASCRIPT_CONTROLS,
}),
};
}

Expand Down
6 changes: 6 additions & 0 deletions superset/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,12 @@ class CeleryConfig(object):
# Interval between consecutive polls when using Hive Engine
HIVE_POLL_INTERVAL = 5

# Allow for javascript controls components
# this enables programmers to customize certain charts (like the
# geospatial ones) by inputing javascript in controls. This exposes
# an XSS security vulnerability
ENABLE_JAVASCRIPT_CONTROLS = False

try:
if CONFIG_PATH_ENV_VAR in os.environ:
# Explicitly import config module that is not in pythonpath; useful
Expand Down
5 changes: 4 additions & 1 deletion superset/views/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
from superset.connectors.sqla.models import SqlaTable
from superset.translations.utils import get_language_pack

FRONTEND_CONF_KEYS = ('SUPERSET_WEBSERVER_TIMEOUT',)
FRONTEND_CONF_KEYS = (
'SUPERSET_WEBSERVER_TIMEOUT',
'ENABLE_JAVASCRIPT_CONTROLS',
)


def get_error_msg():
Expand Down
13 changes: 12 additions & 1 deletion superset/views/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@
else:
DATASOURCE_ACCESS_ERR = __("You don't have access to this datasource")

FORM_DATA_KEY_BLACKLIST = []
if not config.get('ENABLE_JAVASCRIPT_CONTROLS'):
FORM_DATA_KEY_BLACKLIST = [
'js_tooltip',
'js_onclick_href',
'js_data_mutator',
]


def get_database_access_error_msg(database_name):
return __('This view requires the database %(name)s or '
Expand Down Expand Up @@ -948,7 +956,10 @@ def get_form_data(self):

if request.args.get('viz_type'):
# Converting old URLs
d = cast_form_data(request.args)
d = cast_form_data(d)

d = {k: v for k, v in d.items() if k not in FORM_DATA_KEY_BLACKLIST}

return d

def get_viz(
Expand Down

0 comments on commit f782ef5

Please sign in to comment.