I am a college student, diving deeper into web security and programming. My college had asked us to apply for an internship in a related field which means I had to find a company related to Cyber Security. And it was difficult to find a suitable company to work on because I want some experience in web security and programming as well. Both stuff in one place would be rare. After a few weeks, Thinking that I would not find an appropriate company in this COVID situation, I randomly applied to a company named Nassec.io, a recommendation from the college. Later, I felt so lucky cuz, it was exactly what I was seeking for, The company I applied to had a product named ReconWithMe.com. It's a great tool, You must check it out. It also was vaguely similar to my Final Year Project. And the company was into programming and cybersecurity stuff as well. What a gem! After I applied, I researched about NASSec. It was a startup and with a very great vision driven by young enthusiasts. I love their ideas and was willing to work with them, learn from them, and improve myself as much as I can, working with them.
So, after a few days of applying, I was called for an interview. First I will let you know, I am bad at social situations, and I don't get much comfortable with new people at first meet. But anyway I tried to manage and give the interview. I won't call it was a good interview because I was not able to speak what I need to, I was just nervous at the whole session even though they were asking me so easy questions in a very friendly manner. Let's skip this part before I start regretting it.
Ok, let's jump to questions. I am writing some important questions I was asked in the interview along with it's defined answers.
I was a bit off. I was not that aware of the programming aspect of it. I was just into breaking stuff till that time. And I tried to answer with what I knew, and said "we just filter the input user gives by escaping and stuff like that, I don't know the term but I understand how it's done." Haha I know that was a stupid answer.
I came and researched the question and was able to note down and find out the proper answer to it. Let's get into that.
- Parameterized Statements
Firstly, we need to understand how the database driver works. A database driver is a library that helps a programming language communicate to the database. These drivers help a programmer to construct an appropriate function which helps communicate between program and database and ultimately with the user. The driver helps a program to let users add, modify, or delete data from the database. Parameterized statements help us to not care about if the input passed by the user is safe or not. Parameterized SQL queries never interpret parameters are SQL queries, they simply put in the database. For example, if you pass
'; DROP TABLE users; -- as the value on a parameterized statement query, they store it in the database as a data but never interpret it as a SQL query. Let's understand it more clearly.
Lets look at this unsafe code.
//Non Parameterized Statement, Unsafe let sql = "SELECT * FROM users WHERE email = '" + email + "'"; let result = database.executeQuery(sql);
Here, as we can see the email is appended to the SQL query. In programming terms, we should call it
String Concatenation. A hacker can give a well-constructed sql as the email's value which makes the sql query do something different from what it was intended to do. A hacker can find out passwords, user information, and any sort of stuff by manipulating the sql. If you ever find yourself doing String Concatenation on sql query, make sure you know what you are doing.
Now, look at this code.
//Parameterized Statement, Safe const sql = "SELECT * FROM users WHERE email = ?"; let results = database.executeQuery(sql, email);
As you can see the variable
sql is used as a parameter on the database driver's function. It helps the database drivers to interpret the statement as a statement and the data provided is separately stored in the database no matter if there was an SQL query or anything else. This makes sure the data is stored whatever it is. Let's understand why it's safe.
If all you care about is an SQL injection attack and not anything else (WHICH YOU SHOULD) then, Parameterized Statements is probably enough. But there are some situations where you won't be able to construct a Prarmeterized Statement due to the lack of driver support. In that case, make sure you sanitized the user input as neatly as possible. Which we are not going to talk about in this blog because it is a little bit off-topic. Since I have to cover more questions I won't go further on this more than this.
Ok not writing my stupidity again. Let's get into the real answer.
First, what we need to understand is, WE SHOULD NEVER TRUST USER'S INPUT. If you want your program to be secure, never do this mistake. If you ask your user to input their email address and instead of entering an email address the attacker input something like this
firstname.lastname@example.org</input><script src="https://malicious.website.com/badscript.js"></script>. Guess what will happen if the website does not care about the user's input. When he loads his profile, the script gets executed, and god knows what that script will be able to do.
And here is how we can prevent ourselves against XSS.
- Escaping Validating Input and sanitizing
To prevent input like this from being interpreted, while rendering the data to the user, we need to do escaping before it renders. The input we receive has some key characters like
> these are the special characters we need to remove from the string before it is stored in the database or rendered. Escaping not alone can do the job, we need to do a variety of other stuff as well.
We must validate the input of the user, to not let input like these to be stored in the database or rendered anywhere. Blacklisting bad characters, or disallowing certain predetermined characters in user input can help validate the data entered by the user. But it disallows only known characters, so we can instead whitelist only known good characters which seems a better method to validate Input. If a user is asked to enter an email, we can use regular expression or there might be some library to validate its an email and a working one. If a user is asked to enter a name, the program may not allow any suspicious special character to be entered, and so on. Just validate the data if it's safe or not.
Well you might know these 2 devils. If not its better you should find some good articles and learn about them.
Those above answers are incomplete, we must apply many types of security measures to make our program as secure as possible.
And there were few other questions like these, I vaguely gave a reply to. But, at least I tried to let my supervisor know, I can learn fast whatever it is.
Sorry for my bad English, Not a native speaker. I will be updating my blog with security-related content weekly.
Thank you for your time.