-
Notifications
You must be signed in to change notification settings - Fork 0
Security
Every secure route on the API side is protected by a jsonwebtoken authentication function implemented as Express middleware. A user cannot, for example, retrieve their profile information from the server without being logged in via a secure jsonwebtoken authentication key (i.e., by submitting a secure token with their request).
The authentication function is defined in middleware/auth.js
. The authentication function is used in /register
, /login
, /logout
, and /refresh_token
routes of the routes/AuthRouter.js
file. For example, in the /login
route, the request must be correctly authenticated. If the user fails to login, then the corresponding status code will be returned and the route won’t be executed.
We store the logged-in status of the user in the local storage (under the name firstLogin
) and remove the information when the user logs out. When a user wants to gain access to the component, it will check this info at first, i.e. if a user has not ever logged in, he does not have the access to any component. This functionality can be seen in the client/src/redux/actions/authAction.js
and in the client/src/customRouter/PrivateRouter.js
files.
This app uses a custom input validation function found in client/src/utils/valid.js
. This function is called in the client/src/redux/actions/authAction.js
file when a user tries to register or log in. Functions in the controllers/authCtrl.js
file also perform additional validation checks on the inputs and if the validation passes, then the login and register functions will behave as expected in normal cases. If the validation fails, then the server responds with an appropriate status code and a JSON array with information on each failed test. It does not enter the route. In addition, we are performing some regular expression checks on the client side in text input fields to doubly ensure input validation. Checking of file size is also performed within relevant routes. For example, users cannot upload a media file that is larger than 5mb.
If a user enters a password incorrectly 3 times within 30 minutes of each other, then they will be locked out from logging in on that session for 30 minutes (adjustable). A user cannot access their account at all if it is locked, regardless of whether they enter the correct password or not. The objective of this policy is to counter brute-force attacks on the authentication process. Failed login attempts in rapid succession are the hallmark of a brute-force attack. The time penalty applied by the lockout policy will effectively prevent such attacks from being successful. This is implemented in the client/src/pages/login.js
file.
This app uses some .catch()
lines and heavily uses try-catch
blocks to handle any and all exceptions -- and to handle them at as specific a level as possible. For example, in the controllers/authCtrl.js
and controllers/groupCtrl.js
files, there are opportunities for a variety of exceptions, all of which are handled by sending the appropriate status code and message.
The app uses jsonwebtoken to generate and validate secured random tokens while a user is logged in. Whenever a client-side function uses fetch()
to make a request to the API side, it submits credentials along with the request. If the user is logged in, these credentials will include the secured random token that was generated by jsonwebtoken upon login. If the credentials are omitted, if they do not contain a token, or if the token does not match the expected one, the API side responds with an appropriate status code instead of executing the request. This is implemented for all such client-side functions.
Our application makes use of .env
files located at .env
and client/.env
for further security.