Page MenuHomePhabricator

[token-server] Implement rate limiting by IP
ClosedPublic

Authored by bytesofman on Aug 30 2024, 14:31.

Details

Reviewers
emack
Group Reviewers
Restricted Project
Commits
rABC4a17fbed5dfd: [token-server] Implement rate limiting by IP
Summary

Getting scripted faucet hits again. Implement rate limiting by IP address.

Test Plan

npm test. Unfortunately I am not sure how to test this without just testing the dependency. Dependency is well maintained.

Note though the teamcity failure when rate limiting was implemented on all routes -- unit tests failed as, well, we have more than 10 unit tests and they are executed immediately.

Still, expect to have iterations to tweak this implementation depending on what we see.

Diff Detail

Repository
rABC Bitcoin ABC
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

Failed tests logs:

====== routes.js: /claimxec/:address sends an airdrop if called with an address with no tx history.routes.js /claimxec/:address sends an airdrop if called with an address with no tx history ======
Error: expected 200 "OK", got 429 "Too Many Requests"
    at Context.<anonymous> (test/routes.test.ts:272:14)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
----
    at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
    at /work/apps/token-server/node_modules/supertest/lib/test.js:308:13
    at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
    at Test.assert (node_modules/supertest/lib/test.js:164:23)
    at localAssert (node_modules/supertest/lib/test.js:120:14)
    at fn (node_modules/supertest/lib/test.js:125:7)
    at Test.callback (node_modules/superagent/src/node/index.js:925:3)
    at IncomingMessage.<anonymous> (node_modules/superagent/src/node/index.js:1166:18)
    at IncomingMessage.emit (node:events:531:35)
    at IncomingMessage.emit (node:domain:488:12)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at processTicksAndRejections (node:internal/process/task_queues:82:21)
====== routes.js: /claimxec/:address returns expected error status on chronik error.routes.js /claimxec/:address returns expected error status on chronik error ======
Error: expected 500 "Internal Server Error", got 429 "Too Many Requests"
    at Context.<anonymous> (test/routes.test.ts:283:14)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
----
    at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
    at /work/apps/token-server/node_modules/supertest/lib/test.js:308:13
    at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
    at Test.assert (node_modules/supertest/lib/test.js:164:23)
    at localAssert (node_modules/supertest/lib/test.js:120:14)
    at fn (node_modules/supertest/lib/test.js:125:7)
    at Test.callback (node_modules/superagent/src/node/index.js:925:3)
    at IncomingMessage.<anonymous> (node_modules/superagent/src/node/index.js:1166:18)
    at IncomingMessage.emit (node:events:531:35)
    at IncomingMessage.emit (node:domain:488:12)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at processTicksAndRejections (node:internal/process/task_queues:82:21)
====== routes.js: /claimxec/:address returns expected error status if called with invalid address.routes.js /claimxec/:address returns expected error status if called with invalid address ======
Error: expected 500 "Internal Server Error", got 429 "Too Many Requests"
    at Context.<anonymous> (test/routes.test.ts:293:14)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
----
    at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
    at /work/apps/token-server/node_modules/supertest/lib/test.js:308:13
    at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
    at Test.assert (node_modules/supertest/lib/test.js:164:23)
    at localAssert (node_modules/supertest/lib/test.js:120:14)
    at fn (node_modules/supertest/lib/test.js:125:7)
    at Test.callback (node_modules/superagent/src/node/index.js:925:3)
    at IncomingMessage.<anonymous> (node_modules/superagent/src/node/index.js:1166:18)
    at IncomingMessage.emit (node:events:531:35)
    at IncomingMessage.emit (node:domain:488:12)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at processTicksAndRejections (node:internal/process/task_queues:82:21)
====== routes.js: We get a rendered blockie for a valid token image request.routes.js We get a rendered blockie for a valid token image request ======
Error: expected 200 "OK", got 429 "Too Many Requests"
    at Context.<anonymous> (test/routes.test.ts:305:14)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
