Ghost/ghost/core/test/e2e-api/admin/rate-limiting.test.js
Fabien 'egg' O'Carroll 2ff81cc5d3
🔒 Fixed rate limiting for user login (#15336)
refs https://github.com/TryGhost/Team/issues/1074

Rather than relying on the global block to stop malicious actors from
enumerating email addresses to determine who is and isn't a user, we
want our user login brute force protection to be on an IP basis,
rather than tied to the username.
2022-08-31 10:33:42 -04:00

75 lines
2.2 KiB
JavaScript

const {
agentProvider,
fixtureManager,
matchers: {
anyEtag
},
dbUtils,
configUtils
} = require('../../utils/e2e-framework');
describe('Sessions API', function () {
let agent;
before(async function () {
agent = await agentProvider.getAdminAPIAgent();
await fixtureManager.init();
});
it('Is rate limited to protect against brute forcing a users password', async function () {
await dbUtils.truncate('brute');
// +1 because this is a retry count, so we have one request + the retries, then blocked
const userLoginRateLimit = configUtils.config.get('spam').user_login.freeRetries + 1;
for (let i = 0; i < userLoginRateLimit; i++) {
await agent
.post('session/')
.body({
grant_type: 'password',
username: 'user@domain.tld',
password: 'parseword'
});
}
await agent
.post('session/')
.body({
grant_type: 'password',
username: 'user@domain.tld',
password: 'parseword'
})
.expectStatus(429)
.matchHeaderSnapshot({
etag: anyEtag
});
});
it('Is rate limited to protect against brute forcing whether a user exists', async function () {
await dbUtils.truncate('brute');
// +1 because this is a retry count, so we have one request + the retries, then blocked
const userLoginRateLimit = configUtils.config.get('spam').user_login.freeRetries + 1;
for (let i = 0; i < userLoginRateLimit; i++) {
await agent
.post('session/')
.body({
grant_type: 'password',
username: `user+${i}@domain.tld`,
password: `parseword`
});
}
await agent
.post('session/')
.body({
grant_type: 'password',
username: 'user@domain.tld',
password: 'parseword'
})
.expectStatus(429)
.matchHeaderSnapshot({
etag: anyEtag
});
});
});