summaryrefslogtreecommitdiff
path: root/packages/backend/src/server/api/private
diff options
context:
space:
mode:
authorJohann150 <johann.galle@protonmail.com>2022-05-28 05:06:47 +0200
committerGitHub <noreply@github.com>2022-05-28 12:06:47 +0900
commit161659de5cd7633161b0788799b641ff6b7e55f9 (patch)
tree8dff8d5a7ae31a20d38e32ca6dcaa1b34eb95850 /packages/backend/src/server/api/private
parentenhance: clearly link documentation (diff)
downloadmisskey-161659de5cd7633161b0788799b641ff6b7e55f9.tar.gz
misskey-161659de5cd7633161b0788799b641ff6b7e55f9.tar.bz2
misskey-161659de5cd7633161b0788799b641ff6b7e55f9.zip
enhance: replace signin CAPTCHA with rate limit (#8740)
* enhance: rate limit works without signed in user * fix: make limit key required for limiter As before the fallback limiter key will be set from the endpoint name. * enhance: use limiter for signin * Revert "CAPTCHA求めるのは2fa認証が無効になっているときだけにした" This reverts commit 02a43a310f6ad0cc9e9beccc26e51ab5b339e15f. * Revert "feat: make captcha required when signin to improve security" This reverts commit b21b0580058c14532ff3f4033e2a9147643bfca6. * fix undefined reference * fix: better error message * enhance: only handle prefix of IPv6
Diffstat (limited to 'packages/backend/src/server/api/private')
-rw-r--r--packages/backend/src/server/api/private/signin.ts41
1 files changed, 20 insertions, 21 deletions
diff --git a/packages/backend/src/server/api/private/signin.ts b/packages/backend/src/server/api/private/signin.ts
index 0024b8ce3e..b304550e29 100644
--- a/packages/backend/src/server/api/private/signin.ts
+++ b/packages/backend/src/server/api/private/signin.ts
@@ -1,25 +1,21 @@
-import { randomBytes } from 'node:crypto';
import Koa from 'koa';
import bcrypt from 'bcryptjs';
import * as speakeasy from 'speakeasy';
-import { IsNull } from 'typeorm';
+import signin from '../common/signin.js';
import config from '@/config/index.js';
import { Users, Signins, UserProfiles, UserSecurityKeys, AttestationChallenges } from '@/models/index.js';
import { ILocalUser } from '@/models/entities/user.js';
import { genId } from '@/misc/gen-id.js';
-import { fetchMeta } from '@/misc/fetch-meta.js';
-import { verifyHcaptcha, verifyRecaptcha } from '@/misc/captcha.js';
import { verifyLogin, hash } from '../2fa.js';
-import signin from '../common/signin.js';
+import { randomBytes } from 'node:crypto';
+import { IsNull } from 'typeorm';
+import { limiter } from '../limiter.js';
export default async (ctx: Koa.Context) => {
ctx.set('Access-Control-Allow-Origin', config.url);
ctx.set('Access-Control-Allow-Credentials', 'true');
const body = ctx.request.body as any;
-
- const instance = await fetchMeta(true);
-
const username = body['username'];
const password = body['password'];
const token = body['token'];
@@ -29,6 +25,21 @@ export default async (ctx: Koa.Context) => {
ctx.body = { error };
}
+ try {
+ // not more than 1 attempt per second and not more than 10 attempts per hour
+ await limiter({ key: 'signin', duration: 60 * 60 * 1000, max: 10, minInterval: 1000 }, ctx.ip);
+ } catch (err) {
+ ctx.status = 429;
+ ctx.body = {
+ error: {
+ message: 'Too many failed attempts to sign in. Try again later.',
+ code: 'TOO_MANY_AUTHENTICATION_FAILURES',
+ id: '22d05606-fbcf-421a-a2db-b32610dcfd1b',
+ },
+ };
+ return;
+ }
+
if (typeof username !== 'string') {
ctx.status = 400;
return;
@@ -84,18 +95,6 @@ export default async (ctx: Koa.Context) => {
}
if (!profile.twoFactorEnabled) {
- if (instance.enableHcaptcha && instance.hcaptchaSecretKey) {
- await verifyHcaptcha(instance.hcaptchaSecretKey, body['hcaptcha-response']).catch(e => {
- ctx.throw(400, e);
- });
- }
-
- if (instance.enableRecaptcha && instance.recaptchaSecretKey) {
- await verifyRecaptcha(instance.recaptchaSecretKey, body['g-recaptcha-response']).catch(e => {
- ctx.throw(400, e);
- });
- }
-
if (same) {
signin(ctx, user);
return;
@@ -172,7 +171,7 @@ export default async (ctx: Koa.Context) => {
body.credentialId
.replace(/-/g, '+')
.replace(/_/g, '/'),
- 'base64',
+ 'base64'
).toString('hex'),
});