Make static folder URL have a high-entropy random path, to avoid filename collisions with files getting shared

This commit is contained in:
Micah Lee 2019-05-22 20:07:35 -07:00
parent 91238366b1
commit 41be429b91
No known key found for this signature in database
GPG Key ID: 403C2657CD994F73
13 changed files with 60 additions and 47 deletions

View File

@ -34,7 +34,8 @@ class ReceiveModeWeb(object):
@self.web.app.route("/")
def index():
self.web.add_request(self.web.REQUEST_LOAD, request.path)
r = make_response(render_template('receive.html'))
r = make_response(render_template('receive.html',
static_url_path=self.web.static_url_path))
return self.web.add_security_headers(r)
@self.web.app.route("/upload", methods=['POST'])
@ -105,10 +106,12 @@ class ReceiveModeWeb(object):
return redirect('/')
else:
if ajax:
return json.dumps({"new_body": render_template('thankyou.html')})
return json.dumps({
"new_body": render_template('thankyou.html', static_url_path=self.web.static_url_path)
})
else:
# It was the last upload and the timer ran out
r = make_response(render_template('thankyou.html'))
r = make_response(render_template('thankyou.html'), static_url_path=self.web.static_url_path)
return self.web.add_security_headers(r)
@self.web.app.route("/upload-ajax", methods=['POST'])

View File

@ -55,7 +55,8 @@ class ShareModeWeb(object):
# currently a download
deny_download = not self.web.stay_open and self.download_in_progress
if deny_download:
r = make_response(render_template('denied.html'))
r = make_response(render_template('denied.html'),
static_url_path=self.web.static_url_path)
return self.web.add_security_headers(r)
# If download is allowed to continue, serve download page
@ -70,7 +71,8 @@ class ShareModeWeb(object):
filename=os.path.basename(self.download_filename),
filesize=self.filesize,
filesize_human=self.common.human_readable_filesize(self.download_filesize),
is_zipped=self.is_zipped))
is_zipped=self.is_zipped,
static_url_path=self.web.static_url_path))
return self.web.add_security_headers(r)
@self.web.app.route("/download")
@ -82,7 +84,8 @@ class ShareModeWeb(object):
# currently a download
deny_download = not self.web.stay_open and self.download_in_progress
if deny_download:
r = make_response(render_template('denied.html'))
r = make_response(render_template('denied.html',
static_url_path=self.web.static_url_path))
return self.web.add_security_headers(r)
# Each download has a unique id

View File

@ -51,8 +51,13 @@ class Web(object):
self.common = common
self.common.log('Web', '__init__', 'is_gui={}, mode={}'.format(is_gui, mode))
# The static URL path has a 128-bit random number in it to avoid having name
# collisions with files that might be getting shared
self.static_url_path = '/static_{}'.format(self.common.random_string(16))
# The flask app
self.app = Flask(__name__,
static_url_path=self.static_url_path,
static_folder=self.common.get_resource_path('static'),
template_folder=self.common.get_resource_path('templates'))
self.app.secret_key = self.common.random_string(8)
@ -163,7 +168,8 @@ class Web(object):
"""
Display instructions for disabling Tor Browser's NoScript XSS setting
"""
r = make_response(render_template('receive_noscript_xss.html'))
r = make_response(render_template('receive_noscript_xss.html',
static_url_path=self.static_url_path))
return self.add_security_headers(r)
def error401(self):
@ -181,18 +187,18 @@ class Web(object):
self.force_shutdown()
print("Someone has made too many wrong attempts to guess your password, so OnionShare has stopped the server. Start sharing again and send the recipient a new address to share.")
r = make_response(render_template('401.html'), 401)
r = make_response(render_template('401.html', static_url_path=self.static_url_path), 401)
return self.add_security_headers(r)
def error404(self):
self.add_request(Web.REQUEST_OTHER, request.path)
r = make_response(render_template('404.html'), 404)
r = make_response(render_template('404.html', static_url_path=self.static_url_path), 404)
return self.add_security_headers(r)
def error403(self):
self.add_request(Web.REQUEST_OTHER, request.path)
r = make_response(render_template('403.html'), 403)
r = make_response(render_template('403.html', static_url_path=self.static_url_path), 403)
return self.add_security_headers(r)
def add_security_headers(self, r):

View File

@ -131,7 +131,8 @@ class WebsiteModeWeb(object):
r = make_response(render_template('listing.html',
path=path,
files=files,
dirs=dirs))
dirs=dirs,
static_url_path=self.web.static_url_path))
return self.web.add_security_headers(r)
def set_file_info(self, filenames):

View File

