def api_get_host_history(): # Get the hostname hostname = request.args.get('host', '').lower() # Fail if it's not a valid hostname (not in DNS, not a real hostname, etc.) hostname = valid_hostname(hostname) or valid_hostname('www.' + hostname) # prepend www. if necessary if not hostname: return jsonify({'error': '{hostname} is an invalid hostname'.format(hostname=request.args.get('host', ''))}) # Get the site's id number try: site_id = database.select_site_id(hostname) except IOError: return jsonify({'error': 'Unable to connect to database'}) # Get the host history history = database.select_scan_host_history(site_id) # Gracefully handle when there's no history if not history: return jsonify({'error': 'No history found'}) # Prune for when the score doesn't change; thanks to chuck for the elegant list comprehension pruned_history = [v for k, v in enumerate(history) if history[k].get('score') is not history[k-1].get('score') or k is 0] # Return the host history return jsonify(pruned_history)
def api_post_mass_analyze(): # Abort if the API keys don't match if request.form.get('apikey', 'notatrueapikey') != API_KEY: abort(403) # Get the hostnames try: hostnames = request.form['hosts'] except KeyError: return {'error': 'scan-missing-parameters'} # Fail if it's not a valid hostname (not in DNS, not a real hostname, etc.) for host in hostnames.split(','): hostname = valid_hostname(host) or valid_hostname('www.' + host) # prepend www. if necessary if not hostname: continue # Get the site's id number try: site_id = database.select_site_id(hostname) except IOError: return {'error': 'Unable to connect to database'} # And start up a scan row = database.insert_scan(site_id) try: scan.delay(hostname, site_id, row['id']) except redis.exceptions.ConnectionError: database.update_scan_state(row['id'], STATE_ABORTED, error='redis down') return {'error': 'Unable to connect to task system'} return jsonify({'state': 'OK'})
def api_post_scan_hostname(): # TODO: Allow people to accidentally use https://mozilla.org and convert to mozilla.org # Get the hostname hostname = request.args.get('host', '').lower() # Fail if it's not a valid hostname (not in DNS, not a real hostname, etc.) hostname = valid_hostname(hostname) or valid_hostname( 'www.' + hostname) # prepend www. if necessary if not hostname: return { 'error': '{hostname} is an invalid hostname'.format( hostname=request.args.get('host', '')) } # Get the site's id number try: site_id = database.select_site_id(hostname) except IOError: return {'error': 'Unable to connect to database'} # Next, let's see if there's a recent scan; if there was a recent scan, let's just return it # Setting rescan shortens what "recent" means rescan = True if request.form.get('rescan', 'false') == 'true' else False if rescan: row = database.select_scan_recent_scan(site_id, COOLDOWN) else: row = database.select_scan_recent_scan(site_id) # Otherwise, let's start up a scan if not row: hidden = request.form.get('hidden', 'false') # Begin the dispatch process if it was a POST if request.method == 'POST': try: # Connect to the backend and initiate a scan return requests.post(BACKEND_API_URL + '/analyze?host=' + hostname, data={ 'site_id': site_id, 'hidden': hidden, 'apikey': API_KEY }).json() except: return { 'error': 'scanner-backend-not-available-try-again-soon' } else: return {'error': 'recent-scan-not-found'} # If there was a rescan attempt and it returned a row, it's because the rescan was done within the cooldown window elif rescan and request.method == 'POST': return {'error': 'rescan-attempt-too-soon'} # Return the scan row return row
def api_post_scan_hostname(): # TODO: Allow people to accidentally use https://mozilla.org and convert to mozilla.org # Get the hostname hostname = request.args.get('host', '').lower() # Fail if it's not a valid hostname (not in DNS, not a real hostname, etc.) hostname = valid_hostname(hostname) or valid_hostname('www.' + hostname) # prepend www. if necessary if not hostname: return {'error': '{hostname} is an invalid hostname'.format(hostname=request.args.get('host', ''))} # Get the site's id number try: site_id = database.select_site_id(hostname) except IOError: return {'error': 'Unable to connect to database'} # Next, let's see if there's a recent scan; if there was a recent scan, let's just return it # Setting rescan shortens what "recent" means rescan = True if request.form.get('rescan', 'false') == 'true' else False if rescan: row = database.select_scan_recent_scan(site_id, COOLDOWN) else: row = database.select_scan_recent_scan(site_id) # Otherwise, let's start up a scan if not row: hidden = request.form.get('hidden', 'false') # Begin the dispatch process if it was a POST if request.method == 'POST': try: # Connect to the backend and initiate a scan return requests.post(BACKEND_API_URL + '/analyze?host=' + hostname, data={'site_id': site_id, 'hidden': hidden, 'apikey': API_KEY} ).json() except: return {'error': 'scanner-backend-not-available-try-again-soon'} else: return {'error': 'recent-scan-not-found'} # If there was a rescan attempt and it returned a row, it's because the rescan was done within the cooldown window elif rescan and request.method == 'POST': return {'error': 'rescan-attempt-too-soon'} # Return the scan row return row
def api_post_scan_hostname(): # TODO: Allow people to accidentally use https://mozilla.org and convert to mozilla.org # Get the hostname hostname = request.args.get('host', '').lower() # Fail if it's not a valid hostname (not in DNS, not a real hostname, etc.) hostname = valid_hostname(hostname) or valid_hostname( 'www.' + hostname) # prepend www. if necessary if not hostname: return { 'error': '{hostname} is an invalid hostname'.format( hostname=request.args.get('host', '')) } # Get the site's id number try: site_id = database.select_site_id(hostname) except IOError: return {'error': 'Unable to connect to database'} # Next, let's see if there's a recent scan; if there was a recent scan, let's just return it # Setting rescan shortens what "recent" means rescan = True if request.form.get('rescan', 'false') == 'true' else False if rescan: row = database.select_scan_recent_scan(site_id, COOLDOWN) else: row = database.select_scan_recent_scan(site_id) # Otherwise, let's start up a scan if not row: hidden = True if request.form.get('hidden', 'false') == 'true' else False # Begin the dispatch process if it was a POST if request.method == 'POST': row = database.insert_scan(site_id, hidden=hidden) scan_id = row['id'] scan.delay(hostname, site_id, scan_id) else: return {'error': 'recent-scan-not-found'} # If there was a rescan attempt and it returned a row, it's because the rescan was done within the cooldown window elif rescan and request.method == 'POST': return {'error': 'rescan-attempt-too-soon'} # Return the scan row return row
def test_invalid_hostname(self): self.assertFalse(valid_hostname('.com')) self.assertFalse(valid_hostname('foo')) self.assertFalse(valid_hostname('localhost')) self.assertFalse(valid_hostname('intranet')) self.assertFalse(valid_hostname('_spf.google.com')) # no A records self.assertFalse(valid_hostname('127.0.0.1')) self.assertFalse(valid_hostname('2607:f8b0:4009:80b::200e'))
def test_invalid_hostname(self): self.assertFalse(valid_hostname(".com")) self.assertFalse(valid_hostname("foo")) self.assertFalse(valid_hostname("localhost")) self.assertFalse(valid_hostname("intranet")) self.assertFalse(valid_hostname("_spf.google.com")) # no A records self.assertFalse(valid_hostname("127.0.0.1")) self.assertFalse(valid_hostname("2607:f8b0:4009:80b::200e"))
def api_post_scan_hostname(): # TODO: Allow people to accidentally use https://mozilla.org and convert to mozilla.org # Get the hostname hostname = request.args.get('host', '').lower() # Fail if it's not a valid hostname (not in DNS, not a real hostname, etc.) hostname = valid_hostname(hostname) or valid_hostname('www.' + hostname) # prepend www. if necessary if not hostname: return {'error': '{hostname} is an invalid hostname'.format(hostname=request.args.get('host', ''))} # Get the site's id number try: site_id = database.select_site_id(hostname) except IOError: return {'error': 'Unable to connect to database'} # Next, let's see if there's a recent scan; if there was a recent scan, let's just return it # Setting rescan shortens what "recent" means rescan = True if request.form.get('rescan', 'false') == 'true' else False if rescan: row = database.select_scan_recent_scan(site_id, COOLDOWN) else: row = database.select_scan_recent_scan(site_id) # Otherwise, let's start up a scan if not row: hidden = True if request.form.get('hidden', 'false') == 'true' else False # Begin the dispatch process if it was a POST if request.method == 'POST': row = database.insert_scan(site_id, hidden=hidden) scan_id = row['id'] scan.delay(hostname, site_id, scan_id) else: return {'error': 'recent-scan-not-found'} # If there was a rescan attempt and it returned a row, it's because the rescan was done within the cooldown window elif rescan and request.method == 'POST': return {'error': 'rescan-attempt-too-soon'} # Return the scan row return row
def test_valid_hostname(self): # TODO: Try to find a site with www.site.foo but not site.foo self.assertTrue(valid_hostname('mozilla.org')) self.assertTrue(valid_hostname('www.mozilla.org'))
def test_valid_localhost(self): self.assertTrue(valid_hostname('localhost'))
def test_valid_localhost(self): self.assertTrue(valid_hostname("localhost"))