-
-
Notifications
You must be signed in to change notification settings - Fork 57
Bypass few common security attacks to Donut Server #146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: development
Are you sure you want to change the base?
Conversation
Signed-off-by: K mehant <411843@student.nitandhra.ac.in>
@jaskiratsingh2000 @vaibhavdaren @devesh-verma |
We shall add similar fixes to the Donut Frontend too using Nginx |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to be added in middleware layer.
…ity headers Signed-off-by: K mehant <411843@student.nitandhra.ac.in>
Signed-off-by: K mehant <411843@student.nitandhra.ac.in>
Signed-off-by: K mehant <411843@student.nitandhra.ac.in>
Signed-off-by: K mehant <411843@student.nitandhra.ac.in>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vaibhavdaren @Rupeshiya @devesh-verma I have added relevant comments explaining my approach.
I have tested it personally, it seems working fine.
REDIS_HOST="redis" | ||
REDIS_PORT=6379 | ||
REDIS_PASSWORD="auth" | ||
REDIS_DB=0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added Redis connection credentials here
@@ -5,6 +5,7 @@ const cookieParser = require('cookie-parser') | |||
const createError = require('http-errors') | |||
const path = require('path') | |||
const socket = require('socket.io') | |||
const helmet = require('helmet') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using helmet to add few security response headers as it has got standard implementations and widely used in express apps
res.setHeader('Cache-Control', 'no-store') | ||
res.setHeader('Expires', 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does not allow browsers to cache Donut server responses, so using will help to bypass attacks such as CSRF.
Anyways we will be having a global cache server such as Redis which we can implement in subsequent PRs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For csrf attack you can use this, https://www.npmjs.com/package/csrf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Rupeshiya I will work on csrf there are a couple of things to do 😅 will add them in my next or
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah sure!
req.io = io | ||
next() | ||
}) | ||
|
||
// setting headers for security | ||
app.disable('x-powered-by') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hide from attackers on what tech stack does the Donut server runs on.
This will. avoid framework-specific attacks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kmehant I think it will only disable express.js to come into view of attackers
req.io = io | ||
next() | ||
}) | ||
|
||
// setting headers for security | ||
app.disable('x-powered-by') | ||
app.use(helmet.xssFilter()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bypasses reflected XSS
@@ -0,0 +1,67 @@ | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Util for limiting the number of login retries on using email and password
app/utils/rateLimit.js
Outdated
const Redis = require('ioredis') | ||
const { RateLimiterRedis } = require('rate-limiter-flexible') | ||
|
||
const redisClient = new Redis({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Connecting to Redis
const loginLimiter = new RateLimiterRedis({ | ||
storeClient: redisClient, | ||
keyPrefix: 'login', | ||
points: 5, | ||
duration: 60 * 30 // 30 minutes wait time | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
config for rate limiting
duration
is the amount of delay after the allowed number of retries
points
is number of retries allowed before starting the delay
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kmehant You are rate-limiting only for the login endpoints so DOS attack is still possible by a logged-in user.
Let say I am a logged in user and now I will write a script something like this:
while(1) {
setInterval(() => { // hit endpoint to send GET/POST request to the server }, 1000);
}
This will hit the server after every 1second and due to infinite hit server will go down.
Please take it into consideration.
cc @vaibhavdaren
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Rupeshiya Yes, this point is noted ✌🏻.
I will create another issue and add these points there and will work on another PR as this change is especially required for login endpoint 😅 to create time block delays.
But the present work is to create restrict unsuccessful login attempts that come under rate-limiting but has a special extension of using block time intervals. (was the reason for not writing this as a middleware rather an extension to login controller)
So in our next pr, I will simply write a middleware that will keep track of the number of requests (immediate) and IP address of the Client, and then we will use a quota system where we will block the user from accessing the service. (this truly comes under rate-limiting 😅 and not the present work, sorry if I have used the word rate-limiting anywhere in the context for the present work.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes!!
Great go ahead @kmehant !!
const limiterConsecutiveOutOfLimits = new RateLimiterRedis({ | ||
storeClient: redisClient, | ||
keyPrefix: 'login_consecutive_outoflimits', | ||
points: 99999, | ||
duration: 0 | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
config for repeating the process of being out of retries
redis: | ||
container_name: redis | ||
image: redis:5-alpine | ||
ports: | ||
- "6379:6379" | ||
volumes: | ||
- redis-data:/data | ||
command: redis-server --requirepass auth |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added Redis to the container setup
Signed-off-by: K mehant <411843@student.nitandhra.ac.in>
Signed-off-by: K mehant <411843@student.nitandhra.ac.in>
@kmehant One major attack that can easily exploit the server is DOS attack, So if possible please prevent that. (#146 (comment)) |
Possible attacks