@@ -127,6 +127,7 @@ def verify_password(password: str, stored: str) -> bool:
127127class LoginHandler (SimpleHTTPRequestHandler ):
128128 pw_hash : str = "" # PBKDF2 string
129129 secret : bytes = b""
130+ _failed_attempts : dict [str , int ] = {}
130131
131132 def _authed (self ) -> bool :
132133 cookie = self .headers .get ("Cookie" , "" )
@@ -146,6 +147,10 @@ def _send_login(self, error: str = "") -> None:
146147 self .wfile .write (html .encode ("utf-8" ))
147148
148149 def do_GET (self ):
150+ client_ip = self .client_address [0 ]
151+ if LoginHandler ._failed_attempts .get (client_ip , 0 ) >= 5 :
152+ self .send_error (403 , "Too many failed login attempts. Access blocked." )
153+ return
149154 if self .path .startswith ("/__login" ):
150155 return self ._send_login ()
151156
@@ -165,18 +170,15 @@ def do_POST(self):
165170
166171 if not verify_password (pw , self .pw_hash ):
167172 # Track failed attempts by IP address
168- client_ip = self .client_address [0 ]
169- if not hasattr (LoginHandler , '_failed_attempts' ):
170- LoginHandler ._failed_attempts = {}
171-
172- LoginHandler ._failed_attempts [client_ip ] = LoginHandler ._failed_attempts .get (client_ip , 0 ) + 1
173-
174- if LoginHandler ._failed_attempts [client_ip ] >= 5 :
175- self .send_error (403 , "Too many failed login attempts. Access blocked." )
176- return
177-
178- attempts_left = 5 - LoginHandler ._failed_attempts [client_ip ]
179- return self ._send_login (f"Wrong password. { attempts_left } attempts left." )
173+ client_ip = self .client_address [0 ]
174+ LoginHandler ._failed_attempts [client_ip ] = LoginHandler ._failed_attempts .get (client_ip , 0 ) + 1
175+
176+ if LoginHandler ._failed_attempts [client_ip ] >= 5 :
177+ self .send_error (403 , "Too many failed login attempts. Access blocked." )
178+ return
179+
180+ attempts_left = 5 - LoginHandler ._failed_attempts [client_ip ]
181+ return self ._send_login (f"Wrong password. { attempts_left } attempts left." )
180182 # Reset failed attempts on successful login
181183 client_ip = self .client_address [0 ]
182184 if hasattr (LoginHandler , '_failed_attempts' ) and client_ip in LoginHandler ._failed_attempts :
0 commit comments