-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathserver.py
More file actions
98 lines (81 loc) · 3.46 KB
/
Copy pathserver.py
File metadata and controls
98 lines (81 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
"""Flask web front-end for Have I Been Pwned (HIBP) breach checks.
Serves a small UI that lets a user check whether an email address appears in
known data breaches and whether a password appears in the Pwned Passwords
range API. The HIBP API key is read from the environment (via a .env file)
and is never exposed in any response.
"""
import os
import hashlib
import requests
from flask import Flask, render_template, request
from dotenv import load_dotenv
app = Flask(__name__)
# Load the environment variables from .env
load_dotenv()
# Get the API key from the environment variables
API_KEY = os.getenv('HIBP_API_KEY')
if not API_KEY:
raise RuntimeError('HIBP_API_KEY is not set. Add it to your environment or .env file.')
# Request timeout (seconds) so a stalled call doesn't hang the web worker.
REQUEST_TIMEOUT = 10
# HIBP requires both an API key and a descriptive User-Agent.
HIBP_HEADERS = {
'hibp-api-key': API_KEY,
'User-Agent': 'segraef-Scripts-hibp-checker',
}
# The Pwned Passwords range API is a separate, unauthenticated service:
# never send the HIBP API key to it.
PWD_HEADERS = {'User-Agent': 'segraef-Scripts-hibp-checker'}
@app.route('/')
def index():
return render_template('index.html')
@app.route('/cheat')
def cheat():
return render_template('cheat.html')
@app.route('/check', methods=['POST'])
def check():
email = request.form.get('email')
password = request.form.get('password2')
result = {}
if not email and not password:
return "No email or password provided", 400
if email:
# Send the email to the HIBP API
response = requests.get(
f'https://haveibeenpwned.com/api/v3/breachedaccount/{email}',
headers=HIBP_HEADERS,
timeout=REQUEST_TIMEOUT)
if response.status_code == 404:
result["email"] = "Email not found in data breaches"
elif response.status_code != 200:
result["email"] = "Error checking email"
else:
# Extract the name of the breaches from the response
breaches = [breach['Name'] for breach in response.json()]
result["email"] = f"Email found in following breaches: {', '.join(breaches)}."
# foreach breach in breache --> GET https://haveibeenpwned.com/api/v3/breaches/{breach}
if password:
# Hash the password before sending it to the HIBP API
hashed_password = hashlib.sha1(
password.encode('utf-8')).hexdigest().upper()
prefix = hashed_password[:5]
suffix = hashed_password[5:]
# Send the hashed password to the Pwned Passwords API
response = requests.get(
f'https://api.pwnedpasswords.com/range/{prefix}',
headers=PWD_HEADERS,
timeout=REQUEST_TIMEOUT)
if response.status_code != 200:
result["password"] = "Error checking password"
else:
# Check if the hashed password suffix exists in the response
for line in response.text.splitlines():
line_suffix, count = line.split(':')
if line_suffix == suffix:
result["password"] = f"Password found {count} times. Please use a different password."
break
else:
result["password"] = "Password not found. You can use this password."
return render_template("result.html", result=result)
if __name__ == '__main__':
app.run(port=5001, debug=os.getenv('FLASK_DEBUG', 'false').lower() == 'true')