----
    at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
    at /work/apps/token-server/node_modules/supertest/lib/test.js:308:13
    at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
    at Test.assert (node_modules/supertest/lib/test.js:164:23)
    at localAssert (node_modules/supertest/lib/test.js:120:14)
    at fn (node_modules/supertest/lib/test.js:125:7)
    at Test.callback (node_modules/superagent/src/node/index.js:925:3)
    at IncomingMessage.<anonymous> (node_modules/superagent/src/node/index.js:1166:18)
    at IncomingMessage.emit (node:events:531:35)
    at IncomingMessage.emit (node:domain:488:12)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at processTicksAndRejections (node:internal/process/task_queues:82:21)
====== routes.js: We get a 404 for an invalid token icon requeset.routes.js We get a 404 for an invalid token icon requeset ======
Error: expected 404 "Not Found", got 429 "Too Many Requests"
    at Context.<anonymous> (test/routes.test.ts:313:14)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
----
    at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
    at /work/apps/token-server/node_modules/supertest/lib/test.js:308:13
    at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
    at Test.assert (node_modules/supertest/lib/test.js:164:23)
    at localAssert (node_modules/supertest/lib/test.js:120:14)
    at fn (node_modules/supertest/lib/test.js:125:7)
    at Test.callback (node_modules/superagent/src/node/index.js:925:3)
    at IncomingMessage.<anonymous> (node_modules/superagent/src/node/index.js:1166:18)
    at IncomingMessage.emit (node:events:531:35)
    at IncomingMessage.emit (node:domain:488:12)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at processTicksAndRejections (node:internal/process/task_queues:82:21)
====== routes.js: We get a 404 for any request not handled by other endpoints.routes.js We get a 404 for any request not handled by other endpoints ======
Error: expected 404 "Not Found", got 429 "Too Many Requests"
    at Context.<anonymous> (test/routes.test.ts:322:14)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
----
    at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
    at /work/apps/token-server/node_modules/supertest/lib/test.js:308:13
    at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
    at Test.assert (node_modules/supertest/lib/test.js:164:23)
    at localAssert (node_modules/supertest/lib/test.js:120:14)
    at fn (node_modules/supertest/lib/test.js:125:7)
    at Test.callback (node_modules/superagent/src/node/index.js:925:3)
    at IncomingMessage.<anonymous> (node_modules/superagent/src/node/index.js:1166:18)
    at IncomingMessage.emit (node:events:531:35)
    at IncomingMessage.emit (node:domain:488:12)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at processTicksAndRejections (node:internal/process/task_queues:82:21)
====== routes.js: We receive a 500 error if post has no file.routes.js We receive a 500 error if post has no file ======
Error: expected 500 "Internal Server Error", got 429 "Too Many Requests"
    at Context.<anonymous> (test/routes.test.ts:345:14)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
----
    at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
    at /work/apps/token-server/node_modules/supertest/lib/test.js:308:13
    at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
    at Test.assert (node_modules/supertest/lib/test.js:164:23)
    at localAssert (node_modules/supertest/lib/test.js:120:14)
    at fn (node_modules/supertest/lib/test.js:125:7)
    at Test.callback (node_modules/superagent/src/node/index.js:925:3)
    at IncomingMessage.<anonymous> (node_modules/superagent/src/node/index.js:1166:18)
    at IncomingMessage.emit (node:events:531:35)
    at IncomingMessage.emit (node:domain:488:12)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at processTicksAndRejections (node:internal/process/task_queues:82:21)
====== routes.js: We receive a 500 error if image upload exceeds server limit.routes.js We receive a 500 error if image upload exceeds server limit ======
Error: expected 500 "Internal Server Error", got 429 "Too Many Requests"
    at Context.<anonymous> (test/routes.test.ts:369:14)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
