Skip to content

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

Open
wants to merge 7 commits into
base: development
Choose a base branch
from

Conversation

kmehant
Copy link
Contributor

@kmehant kmehant commented Jul 9, 2020

Possible attacks

  • clickjacking
  • XSS (reflected)
  • Hide technology stack (to give no information to the attacker to avoid technology stack specific attacks)
  • Protocol downgrade attacks
  • MIME sniffing
  • CSRF (Will do in my next patch)
  • Cache control: do not store any
  • Policies
    • set cross domain policies
    • Content security policy
  • Privacy Issues
    • referrer policy (privacy issue)
    • DNS prefetch (privacy issue)
  • rate limit few endpoints such as login (bypass bruteforce attacks) => Used Dynamic block duration technique with Fibonaccically increasing delayes for wrong attempts to effectively arrest brute force attacks.

Signed-off-by: K mehant <411843@student.nitandhra.ac.in>
@kmehant
Copy link
Contributor Author

kmehant commented Jul 9, 2020

@jaskiratsingh2000 @vaibhavdaren @devesh-verma
I am working on these!

@kmehant kmehant marked this pull request as draft July 10, 2020 02:12
@kmehant
Copy link
Contributor Author

kmehant commented Jul 10, 2020

We shall add similar fixes to the Donut Frontend too using Nginx

Copy link
Member

@vaibhavdaren vaibhavdaren left a 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.

@codeuino codeuino deleted a comment from kmehant Jul 10, 2020
kmehant added 4 commits July 13, 2020 17:43
…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>
@kmehant kmehant marked this pull request as ready for review July 13, 2020 17:32
@kmehant kmehant requested a review from vaibhavdaren July 13, 2020 17:32
@kmehant kmehant changed the title [WIP] Bypass few common security attacks to Donut Server Bypass few common security attacks to Donut Server Jul 13, 2020
Copy link
Contributor Author

@kmehant kmehant left a 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.

Comment on lines +6 to +10
REDIS_HOST="redis"
REDIS_PORT=6379
REDIS_PASSWORD="auth"
REDIS_DB=0
Copy link
Contributor Author

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')
Copy link
Contributor Author

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

Comment on lines +45 to +46
res.setHeader('Cache-Control', 'no-store')
res.setHeader('Expires', 0)
Copy link
Contributor Author

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.

Copy link
Member

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

Copy link
Contributor Author

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

Copy link
Member

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')
Copy link
Contributor Author

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.

Copy link
Member

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())
Copy link
Contributor Author

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 @@

Copy link
Contributor Author

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

const Redis = require('ioredis')
const { RateLimiterRedis } = require('rate-limiter-flexible')

const redisClient = new Redis({
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Connecting to Redis

Comment on lines +13 to +18
const loginLimiter = new RateLimiterRedis({
storeClient: redisClient,
keyPrefix: 'login',
points: 5,
duration: 60 * 30 // 30 minutes wait time
})
Copy link
Contributor Author

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

Copy link
Member

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

Copy link
Contributor Author

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.)

Copy link
Member

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 !!

Comment on lines +20 to +25
const limiterConsecutiveOutOfLimits = new RateLimiterRedis({
storeClient: redisClient,
keyPrefix: 'login_consecutive_outoflimits',
points: 99999,
duration: 0
})
Copy link
Contributor Author

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

Comment on lines +26 to +33
redis:
container_name: redis
image: redis:5-alpine
ports:
- "6379:6379"
volumes:
- redis-data:/data
command: redis-server --requirepass auth
Copy link
Contributor Author

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>
@Rupeshiya
Copy link
Member

Rupeshiya commented Jul 14, 2020

@kmehant One major attack that can easily exploit the server is DOS attack, So if possible please prevent that. (#146 (comment))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants