Skip to content

Commit

Permalink
Add instructions for working around NoScript XSS upload problem
Browse files Browse the repository at this point in the history
There is currently an unpredictable problem with uploads, due to a
Firefox bug. For now, the only workarounds are implementing AJAX
uploads or disabling NoScript's cross-site request sanitization. We're
recommending the latter, since it should be safe with our recommended
Tor Browser settings, and doesn't require enabling JavaScript to use
SecureDrop.

This change adds:

- instructions in the source UI for disabling NoScript cross-site
  request sanitization before uploading
- a note about the bug in the source guide
- updated screenshots of the source submission page

Fixes: #4078
  • Loading branch information
rmol authored and kushaldas committed Sep 25, 2019
1 parent 5bbe1b2 commit ab61226
Show file tree
Hide file tree
Showing 22 changed files with 113 additions and 3 deletions.
Binary file modified docs/images/manual/screenshots/source-checks_for_reply.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/manual/screenshots/source-deletes_reply.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/manual/screenshots/source-flagged.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/manual/screenshots/source-lookup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions docs/source.rst
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,15 @@ limit, we recommend that you send a message to the journalist explaining
this, so that they can set up another method for transferring the
documents.

.. note:: The Tor Browser currently suffers from a Firefox bug that
can cause uploads to fail unpredictably. You can avoid this
bug by disabling the NoScript browser extension's cross-site
request sanitization. This is safe to do if you have set
your Tor Browser security slider to our recommended setting,
"Safest". The instructions for the first step of submission
include a link to a page explaining how to adjust your
settings.

When your submission is ready, click **Submit**.

|Submit a document|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@
/var/www/securedrop/source_templates/banner_warning_flashed.html r,
/var/www/securedrop/source_templates/base.html r,
/var/www/securedrop/source_templates/error.html r,
/var/www/securedrop/source_templates/disable-noscript-xss.html r,
/var/www/securedrop/source_templates/first_submission_flashed_message.html r,
/var/www/securedrop/source_templates/flashed.html r,
/var/www/securedrop/source_templates/generate.html r,
Expand Down Expand Up @@ -266,6 +267,12 @@
/var/www/securedrop/static/i/font-awesome/trash-black.png r,
/var/www/securedrop/static/i/toronion.png r,
/var/www/securedrop/static/i/hand_with_fingerprint.png r,
/var/www/securedrop/static/i/noscript-xss/advanced-settings.png r,
/var/www/securedrop/static/i/noscript-xss/noscript-icon-plain.png r,
/var/www/securedrop/static/i/noscript-xss/noscript-icon.png r,
/var/www/securedrop/static/i/noscript-xss/noscript-pane.png r,
/var/www/securedrop/static/i/noscript-xss/noscript-settings-icon.png r,
/var/www/securedrop/static/i/noscript-xss/settings-pane.png r,
/var/www/securedrop/static/i/success_checkmark.png r,
/var/www/securedrop/static/i/relieved_face.png r,
/var/www/securedrop/static/i/server_upload.png r,
Expand Down
3 changes: 3 additions & 0 deletions securedrop/sass/_base.sass
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@
@import "modules/grid-item"
// Option - might be unused. Delete?
@import "modules/option"
// Image - general image styling
@import "modules/img"
// Logo - Small and large versions of the branding; can also be the journalist org brand (not SD).
@import "modules/logo"
// Submissions - container for all of the submissions
Expand Down Expand Up @@ -139,6 +141,7 @@
+document-actions-button
+grid-item
+option
+img
+logo
+submissions
+submission
Expand Down
11 changes: 11 additions & 0 deletions securedrop/sass/modules/_hr-horizontal-rule-line.sass
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,14 @@
clear: both
border: none
height: 10px

&.dotted
clear: both
margin: 3em 0 0em 0
padding: 0
border-top: none
border-bottom: dotted 2px
border-color: rgba(128, 128, 128, 0.25)

& + h2
margin-top: 0
7 changes: 7 additions & 0 deletions securedrop/sass/modules/_img.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
=img
img
&.inline
max-height: 1em
&.constrained
max-height: 100%
max-width: 100%
4 changes: 4 additions & 0 deletions securedrop/source_app/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
def make_blueprint(config):
view = Blueprint('info', __name__)

@view.route('/disable-noscript-xss')
def disable_noscript_xss():
return render_template("disable-noscript-xss.html")

@view.route('/tor2web-warning')
def tor2web_warning():
return render_template("tor2web-warning.html")
Expand Down
51 changes: 51 additions & 0 deletions securedrop/source_templates/disable-noscript-xss.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{% extends "base.html" %}
{% block body %}
<h1>{{ gettext("Turn off NoScript's cross-site request sanitization setting") }}</h1>

<p>{{ gettext('Due to a browser issue (<a href="{url}">more details</a>), uploads do not currently work reliably in Tor Browser while cross-site request sanitization is turned on. It is safe to turn off this feature while your Security Slider is set to "Safest". Here\'s how:').format(url="https://github.com/hackademix/noscript/issues/64#issuecomment-462709129") }}</p>

<p>{{ gettext('You should find a blue "S" icon in the Tor browser\'s toolbar: <img class="inline" src="{noscript_plain_icon_url}"> or <img class="inline" src="{noscript_icon_url}">. This is the NoScript button.').format(noscript_plain_icon_url=url_for('static', filename='i/noscript-xss/noscript-icon-plain.png'), noscript_icon_url=url_for('static', filename='i/noscript-xss/noscript-icon.png')) }}</p>

