Thinking about Web Application Security
Tags: security, programming, webapp
Published: 2020-04-24 14:36:22

Hello, everyone. This is my first article publicly published, tech or otherwise. More than an article, this will be a rundown of my thoughts, so please bear with me when you see incoherence (I promise to improve but can't say how much time it would take). Anyway...

In my brief yet constantly fulfilling journey in web development, I have come across an increasing concern over API and data security. Of course, you'd find millions of great articles by researches and fellow devs alike, I want to give my two cents to how I think of and deal with the problem.

Let's say, I learnt a new language Dython and a web framework called Pango. I then built an application that takes some user information and displays certain matching recommendations over the internet.

Now I want to secure my APIs and data from any unwarranted requests. This is the problem statement I'll work with henceforth.

Let's divide-and-conquer and see what safeguards can be put from the smaller level. (Please do not mind if I leave substantial security measures, my plan is to update this article as I learn along).

At API View (the V in MVC) level -

1. Authentication: Use authentication in your API views as much as possible. It can be done using a API key at the bare minimum, going towards user session based dynamic tokens, bearer tokens, OAuth, digital signature and 2-factor authentication. At certain places where such authentication is not possible, guard it with an API gateway.

2. Authorization: Oone can think of authorization as role-bases access-control. You can't view your grades if they are only accessible to teachers. At the time of data modelling, think if you require roles at all and if yes, then define which roles see what. Abide by them while writing your views. As an example, you may have role-based profiles for each user which can be identified at the level of authentication.

3. Respect the GETs: Please, for the love of God, do not send request data into your GET requests even if GET does not forbid it. Additionally, no authentication request should have passwords sent via request headers (unless your servers run on private and secured IPs, but still no). If authentication in your application is not a 2-tap process like 2-factor, it's better to use a POST and send all user credentials as POST data.

4. Naming API Endpoints: While in a free country like internet, there are no rules on naming endpoints, still it's better to be cautious around certain names. Many web frameworks provide an admin interface for your application, which is by default, named as `<mysite>.com/admin`. Often we don't update it and it doesn't matter much, but it's helpful to rename it to evade any foreign requests. Needless to say, do not keep default username and password for admin stuff. And if you're coming from SQL world, it's better that the names of your endpoints and data models are not same, otherwise it can help hackers in certain fashion.

5. Best Practices - One's good programming practices always help keep the application one step ahead. If not handled properly, any failure in application can lead to it going down at best and displaying all code jargon and stack trace into the API response at worst. And if the failure is in connecting to an external service, your keys might get exposed in the process.

At application level -

6. Data Validations: This sounds lame but I'll still reiterate. Never accept any data coming through HTTP requests without validations. A number of vulnerabilities open up if appropriate validations are not put in place. SQL injection, for example, is done through pasting a malicious SQL query into request data to either extract all information or bottle your servers in its processing. Does `select * from ...` scare you enough?

7. CORS: Yes, dread it. Run from it. CORS arrives all the same. If your source code is present on multiple domains, it makes sense to read about CORS and implement it effectively. You may either allow certain hosts or certain HTTP methods over allowed hosts. It also reduces the processing load of authentication on the server. As such, a great deal of security can be provided to the application with better CORS policies.

8. Application Configs: Many web frameworks inherently ask to never run the application with DEBUG configuration switched on in production environments. I would go on to say that don't do it in testing environments as well. As much as they help in testing, they become a dangerous tool at the hands of hackers. Along similar lines, keep sensitive data encrypted in the system.

At server infrastructure level -

9. Application Keys: A lot of us are keeping their keys to internal or external services in their settings file in the code. Please refrain. A better solution to it is to use your web services like Azure or AWS to help you out. Many of them provide a way to insert key-value pairs in your server instances, where you can push such keys. If your code gets compromised somehow, at least it will not expose your database or any other connection information. To start with, push all keys as environment variables in your local system.

10. API Throttling: As per the usage, one can think of putting API throttling limits on the load balancer level. If more than x requests come from certain system/user/group, you block them right away. This way, it will keep the system available to all the users at all times.


For now, I can think of this many points, and will hopefully update the list as I learn more. A number of devs/communities/organisations are doing excellent job in maintaining good principles related to REST and SOAP API security and data safety. Please check out OWASP: https://owasp.org/www-project-top-ten/ for better insights. Read more here: 
1. https://dzone.com/application-web-network-security, 
2. http://highscalability.com/blog/category/security, 
3. https://www.reddit.com/r/AppSecurity/
4. https://martinfowler.com/articles/web-security-basics.html

P.S. I do not own the cover image; it is taken off Google Images.