Add honeypot field to login form: instant 24h IP ban on autofill
This commit is contained in:
+1
-1
@@ -10,7 +10,7 @@ async function doLogin() {
|
|||||||
const res = await fetch(`${API}/api/auth/login`, {
|
const res = await fetch(`${API}/api/auth/login`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ username, password }),
|
body: JSON.stringify({ username, password, website: document.getElementById('hpWebsite').value }),
|
||||||
});
|
});
|
||||||
const data = await res.json().catch(() => ({}));
|
const data = await res.json().catch(() => ({}));
|
||||||
if (res.ok && data.token) {
|
if (res.ok && data.token) {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;b
|
|||||||
<h1>Админ-панель</h1>
|
<h1>Админ-панель</h1>
|
||||||
<input type="text" id="userInput" placeholder="Логин" autocomplete="username" autofocus>
|
<input type="text" id="userInput" placeholder="Логин" autocomplete="username" autofocus>
|
||||||
<input type="password" id="pwdInput" placeholder="Пароль" autocomplete="current-password">
|
<input type="password" id="pwdInput" placeholder="Пароль" autocomplete="current-password">
|
||||||
|
<input type="text" id="hpWebsite" tabindex="-1" autocomplete="off" style="display:none" value="">
|
||||||
<button type="button" id="loginBtn">Войти</button>
|
<button type="button" id="loginBtn">Войти</button>
|
||||||
<div class="err" id="loginErr">Неверный логин или пароль</div>
|
<div class="err" id="loginErr">Неверный логин или пароль</div>
|
||||||
<div class="back"><a href="/">На главную</a></div>
|
<div class="back"><a href="/">На главную</a></div>
|
||||||
|
|||||||
@@ -653,6 +653,10 @@ async function logAudit(req, action, target) {
|
|||||||
app.post('/api/auth/login', apiLimiter, async (req, res) => {
|
app.post('/api/auth/login', apiLimiter, async (req, res) => {
|
||||||
const rawUsername = typeof req.body?.username === 'string' ? req.body.username.trim().toLowerCase() : '';
|
const rawUsername = typeof req.body?.username === 'string' ? req.body.username.trim().toLowerCase() : '';
|
||||||
const password = String(req.body?.password || '');
|
const password = String(req.body?.password || '');
|
||||||
|
if (typeof req.body?.website === 'string' && req.body.website) {
|
||||||
|
await recordFailure(req, 'honeypot', 1, BAN_TTL_MS);
|
||||||
|
return res.status(401).json({ error: 'Неверный логин или пароль' });
|
||||||
|
}
|
||||||
if (!rawUsername || rawUsername.length > 100 || !password) {
|
if (!rawUsername || rawUsername.length > 100 || !password) {
|
||||||
return res.status(401).json({ error: 'Неверный логин или пароль' });
|
return res.status(401).json({ error: 'Неверный логин или пароль' });
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user