----
    at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
    at /work/apps/token-server/node_modules/supertest/lib/test.js:308:13
    at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
    at Test.assert (node_modules/supertest/lib/test.js:164:23)
    at localAssert (node_modules/supertest/lib/test.js:120:14)
    at fn (node_modules/supertest/lib/test.js:125:7)
    at Test.callback (node_modules/superagent/src/node/index.js:925:3)
    at IncomingMessage.<anonymous> (node_modules/superagent/src/node/index.js:1166:18)
    at IncomingMessage.emit (node:events:531:35)
    at IncomingMessage.emit (node:domain:488:12)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at processTicksAndRejections (node:internal/process/task_queues:82:21)
====== routes.js: We can accept a png upload and resize it on the server.routes.js We can accept a png upload and resize it on the server ======
Error: expected 200 "OK", got 429 "Too Many Requests"
    at Context.<anonymous> (test/routes.test.ts:398:14)
----
    at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
    at /work/apps/token-server/node_modules/supertest/lib/test.js:308:13
    at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
    at Test.assert (node_modules/supertest/lib/test.js:164:23)
    at localAssert (node_modules/supertest/lib/test.js:120:14)
    at fn (node_modules/supertest/lib/test.js:125:7)
    at Test.callback (node_modules/superagent/src/node/index.js:925:3)
    at IncomingMessage.<anonymous> (node_modules/superagent/src/node/index.js:1166:18)
    at IncomingMessage.emit (node:events:531:35)
    at IncomingMessage.emit (node:domain:488:12)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at processTicksAndRejections (node:internal/process/task_queues:82:21)
====== routes.js: We can accept a png upload from Cashtab extension and resize it on the server.routes.js We can accept a png upload from Cashtab extension and resize it on the server ======
Error: expected 200 "OK", got 429 "Too Many Requests"
    at Context.<anonymous> (test/routes.test.ts:433:14)
----
    at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
    at /work/apps/token-server/node_modules/supertest/lib/test.js:308:13
    at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
    at Test.assert (node_modules/supertest/lib/test.js:164:23)
    at localAssert (node_modules/supertest/lib/test.js:120:14)
    at fn (node_modules/supertest/lib/test.js:125:7)
    at Test.callback (node_modules/superagent/src/node/index.js:925:3)
    at IncomingMessage.<anonymous> (node_modules/superagent/src/node/index.js:1166:18)
    at IncomingMessage.emit (node:events:531:35)
    at IncomingMessage.emit (node:domain:488:12)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at processTicksAndRejections (node:internal/process/task_queues:82:21)
====== routes.js: A png upload request from a non-whitelisted domain is rejected.routes.js A png upload request from a non-whitelisted domain is rejected ======
Error: expected 500 "Internal Server Error", got 429 "Too Many Requests"
    at Context.<anonymous> (test/routes.test.ts:465:14)
----
    at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
    at /work/apps/token-server/node_modules/supertest/lib/test.js:308:13
    at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
    at Test.assert (node_modules/supertest/lib/test.js:164:23)
    at localAssert (node_modules/supertest/lib/test.js:120:14)
    at fn (node_modules/supertest/lib/test.js:125:7)
    at Test.callback (node_modules/superagent/src/node/index.js:925:3)
    at IncomingMessage.<anonymous> (node_modules/superagent/src/node/index.js:1166:18)
    at IncomingMessage.emit (node:events:531:35)
    at IncomingMessage.emit (node:domain:488:12)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at processTicksAndRejections (node:internal/process/task_queues:82:21)
====== routes.js: If the token icon already exists on the server, the /new request is rejected.routes.js If the token icon already exists on the server, the /new request is rejected ======
Error: expected 200 "OK", got 429 "Too Many Requests"
    at Context.<anonymous> (test/routes.test.ts:495:14)
----
    at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
    at /work/apps/token-server/node_modules/supertest/lib/test.js:308:13
    at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
    at Test.assert (node_modules/supertest/lib/test.js:164:23)
    at localAssert (node_modules/supertest/lib/test.js:120:14)
    at fn (node_modules/supertest/lib/test.js:125:7)
    at Test.callback (node_modules/superagent/src/node/index.js:925:3)
    at IncomingMessage.<anonymous> (node_modules/superagent/src/node/index.js:1166:18)
    at IncomingMessage.emit (node:events:531:35)
    at IncomingMessage.emit (node:domain:488:12)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at processTicksAndRejections (node:internal/process/task_queues:82:21)
