{"id":13520446,"url":"https://github.com/abriginets/umbress","last_synced_at":"2025-04-08T23:41:07.142Z","repository":{"id":40731326,"uuid":"223183913","full_name":"abriginets/umbress","owner":"abriginets","description":"Blazing fast ExpressJS anti-DDoS middleware ⚡","archived":false,"fork":false,"pushed_at":"2024-05-12T16:11:17.000Z","size":2143,"stargazers_count":49,"open_issues_count":4,"forks_count":12,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-07T14:18:36.565Z","etag":null,"topics":["abuseipdb","anti-ddos","blacklist","ddos","ddos-attacks","express-middleware","expressjs","mitigation","node","nodejs","rate-limiter"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/abriginets.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-21T13:45:19.000Z","updated_at":"2025-04-07T09:53:31.000Z","dependencies_parsed_at":"2023-02-03T03:45:55.878Z","dependency_job_id":"67199b08-09c4-4e9a-b33b-0cb8352ae945","html_url":"https://github.com/abriginets/umbress","commit_stats":null,"previous_names":["jamesjgoodwin/umbress"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abriginets%2Fumbress","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abriginets%2Fumbress/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abriginets%2Fumbress/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abriginets%2Fumbress/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/abriginets","download_url":"https://codeload.github.com/abriginets/umbress/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247947823,"owners_count":21023058,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["abuseipdb","anti-ddos","blacklist","ddos","ddos-attacks","express-middleware","expressjs","mitigation","node","nodejs","rate-limiter"],"created_at":"2024-08-01T05:02:20.971Z","updated_at":"2025-04-08T23:41:07.124Z","avatar_url":"https://github.com/abriginets.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003eUmbress\u003c/h2\u003e\n  \u003cdiv style=\"display: flex; align-items: center; justify-content: center;\"\u003e\n    \u003ca href=\"https://github.com/JamesJGoodwin/umbress/actions\"\u003e\n      \u003cimg src=\"https://github.com/JamesJGoodwin/umbress/workflows/build/badge.svg\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://coveralls.io/github/JamesJGoodwin/umbress?branch=master\" target=\"_blank\"\u003e\n      \u003cimg src=\"https://coveralls.io/repos/github/JamesJGoodwin/umbress/badge.svg?branch=master\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://david-dm.org/JamesJGoodwin/umbress\" target=\"_blank\"\u003e\n      \u003cimg src=\"https://david-dm.org/JamesJGoodwin/umbress.svg\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.npmjs.com/package/umbress\" target=\"_blank\"\u003e\n      \u003cimg src=\"https://img.shields.io/npm/v/umbress.svg\" /\u003e\n    \u003c/a\u003e\n  \u003c/div\u003e\n  \u003c/br\u003e\n  \u003c/br\u003e\n\u003c/div\u003e\n\n\u003cb\u003eUmbress\u003c/b\u003e is a fast and easy-to-use DDoS protection and mitigation Express.js middleware. It has several techniques\nof detection and mitigation like crawlers authenticity checks, malicious IP addresses access mitigation (based on \u003ca href=\"https://www.abuseipdb.com/\" target=\"_blank\"\u003eAbuseIPDB\u003c/a\u003e data), advanced client-side JavaScript challenging, GeoIP manager, etc.\n\n## Features\n- Recaptcha\n- Rate-limiter\n- GeoIP manager\n- Malicious IP checker\n- Crawlers authenticity checker\n- Whitelists and blacklists for single IPs or subnets\n- Client-side JavaScript-challenging (like CloudFlare's UAM)\n\n## Requirements\n\n- Node.js 10+\n- \u003ca href=\"https://github.com/expressjs/express\" target=\"_blank\"\u003eExpress\u003c/a\u003e 4+\n- \u003ca href=\"https://redis.io/\" target=\"_blank\"\u003eRedis\u003c/a\u003e 4+\n\n## Benchmarks\n\nSince this software is designed to work in highly loaded systems, it should provide high availability and not affect the overall performance of the application in which it works. Mitigating threats and protecting your application from DDoS attacks requires some amount of computing resources, which this software may take from your application in order to defend it. The following table provides information about how much ExpressJS-based application performance can degrade with various modules enabled. Benchmark ran on i5-8250U, 8GB RAM and NVMe drive. Numbers provided below are the avarage values calculated from 10 independent iterations. Each iteration ran using \u003ca href=\"https://httpd.apache.org/docs/2.4/programs/ab.html\" target=\"_blank\"\u003eApache Bench\u003c/a\u003e using the next command:\n```bash\nab -n 10000 -c 200 'http://localhost:3000/{endpoint}'\n```\n\n| * | Requests  | Time per request | Performance degradation\n| ------------- | ------------- | ------------- | ------------- |\n| Blank Express App | 6328.68 req/s  | 31.46ms  | - |\n| **Ratelimiter** | 4627.07 req/s  | 43.97ms  | 26.89% |\n| **Automated Checks** | 3468.94 req/s | 59.37ms | 45.19% |\n| **Recaptcha** | 3540.40 req/s | 57.60ms | 44.06% |\n\nRoughly speaking, *performance degradation* percentages are the price you are paying to mitigate and protect you from DDoS attacks.\n\n\u003csub\u003eNote that this results may vary depending on your OS, CPU, RAM, etc.\u003c/sub\u003e \n\n## Install\n\n```\n$ npm install umbress --save\n```\n\n## Usage\n\n**❗ Important:** Umbress relies on another middleware in some combinations of configuration so when you set `advancedClientChallenging.enabled = true`, `recaptcha.enabled = true`, `checkSuspiciousAddresses.action = 'check' | 'recaptcha'`, `geoipRule.action = 'check' | 'recaptcha'` and `geoipRule.otherwise = 'check' | 'recaptcha'` it is mandatory to add the next lines of code before using Umbress:\n\n```typescript\n// ExpressJS above 4.16.0\napp.use(express.urlencoded({ extended: true }))\n\n// ExpressJS below 4.16.0\nimport bodyParser from 'body-parser'\napp.use(bodyParser.urlencoded({ extended: false }))\n```\n\n#### Case #1: Simple rate-limiter\nRecommended to use only if you have no choice but to expose ExpressJS application without proxying all the traffic through Nginx, i.e.\n\n```typescript\nimport express from 'express'\nimport umbress from 'umbress'\n\nconst app = express()\n\napp.use(\n  umbress({\n    rateLimiter: {\n      enabled: true\n    }\n  })\n)\n```\n\nDefault policy is *no more than 60 requests per minute; 30 seconds ban otherwise*, but can be configured in any other way. Ratelimiter is semantic-friendly - it will throw 429 Too Many Requests and provide visitor with `Retry-After` header.\n\n#### Case #2: White and black lists\nYou can block access for some IP's (blacklist) or allow it to only specified ones (whitelist).\n\n**Note:** whitelist and blacklist can't be used at the same time. If you enabled both then only whitelist will be applied and blacklist will be ignored.\n\n```typescript\nimport express from 'express'\nimport umbress from 'umbress'\n\nconst app = express()\n\napp.use(\n  umbress({\n    whitelist: ['2a03:2880::/32', '12.34.65.0/24', '8.8.8.8']\n  })\n)\n```\n\n#### Case #3 Automated browser checking\nEvery user (except search engine's bots and crawlers) will be promted with automated client-side browser checks. This process is fully automatic and works just like CloudFlare's UAM. Visitors will be seeing pre-defined message, but you can easilly modify it by yourself.\n\n**Attention Nginx users!** If your ExpressJS app is behind Nginx then additional configuration is mandatory in order for this part of module to work. Add next lines to your `location` directive:\n\n```nginx\nproxy_set_header X-Forwarded-Proto $scheme;\nproxy_set_header X-Forwarded-For $remote_addr;\nproxy_set_header X-Forwarded-Hostname $host;\n```\n\nNow the code example:\n\n```typescript\nimport express from 'express'\nimport umbress from 'umbress'\n\nconst app = express()\n\napp.use(express.urlencoded({ extended: true }))\n\napp.use(\n  umbress({\n    advancedClientChallenging: {\n      enabled: true,\n      cookieTtl: 30\n    }\n  })\n)\n```\n\nWhen users visiting your website for the first time, they will receive a unique cookie and will be seeing \u003ca href=\"https://i.imgur.com/puUoVck.png\" target=\"_blank\"\u003ethis page\u003c/a\u003e. 5 seconds is needed to perform some computational tasks that only JavaScript-enabled visitors can solve. After 4-5 seconds the visitor will be redirected to the page by POSTing to it and receive the second cookie. Then visitor will be redirected to the requested URL immediatelly. Cookies TTL is 30 days, after it's expiration visitor will have to complete this challenge again.\n\n#### Case #4: Most complex and secure way\n\n*To proceed with this configuration you need to sign up for AbuseIPDB*\n\nUmbress is tied up with AbuseIPDB database of IP addresses. When someone is hitting your website for the first time, Umbress will send a request to AbuseIPDB to check if IP address is malicious and being an origin of bad traffic. If so, the bad IP will be banned for a user-specified time. By default it is 3600 seconds or 1 hour. But if you enabled automated checking before then it's possible not to block user undoubtedly but ask him to pass an automated check to ensure he is using a real browser (this is the recommended way since \u003ca href=\"https://en.wikipedia.org/wiki/IPv4_address_exhaustion\" target=\"_blank\"\u003eIPv4 addresses are exhausting\u003c/a\u003e and many users are getting their access to the web through the NAT and bad neighbour activity can result in getting everyone in certain NAT blocked which is not what you probably want)\n\n```typescript\nimport express from 'express'\nimport umbress from 'umbress'\n\nconst app = express()\n\napp.use(express.urlencoded({ extended: true }))\n\napp.use(\n  umbress({\n    checkSuspiciousAddresses: {\n      enabled: true,\n      token: process.env.ABUSEIPDB_TOKEN,\n      action: 'check',\n      cookieTtl: 1\n    }\n  })\n)\n```\n\n### Case #5: Under heavy JS-based attack\n\nWhen someone wants your web application to go down really bad, they might use headless browsers to solve the client-side task, receive the cookies and use them to bypass automated checking. Under such circumstances you have no choice but to apply geographically-based blocking. For example, your website works in CIS area, but mostly attack originated from China:\n\n```typescript\nimport express from 'express'\nimport umbress from 'umbress'\n\nconst app = express()\n\napp.use(\n  umbress({\n    geoipRule: {\n      type: 'whitelist',\n      codes: ['RU', 'UA', 'BY', 'KZ'],\n      action: 'pass',\n      otherwise: 'block'\n    }\n  })\n)\n```\n\nBlacklisting is available as well:\n\n```typescript\nimport express from 'express'\nimport umbress from 'umbress'\n\nconst app = express()\n\napp.use(\n  umbress({\n    geoipRule: {\n      type: 'blacklist',\n      codes: ['CN'],\n      action: 'block',\n      otherwise: 'pass'\n    }\n  })\n)\n```\n\n## License\n\nCopyright 2020 JamesJGoodwin. Licensed \u003ca href=\"https://github.com/JamesJGoodwin/umbress/blob/master/LICENSE\"\u003eMIT\u003c/a\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabriginets%2Fumbress","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabriginets%2Fumbress","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabriginets%2Fumbress/lists"}