Return 404 to UserAgents matching list

Empty User-Agent should not break
Add test for 404 response to /bot/
Wrap User-Agent check in `request_is_valid` method
This commit is contained in:
Joseph Boiteau 2016-12-20 16:08:56 +11:00
parent addd1495a3
commit 1651ac4bd5
No known key found for this signature in database
GPG key ID: 03569E835707F0B0
2 changed files with 30 additions and 0 deletions

View file

@ -1,6 +1,7 @@
import os import os
import sys import sys
import uuid import uuid
import re
import redis import redis
from redis.exceptions import ConnectionError from redis.exceptions import ConnectionError
@ -78,6 +79,15 @@ def clean_input():
return time_conversion[time_period], request.form['password'] return time_conversion[time_period], request.form['password']
def request_is_valid(request):
"""
Ensure the request validates the following:
- not made by some specific User-Agents (to avoid chat's preview feature issue)
"""
known_sneaky_user_agents = ['Slackbot', 'facebookexternalhit', 'Twitterbot', 'Facebot', 'WhatsApp']
user_agents_regexp = "|".join(known_sneaky_user_agents)
return not re.search(user_agents_regexp, request.headers.get('User-Agent', ''))
@app.route('/', methods=['GET']) @app.route('/', methods=['GET'])
def index(): def index():
@ -99,6 +109,8 @@ def handle_password():
@app.route('/<password_key>', methods=['GET']) @app.route('/<password_key>', methods=['GET'])
def show_password(password_key): def show_password(password_key):
if not request_is_valid(request):
abort(404)
password = get_password(password_key) password = get_password(password_key)
if not password: if not password:
abort(404) abort(404)

View file

@ -73,6 +73,24 @@ class SnapPassRoutesTestCase(TestCase):
rv = self.app.get('/{0}'.format(key)) rv = self.app.get('/{0}'.format(key))
self.assertTrue(password in rv.get_data(as_text=True)) self.assertTrue(password in rv.get_data(as_text=True))
def test_bots_denial(self):
"""
Main known bots User-Agent should be denied access
"""
password = "Bots can't access this"
key = snappass.set_password(password, 30)
a_few_sneaky_bots = [
"Slackbot-LinkExpanding 1.0 (+https://api.slack.com/robots)",
"facebookexternalhit/1.1",
"Twitterbot/1.0",
"_WhatsApp/2.12.81 (Windows NT 6.1; U; es-ES) Presto/2.9.181 Version/12.00",
"WhatsApp/2.16.6/i"
]
for ua in a_few_sneaky_bots:
rv = self.app.get('/{0}'.format(key), headers={ 'User-Agent': ua })
self.assertEquals(rv.status_code, 404)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()