@ -3,14 +3,14 @@
<head>
<title>OnionShare: 401 Unauthorized Access</title>
<link href="/static/img/favicon.ico" rel="icon" type="image/x-icon" />
<link rel="stylesheet" rel="subresource" type="text/css" href="/static/css/style.css" media="all">
<link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon" />
<link rel="stylesheet" rel="subresource" type="text/css" href="{{ static_url_path }}/css/style.css" media="all">
</head>
<body>
<div class="info-wrapper">
<div class="info">
<p><img class="logo" src="/static/img/logo_large.png" title="OnionShare"></p>
<p><img class="logo" src="{{ static_url_path }}/img/logo_large.png" title="OnionShare"></p>
<p class="info-header">401 Unauthorized Access</p>
</div>
</div>

View File

@ -3,14 +3,14 @@
<head>
<title>OnionShare: 403 Forbidden</title>
<link href="/static/img/favicon.ico" rel="icon" type="image/x-icon" />
<link rel="stylesheet" rel="subresource" type="text/css" href="/static/css/style.css" media="all">
<link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon" />
<link rel="stylesheet" rel="subresource" type="text/css" href="{{ static_url_path }}/css/style.css" media="all">
</head>
<body>
<div class="info-wrapper">
<div class="info">
<p><img class="logo" src="/static/img/logo_large.png" title="OnionShare"></p>
<p><img class="logo" src="{{ static_url_path }}/img/logo_large.png" title="OnionShare"></p>
<p class="info-header">You are not allowed to perform that action at this time.</p>
</div>
</div>

View File

@ -3,14 +3,14 @@
<head>
<title>OnionShare: 404 Not Found</title>
<link href="/static/img/favicon.ico" rel="icon" type="image/x-icon">
<link rel="stylesheet" rel="subresource" type="text/css" href="/static/css/style.css" media="all">
<link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon">
<link rel="stylesheet" rel="subresource" type="text/css" href="{{ static_url_path }}/css/style.css" media="all">
</head>
<body>
<div class="info-wrapper">
<div class="info">
<p><img class="logo" src="/static/img/logo_large.png" title="OnionShare"></p>
<p><img class="logo" src="{{ static_url_path }}/img/logo_large.png" title="OnionShare"></p>
<p class="info-header">404 Not Found</p>
</div>
</div>

View File

@ -3,7 +3,7 @@
<head>
<title>OnionShare</title>
<link href="/static/img/favicon.ico" rel="icon" type="image/x-icon" />
<link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon" />
</head>
<body>

View File

@ -2,13 +2,13 @@
<html>
<head>
<title>OnionShare</title>
<link href="/static/img/favicon.ico" rel="icon" type="image/x-icon" />
<link href="/static/css/style.css" rel="stylesheet" type="text/css" />
<link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon" />
<link href="{{ static_url_path }}/css/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<header class="clearfix">
<img class="logo" src="/static/img/logo.png" title="OnionShare">
<img class="logo" src="{{ static_url_path }}/img/logo.png" title="OnionShare">
<h1>OnionShare</h1>
</header>
@ -22,7 +22,7 @@
{% for info in dirs %}
<tr>
<td>
<img width="30" height="30" title="" alt="" src="/static/img/web_folder.png" />
<img width="30" height="30" title="" alt="" src="{{ static_url_path }}/img/web_folder.png" />
<a href="{{ info.basename }}">
{{ info.basename }}
</a>
@ -34,7 +34,7 @@
{% for info in files %}
<tr>
<td>
<img width="30" height="30" title="" alt="" src="/static/img/web_file.png" />
<img width="30" height="30" title="" alt="" src="{{ static_url_path }}/img/web_file.png" />
<a href="{{ info.basename }}">
{{ info.basename }}
</a>

View File