<hr class="dotted">

<h2>{{ gettext("1. Click on the NoScript button.") }}</h2>
<p>{{ gettext("The NoScript pane should appear. It looks like this:") }}</p>

<img class="constrained" src="{{ url_for('static', filename='i/noscript-xss/noscript-pane.png') }}">

<hr class="dotted">

<h2>{{ gettext('2. In the NoScript pane, click on the Settings icon: <img class="inline" src="{url}">').format(url=url_for('static', filename='i/noscript-xss/noscript-settings-icon.png')) }}</h2>

<p>{{ gettext("The settings page should appear in a new browser tab. It looks like this:") }}</p>

<img class="constrained" src="{{ url_for('static', filename='i/noscript-xss/settings-pane.png') }}">

<hr class="dotted">

<h2>{{ gettext('3. Click the "Advanced" tab.') }}</h2>

<p>{{ gettext("The advanced settings tab should come into view. It looks like this:") }}</p>

<img class="constrained" src="{{ url_for('static', filename='i/noscript-xss/advanced-settings.png') }}">

<hr class="dotted">

<h2>{{ gettext('4. Un-check "Sanitize cross-site suspicious requests".') }}</h2>

<p>{{ gettext("Due to a browser issue, this is required for uploads to work reliably. As soon as the browser issue is resolved, we will remove this recommendation.") }}</p>

<hr class="dotted">

<h2>{{ gettext("5. Close the <i>NoScript Settings</i> browser tab and return to the SecureDrop tab.") }}</h2>

<p>{{ gettext("You can now upload your files. Please keep in mind that each file requires its own submission.") }}</p>

<hr class="dotted">

<h2>{{ gettext('6. Re-check "Sanitize cross-site suspicious requests".') }}</h2>

<p>{{ gettext('Repeat steps 1-3 from above and re-check the setting. The setting has no effect while your Security Slider is set to "Safest", but we recommend enabling it during normal Tor usage.') }}</p>


{% endblock %}
10 changes: 7 additions & 3 deletions securedrop/source_templates/lookup.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,14 @@
</div>

<h1 class="headline">{{ gettext('Submit Files or Messages') }}</h1>
<p class="explanation">{{ gettext('If you are already familiar with GPG, you can optionally encrypt your files and messages with our <a href="{url}" class="text-link">public key</a> before submission. Files are encrypted as they are received by SecureDrop.').format(url=url_for('info.download_journalist_pubkey')) }}
{{ gettext('<a href="{url}" class="text-link">Learn more</a>.').format(url=url_for('info.why_download_journalist_pubkey')) }}</p>

<p class="explanation">{{ gettext('You can submit any kind of file, a message, or both.') }}</p>
<p class="explanation"><b>1.</b> {{ gettext('Before you begin, turn off cross-site request sanitization in NoScript. This is <strong>required</strong> for uploads to work. <a href="{url}" class="text-link">Show me how.</a>').format(url=url_for('info.disable_noscript_xss'))}}</p>

<p class="explanation"><b>2.</b> {{ gettext('You can submit any kind of file, a message, or both.') }}</p>

<p class="explanation"><b>3.</b> {{ gettext('If you are already familiar with GPG, you can optionally encrypt your files and messages with our <a href="{url}" class="text-link">public key</a> before submission. Files are encrypted as they are received by SecureDrop.').format(url=url_for('info.download_journalist_pubkey')) }}
{{ gettext('<a href="{url}" class="text-link">Learn more</a>.').format(url=url_for('info.why_download_journalist_pubkey')) }}</p>

<hr class="no-line">

<form id="upload" method="post" action="{{ url_for('main.submit') }}" enctype="multipart/form-data" autocomplete="off">
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions securedrop/tests/functional/source_navigation_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ def _source_tor2web_warning(self):
def _source_why_journalist_key(self):
self.driver.get(self.source_location + "/why-journalist-key")

def _source_disable_noscript_xss(self):
self.driver.get(self.source_location + "/disable-noscript-xss")

def _source_waits_for_session_to_timeout(self, session_length_minutes):
time.sleep(session_length_minutes * 60 + 0.1)

Expand Down
3 changes: 3 additions & 0 deletions securedrop/tests/functional/test_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ def test_lookup_codename_hint(self):
self._source_chooses_to_login()
self._source_proceeds_to_login()
self._source_sees_no_codename()

def test_disable_noscript_xss(self):
self._source_disable_noscript_xss()
8 changes: 8 additions & 0 deletions securedrop/tests/test_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,14 @@ def test_why_journalist_key(source_app):
assert "Why download the journalist's public key?" in text


def test_disable_noscript_xss(source_app):
with source_app.test_client() as app:
resp = app.get(url_for('info.disable_noscript_xss'))
assert resp.status_code == 200
text = resp.data.decode('utf-8')
assert "<h1>Turn off NoScript's cross-site request sanitization setting</h1>" in text


def test_metadata_route(source_app):
with patch.object(source_app_api.platform, "linux_distribution") as mocked_platform:
mocked_platform.return_value = ("Ubuntu", "16.04", "xenial")
Expand Down

0 comments on commit ab61226

Please sign in to comment.