diff --git a/docs/en/install/README.md b/docs/en/install/README.md index 6178e4db3d..81afb6599b 100644 --- a/docs/en/install/README.md +++ b/docs/en/install/README.md @@ -386,7 +386,7 @@ RSSHub supports access control via access key/code, whitelisting and blacklistin - `BLACKLIST`: the blacklist -White/blacklisting support IP and route as values. Use `,` as the delimiter to separate multiple values, eg: `WHITELIST=1.1.1.1,2.2.2.2,/qdaily/column/59` +White/blacklisting support IP, route and UA as values, fuzzy matching. Use `,` as the delimiter to separate multiple values, eg: `WHITELIST=1.1.1.1,2.2.2.2,/qdaily/column/59` #### Access Key/Code diff --git a/docs/install/README.md b/docs/install/README.md index 0f1333d576..e42db68eea 100644 --- a/docs/install/README.md +++ b/docs/install/README.md @@ -413,7 +413,7 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行 - `BLACKLIST`: 黑名单 -黑白名单支持 IP 和路由,设置多项时用英文逗号 `,` 隔开,例如 `WHITELIST=1.1.1.1,2.2.2.2,/qdaily/column/59` +黑白名单支持 IP、路由和 UA,模糊匹配,设置多项时用英文逗号 `,` 隔开,例如 `WHITELIST=1.1.1.1,2.2.2.2,/qdaily/column/59` #### 访问密钥 / 码 diff --git a/lib/middleware/access-control.js b/lib/middleware/access-control.js index 81459d8634..b82c3fbf9f 100644 --- a/lib/middleware/access-control.js +++ b/lib/middleware/access-control.js @@ -11,6 +11,7 @@ const reject = (ctx) => { module.exports = async (ctx, next) => { const ip = ctx.ips[0] || ctx.ip; const requestPath = ctx.request.path; + const requestUA = ctx.request.header['user-agent']; const accessKey = ctx.query.key; const accessCode = ctx.query.code; @@ -38,13 +39,13 @@ module.exports = async (ctx, next) => { } if (config.whitelist) { - if (config.whitelist.includes(ip) || config.whitelist.includes(requestPath)) { + if (config.whitelist.find((white) => ip.includes(white) || requestPath.includes(white) || requestUA.includes(white))) { return await grant(); } } if (config.blacklist) { - if (!(config.blacklist.includes(ip) || config.blacklist.includes(requestPath))) { + if (!config.blacklist.find((black) => ip.includes(black) || requestPath.includes(black) || requestUA.includes(black))) { return await grant(); } } diff --git a/test/middleware/access-control.js b/test/middleware/access-control.js index 41fec5bddd..83bfe5793c 100644 --- a/test/middleware/access-control.js +++ b/test/middleware/access-control.js @@ -20,7 +20,7 @@ describe('access-control', () => { it(`blacklist`, async () => { const key = '1L0veRSSHub'; const code = md5('/test/2' + key); - process.env.BLACKLIST = '/test/1,233.233.233.233'; + process.env.BLACKLIST = 'est/1,233.233.233.,black'; process.env.ACCESS_KEY = key; server = require('../../lib/index'); const request = supertest(server); @@ -31,12 +31,18 @@ describe('access-control', () => { const response12 = await request.get('/test/1').set('X-Forwarded-For', '233.233.233.233'); checkBlock(response12); + const response13 = await request.get('/test/1').set('user-agent', 'blackua'); + checkBlock(response13); + const response21 = await request.get('/test/2'); expect(response21.status).toBe(200); const response22 = await request.get('/test/2').set('X-Forwarded-For', '233.233.233.233'); checkBlock(response22); + const response23 = await request.get('/test/2').set('user-agent', 'blackua'); + checkBlock(response23); + // wrong key/code, not on blacklist const response311 = await request.get(`/test/2?key=wrong+${key}`); expect(response311.status).toBe(200); @@ -62,7 +68,7 @@ describe('access-control', () => { it(`whitelist`, async () => { const key = '1L0veRSSHub'; const code = md5('/test/2' + key); - process.env.WHITELIST = '/test/1,233.233.233.233'; + process.env.WHITELIST = 'est/1,233.233.233.,white'; process.env.ACCESS_KEY = key; server = require('../../lib/index'); const request = supertest(server); @@ -79,12 +85,18 @@ describe('access-control', () => { const response12 = await request.get('/test/1').set('X-Forwarded-For', '233.233.233.233'); expect(response12.status).toBe(200); + const response13 = await request.get('/test/1').set('user-agent', 'whiteua'); + expect(response13.status).toBe(200); + const response21 = await request.get('/test/2'); checkBlock(response21); const response22 = await request.get('/test/2').set('X-Forwarded-For', '233.233.233.233'); expect(response22.status).toBe(200); + const response23 = await request.get('/test/2').set('user-agent', 'whiteua'); + expect(response23.status).toBe(200); + // wrong key/code, not on whitelist const response311 = await request.get(`/test/2?code=wrong+${code}`); checkBlock(response311);