@ -2,13 +2,13 @@
<html>
<head>
<title>OnionShare</title>
<link href="/static/img/favicon.ico" rel="icon" type="image/x-icon">
<link rel="stylesheet" rel="subresource" type="text/css" href="/static/css/style.css" media="all">
<link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon">
<link rel="stylesheet" rel="subresource" type="text/css" href="{{ static_url_path }}/css/style.css" media="all">
</head>
<body>
<header class="clearfix">
<img class="logo" src="/static/img/logo.png" title="OnionShare">
<img class="logo" src="{{ static_url_path }}/img/logo.png" title="OnionShare">
<h1>OnionShare</h1>
</header>
@ -19,14 +19,14 @@
-->
<div id="noscript">
<p>
<img src="/static/img/warning.png" title="Warning" /><strong>Warning:</strong> Due to a bug in Tor Browser and Firefox, uploads
<img src="{{ static_url_path }}/img/warning.png" title="Warning" /><strong>Warning:</strong> Due to a bug in Tor Browser and Firefox, uploads
sometimes never finish. To upload reliably, either set your Tor Browser
<a rel="noreferrer" target="_blank" href="https://tb-manual.torproject.org/en-US/security-slider/">security slider</a>
to Standard or
<a target="_blank" href="/noscript-xss-instructions">turn off your Tor Browser's NoScript XSS setting</a>.</p>
</div>
<p><img class="logo" src="/static/img/logo_large.png" title="OnionShare"></p>
<p><img class="logo" src="{{ static_url_path }}/img/logo_large.png" title="OnionShare"></p>
<p class="upload-header">Send Files</p>
<p class="upload-description">Select the files you want to send, then click "Send Files"...</p>
@ -51,8 +51,8 @@
</form>
</div>
<script src="/static/js/receive-noscript.js"></script>
<script src="/static/js/jquery-3.4.0.min.js"></script>
<script async src="/static/js/receive.js"></script>
<script src="{{ static_url_path }}/js/receive-noscript.js"></script>
<script src="{{ static_url_path }}/js/jquery-3.4.0.min.js"></script>
<script async src="{{ static_url_path }}/js/receive.js"></script>
</body>
</html>

View File

@ -2,13 +2,13 @@
<html>
<head>
<title>OnionShare</title>
<link href="/static/img/favicon.ico" rel="icon" type="image/x-icon">
<link rel="stylesheet" rel="subresource" type="text/css" href="/static/css/style.css" media="all">
<link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon">
<link rel="stylesheet" rel="subresource" type="text/css" href="{{ static_url_path }}/css/style.css" media="all">
</head>
<body>
<header class="clearfix">
<img class="logo" src="/static/img/logo.png" title="OnionShare">
<img class="logo" src="{{ static_url_path }}/img/logo.png" title="OnionShare">
<h1>OnionShare</h1>
</header>

View File

@ -3,8 +3,8 @@
<head>
<title>OnionShare</title>
<link href="/static/img/favicon.ico" rel="icon" type="image/x-icon">
<link rel="stylesheet" rel="subresource" type="text/css" href="/static/css/style.css" media="all">
<link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon">
<link rel="stylesheet" rel="subresource" type="text/css" href="{{ static_url_path }}/css/style.css" media="all">
<meta name="onionshare-filename" content="{{ filename }}">
<meta name="onionshare-filesize" content="{{ filesize }}">
</head>
@ -18,7 +18,7 @@
<li><a class="button" href='/download'>Download Files</a></li>
</ul>
</div>
<img class="logo" src="/static/img/logo.png" title="OnionShare">
<img class="logo" src="{{ static_url_path }}/img/logo.png" title="OnionShare">
<h1>OnionShare</h1>
</header>
@ -31,7 +31,7 @@
{% for info in file_info.dirs %}
<tr>
<td>
<img width="30" height="30" title="" alt="" src="/static/img/web_folder.png" />
<img width="30" height="30" title="" alt="" src="{{ static_url_path }}/img/web_folder.png" />
{{ info.basename }}
</td>
<td>{{ info.size_human }}</td>
@ -41,7 +41,7 @@
{% for info in file_info.files %}
<tr>
<td>
<img width="30" height="30" title="" alt="" src="/static/img/web_file.png" />
<img width="30" height="30" title="" alt="" src="{{ static_url_path }}/img/web_file.png" />
{{ info.basename }}
</td>
<td>{{ info.size_human }}</td>
@ -49,7 +49,7 @@
</tr>
{% endfor %}
</table>
<script async src="/static/js/send.js" charset="utf-8"></script>
<script async src="{{ static_url_path }}/js/send.js" charset="utf-8"></script>
</body>
</html>

View File

@ -3,19 +3,19 @@
<head>
<title>OnionShare is closed</title>
<link href="/static/img/favicon.ico" rel="icon" type="image/x-icon">
<link rel="stylesheet" rel="subresource" type="text/css" href="/static/css/style.css" media="all">
<link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon">
<link rel="stylesheet" rel="subresource" type="text/css" href="{{ static_url_path }}/css/style.css" media="all">
</head>
<body>
<header class="clearfix">
<img class="logo" src="/static/img/logo.png" title="OnionShare">
<img class="logo" src="{{ static_url_path }}/img/logo.png" title="OnionShare">
<h1>OnionShare</h1>
</header>
<div class="info-wrapper">
<div class="info">
<p><img class="logo" src="/static/img/logo_large.png" title="OnionShare"></p>
<p><img class="logo" src="{{ static_url_path }}/img/logo_large.png" title="OnionShare"></p>
<p class="info-header">Thank you for using OnionShare</p>
<p class="info-description">You may now close this window.</p>
</div>