added rate-limiting
This commit is contained in:
		
							parent
							
								
									0421691545
								
							
						
					
					
						commit
						76aa016ef6
					
				
							
								
								
									
										1913
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1913
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										10
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								package.json
									
									
									
									
									
								
							| @ -12,6 +12,7 @@ | |||||||
|     "test": "run-p --race dev cy:run" |     "test": "run-p --race dev cy:run" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|  |     "@babel/runtime": "^7.10.3", | ||||||
|     "bcrypt": "^4.0.1", |     "bcrypt": "^4.0.1", | ||||||
|     "body-parser": "^1.19.0", |     "body-parser": "^1.19.0", | ||||||
|     "cl-editor": "^2.0.0", |     "cl-editor": "^2.0.0", | ||||||
| @ -26,15 +27,22 @@ | |||||||
|     "mongoose-fuzzy-searching": "^1.3.1", |     "mongoose-fuzzy-searching": "^1.3.1", | ||||||
|     "passport": "^0.4.1", |     "passport": "^0.4.1", | ||||||
|     "passport-local": "^1.0.0", |     "passport-local": "^1.0.0", | ||||||
|  |     "rate-limiter-flexible": "^2.1.7", | ||||||
|     "session-file-store": "^1.4.0", |     "session-file-store": "^1.4.0", | ||||||
|     "sirv": "^0.4.0" |     "sirv": "^0.4.0" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|  |     "@babel/core": "^7.10.3", | ||||||
|  |     "@babel/plugin-proposal-object-rest-spread": "^7.10.3", | ||||||
|  |     "@babel/plugin-syntax-dynamic-import": "^7.8.3", | ||||||
|  |     "@babel/preset-env": "^7.10.3", | ||||||
|  |     "babel-loader": "^8.1.0", | ||||||
|     "npm-run-all": "^4.1.5", |     "npm-run-all": "^4.1.5", | ||||||
|     "sapper": "^0.27.0", |     "sapper": "^0.27.0", | ||||||
|     "svelte": "^3.0.0", |     "svelte": "^3.0.0", | ||||||
|     "svelte-loader": "^2.9.0", |     "svelte-loader": "^2.9.0", | ||||||
|     "webpack": "^4.7.0" |     "terser-webpack-plugin": "^3.0.6", | ||||||
|  |     "webpack": "^4.43.0" | ||||||
|   }, |   }, | ||||||
|   "repository": { |   "repository": { | ||||||
|     "type": "git", |     "type": "git", | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ import mongoose from 'mongoose'; | |||||||
| import passport from 'passport'; | import passport from 'passport'; | ||||||
| import { Strategy } from 'passport-local'; | import { Strategy } from 'passport-local'; | ||||||
| import sessionFileStore from 'session-file-store'; | import sessionFileStore from 'session-file-store'; | ||||||
|  | import { RateLimiterMemory } from 'rate-limiter-flexible'; | ||||||
| import fileUpload from 'express-fileupload'; | import fileUpload from 'express-fileupload'; | ||||||
| import helmet from 'helmet'; | import helmet from 'helmet'; | ||||||
| import Article from './models/article.js'; | import Article from './models/article.js'; | ||||||
| @ -55,6 +56,32 @@ passport.use(new Strategy((username, password, done) => { | |||||||
|     }); |     }); | ||||||
| })); | })); | ||||||
| 
 | 
 | ||||||
|  | const loginAttemptRateLimiter = new RateLimiterMemory({ | ||||||
|  |     points: 5, | ||||||
|  |     duration: 3600, | ||||||
|  |     blockDuration: 60 | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | const registerRateLimiter = new RateLimiterMemory({ | ||||||
|  |     points: 1, | ||||||
|  |     duration: 60, | ||||||
|  |     blockDuration: 60 | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | const rateLimiterMiddleware = rl => async function (req, res, next) { | ||||||
|  |     try { | ||||||
|  |         await rl.consume(req.ip); | ||||||
|  |         next(); | ||||||
|  |     } catch (err) { | ||||||
|  |         res.writeHead(429, { | ||||||
|  |             'Content-Type': 'application/json' | ||||||
|  |         }); | ||||||
|  |         res.end(JSON.stringify({ | ||||||
|  |             message: 'Too Many Requests' | ||||||
|  |         })); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| const isAuthor = function(req, res, next) { | const isAuthor = function(req, res, next) { | ||||||
|     if (req.user) { |     if (req.user) { | ||||||
|         if (req.user.author) { |         if (req.user.author) { | ||||||
| @ -148,6 +175,17 @@ express() | |||||||
|                 })); |                 })); | ||||||
|                 return false; |                 return false; | ||||||
|             } |             } | ||||||
|  |             try { | ||||||
|  |                 await registerRateLimiter.consume(); | ||||||
|  |             } catch (err) { | ||||||
|  |                 res.writeHead(429, { | ||||||
|  |                     'Content-Type': 'application/json' | ||||||
|  |                 }); | ||||||
|  |                 res.end(JSON.stringify({ | ||||||
|  |                     message: `Too Many Requests` | ||||||
|  |                 })); | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|             try { |             try { | ||||||
|                 const user = await User.findOne({ username: req.body.username }); |                 const user = await User.findOne({ username: req.body.username }); | ||||||
|                 if (user) { |                 if (user) { | ||||||
| @ -181,6 +219,7 @@ express() | |||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     .post('/cms/login', |     .post('/cms/login', | ||||||
|  |         rateLimiterMiddleware(loginAttemptRateLimiter), | ||||||
|         passport.authenticate('local', { failWithError: true }), |         passport.authenticate('local', { failWithError: true }), | ||||||
|         function(req, res, next) { |         function(req, res, next) { | ||||||
|             // handle success
 |             // handle success
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user