diff --git a/snappass/main.py b/snappass/main.py index 9d05f54..30f6926 100644 --- a/snappass/main.py +++ b/snappass/main.py @@ -1,4 +1,5 @@ import os +import re import sys import uuid @@ -8,6 +9,8 @@ from redis.exceptions import ConnectionError from flask import abort, Flask, render_template, request +SNEAKY_USER_AGENTS = ('Slackbot', 'facebookexternalhit', 'Twitterbot', 'Facebot', 'WhatsApp') +SNEAKY_USER_AGENTS_RE = re.compile('|'.join(SNEAKY_USER_AGENTS)) NO_SSL = os.environ.get('NO_SSL', False) app = Flask(__name__) if os.environ.get('DEBUG'): @@ -80,6 +83,13 @@ def clean_input(): 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) + """ + return not SNEAKY_USER_AGENTS_RE.search(request.headers.get('User-Agent', '')) + @app.route('/', methods=['GET']) def index(): @@ -101,6 +111,8 @@ def handle_password(): @app.route('/', methods=['GET']) def show_password(password_key): + if not request_is_valid(request): + abort(404) password = get_password(password_key) if not password: abort(404) diff --git a/tests.py b/tests.py index 1726068..bc5e709 100644 --- a/tests.py +++ b/tests.py @@ -73,6 +73,25 @@ class SnapPassRoutesTestCase(TestCase): rv = self.app.get('/{0}'.format(key)) 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", + "Facebot/1.0", + "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__': unittest.main()