Web security is one of the essential parts of a back-end developer. It doesn't matter which or how many design patterns you follow, but you must know these 5 security matters.
1) Rate Limiting
Rate Limiting is a significant way to block hackers out of your application. That's because hackers tend to look at the weakest link in your app, whether it is CPU bound task or a task that add rows to your database, for example, a login form, they can send a lot of requests from that endpoint to your application.
So to avoid this kind of attack, it is essential to have any limiter sitting in front of your server.
It could be an NGINX or Redis based limiter, or it could be any custom limiter, or could also be logically implemented inside your sever. The primary task here is to protect the sensitive operations performed with the database.
The criteria for the limiter could be
- IP Address
- Account limit (for a service that requires signup)
The priority for the limiter should be an account-based limiter as in public places like schools, colleges. If there is a public IP, it is ideal to use an account limiter over an IP limiter.
So when account data is available, you should never prefer accounts data over IP Addresses for your limiter.
2) Upload Limit
Suppose your application requires any uploading functionality, and you do not have an upload limit. In that case, it can easily bring down your EC2 instance or any other service provider that you are using. So if large files are transferred to your server, and it fills the available space on the disk, it will lead to downtime of your server. It is not only about files. It can also be about web socket message size. By default, Web Socket message size cannot exceed 64 kB.
NGINX has upload limits as well. It is better to have an upload limiter on the network level other than the application level. So, if any TCP connection exceeds the data limit, the connection can be terminated.
3) All user data is evil
All user data is evil. This is the root cause of almost all vulnerabilities because back-end developers trust the user data as authentic by default without any checks.
Let's say you are fetching data from the database based on an ID given by the user. It is very insecure to blindly fetch the data without ensuring that the given ID is legit. Otherwise, their given ID can cause an SQL Injection, and the exploiter will get the total data dump just because the back-end developer didn't consider reviewing the given ID by the user.
Always sanitize your data, check if you have the correct data and the data type. So it is always the best way to sanitize your data before storing it in any database, either a SQL or a NoSQL database.
4) Security by obscurity
Security through obscurity relies on security engineering on design or implementation secrecy as the primary method of providing security to a system or component. Security experts have rejected this view as far back as 1851 and advise that obscurity should never be the only security mechanism.
For example, you don't want your GraphQL introspection query enabled in the production as this query can return all the resolver and the mutations to the client side. So this is a kind of obscurity that you have to maintain. Even if your application has any vulnerability that you can later patch up in the future version, there is no way an attacker can find this out because of obscurity. The effective practices to maintain this would be to disable developer mode while deploying to production and disabling SQL Error which will reduce the scope of blind SQL injections.
Security by obscurity is acceptable as long as you have different kinds of alerts and flags set up to patch up it as soon as possible, which might save the day in the application.
5) Dumb services should not be exposed on the internet
The dumb services could be your database, most commonly the SQL, Mem Cached, or Redis. Leaving your Redis public IP address over the internet is bad. Exposing these services without any security practices is insane. You should also never directly communicate with Firebase, PostgREST, or Supabase from your client-side. If you have not set the rules correctly, this could let the users of your application have all the data on their hands.
It is very crucial to set up correct authentication and authorization to access the data from the database. It is never advised to have database access to the client-side.
It is always advised to have any logic layer between your service and the data access layer for your application. Ideally, you should set up the authentication on the server-side, and your client should never directly access your application's database. So any server or product that helps you store data should not have direct access on the client-side. This will be a nightmare if any authentication goes wrong. The exploiter has the whole data of your application on their hands. Just because accessing the data from the client makes it easy doesn't make your application secure.
You can watch the YouTube video here.