====== routes.js: We only accept pngs at the /new post endpoint.routes.js We only accept pngs at the /new post endpoint ======
Error: expected 403 "Forbidden", got 429 "Too Many Requests"
    at Context.<anonymous> (test/routes.test.ts:545:14)
----
    at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
    at /work/apps/token-server/node_modules/supertest/lib/test.js:308:13
    at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
    at Test.assert (node_modules/supertest/lib/test.js:164:23)
    at localAssert (node_modules/supertest/lib/test.js:120:14)
    at fn (node_modules/supertest/lib/test.js:125:7)
    at Test.callback (node_modules/superagent/src/node/index.js:925:3)
    at IncomingMessage.<anonymous> (node_modules/superagent/src/node/index.js:1166:18)
    at IncomingMessage.emit (node:events:531:35)
    at IncomingMessage.emit (node:domain:488:12)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at processTicksAndRejections (node:internal/process/task_queues:82:21)
====== routes.js: Error in sharp resize is handled.routes.js Error in sharp resize is handled ======
Error: expected 500 "Internal Server Error", got 429 "Too Many Requests"
    at Context.<anonymous> (test/routes.test.ts:569:14)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
----
    at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
    at /work/apps/token-server/node_modules/supertest/lib/test.js:308:13
    at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
    at Test.assert (node_modules/supertest/lib/test.js:164:23)
    at localAssert (node_modules/supertest/lib/test.js:120:14)
    at fn (node_modules/supertest/lib/test.js:125:7)
    at Test.callback (node_modules/superagent/src/node/index.js:925:3)
    at IncomingMessage.<anonymous> (node_modules/superagent/src/node/index.js:1166:18)
    at IncomingMessage.emit (node:events:531:35)
    at IncomingMessage.emit (node:domain:488:12)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at processTicksAndRejections (node:internal/process/task_queues:82:21)

Each failure log is accessible here:
routes.js: /claimxec/:address sends an airdrop if called with an address with no tx history.routes.js /claimxec/:address sends an airdrop if called with an address with no tx history
routes.js: /claimxec/:address returns expected error status on chronik error.routes.js /claimxec/:address returns expected error status on chronik error
routes.js: /claimxec/:address returns expected error status if called with invalid address.routes.js /claimxec/:address returns expected error status if called with invalid address
routes.js: We get a rendered blockie for a valid token image request.routes.js We get a rendered blockie for a valid token image request
routes.js: We get a 404 for an invalid token icon requeset.routes.js We get a 404 for an invalid token icon requeset
routes.js: We get a 404 for any request not handled by other endpoints.routes.js We get a 404 for any request not handled by other endpoints
routes.js: We receive a 500 error if post has no file.routes.js We receive a 500 error if post has no file
routes.js: We receive a 500 error if image upload exceeds server limit.routes.js We receive a 500 error if image upload exceeds server limit
routes.js: We can accept a png upload and resize it on the server.routes.js We can accept a png upload and resize it on the server
routes.js: We can accept a png upload from Cashtab extension and resize it on the server.routes.js We can accept a png upload from Cashtab extension and resize it on the server
routes.js: A png upload request from a non-whitelisted domain is rejected.routes.js A png upload request from a non-whitelisted domain is rejected
routes.js: If the token icon already exists on the server, the /new request is rejected.routes.js If the token icon already exists on the server, the /new request is rejected
routes.js: We only accept pngs at the /new post endpoint.routes.js We only accept pngs at the /new post endpoint
routes.js: Error in sharp resize is handled.routes.js Error in sharp resize is handled

only implement rate limit on the xec claim route

This revision is now accepted and ready to land.Aug 30 2024, 14:49