XSS, SQL Injection and CSRF
I’ve been interviewing lately and some of the side questions I’ve gotten have made me realize I have a few topics I need to brush up on 😅
Given that I’m a web developer primarily, I want to address any weak points of knowledge that I’ve forgotten over time and make sure the topics I haven’t touched in a while aren’t atrophying.
I don’t know if anyone will even read this but I like the idea of documenting my thoughts within this blog since
- a) taking the extra time to write these posts out will help with my memorization
- b) I may need refresh on this again in the future and it’s always useful to have
- c) If anyone happens to read this, hopefully it gives you a refresher too!
Today, I want to check out 3 prevalent web security threats:
-
- Cross-Site Scripting (XSS)
-
- SQL Injection
-
- Cross-Site Request Forgery (CSRF)
There’s obviously more but I’ve seen these mentioned a handful of times specifically. These vulnerabilities rank in the OWASP Top 10 Security Risks so definitely doesn’t hurt to brush up on
Cross-Site Scripting (XSS)
Cross-Site Scripting is when the hacker is able to inject malicious scripts into web pages that lack proper data validation and/or escaping.
There are 3 common types:
Reflected XSS
- The script is executed through URL params or form inputs and is executed in the browser on page visit
Stored XSS
- The script is stored on the target server (ie. database, user profiles, etc) and executes when content is fetched.
DOM-based XSS
- The hacker modifies the client-side DOM environment to execute malicious scripts via DOM manipulation.
These XSS attacks can be used to hijack sessions so hackers can steal your authentication cookies, perform actions on your behalf, or redirect you to other malicious sites.
Prevention Strategies
The best way to prevent XSS is by proper input validation and output encoding.
- Always sanitize user input by removing or encoding special characters!!!!
You can also use Content Security Policy (CSP) headers to restrict script execution, and securely implement session management with cookies.
You should take a pessimistic view and treat all user input as malicious and validate it on both the client and server side to be safe!
SQL Injection
SQL Injection is malicious code is included in db queries to get access to your data and/or figure out how to get access to your data
Typically it happens when form inputs are added into SQL queries directly without proper sanitization. These queries can be used to access or modify unauthorized data and execute system commands
For example, a query like SELECT * FROM users WHERE username = '$username'
would accept an input like admin'; DROP TABLE users; --
which of course would wreak absolute havoc
Types of SQL Injection
Classic SQL Injection
- Involves directly manipulating SQL queries through inputs like form fields or URL parameters.
Blind SQL Injection
- Can occur when applications don’t display errors but still execute bad queries and allow hackers to infer sensitive information based on the application’s behavior (eg. Time based SQL injection, noted below).
Time-based SQL Injection
-
Is a type of Blind Injection where database time delays are used to extract bits of information.
-- If user_id = 1 exists, will delay 5 seconds SELECT * FROM users WHERE id = 1 AND IF(SUBSTRING(password,1,1)='a',SLEEP(5),0)
The most effective prevention is using parameterized queries or prepared statements (pre-defined, parameterized SQL queries) to separate the SQL code from the data.
// Prepared Statement (secure)
const query = 'SELECT * FROM users WHERE username = ? AND password = ?';
const statement = db.prepare(query);
const result = statement.run(username, password);
// This approach (^) is the most secure. The typical
// approaches like below pose HUGE security risks
// Hard-coded SQL (vulnerable)
SELECT * FROM users WHERE username = 'john' AND password = 'secret123'
// String concatenation (vulnerable)
const query = `SELECT * FROM users WHERE username = '${username}' AND password = '${password}'`;
Input validation should handle all data type validation and formatting, and YOU should ensure that all database users have ONLY the necessary permissions.
Cross-Site Request Forgery (CSRF)
CSRF takes advantage of authenticated sessions on the victim’s machine to perform actions on their behalf.
The goal isn’t to steal data necessarily but rather to perform actions that will:
- a) give them your data OR
- b) they would have needed your data to perform (ie. they bypass duping you for data and just make your life hell directly)
CSRF attacks can happen through emails, sketchy web pages, or ads that contain hidden forms or scripts that automatically send requests to their server with your vulnerable information.
Hackers can then change passwords, transfer money, modify account settings, post on social medias, make purchases, etc without the victim knowing. RIP your bank account, social media, email, and everything else you’re conveniently logged-in on your device
The best protection is implementing CSRF tokens (ie. unique, unpredictable values associated with each user session) which are included in all state-changing requests to prevent any invalid requests from third parties.
There’s a few more solutions I came across like:
- using the HTTP Referer header (good one!!)
- using custom headers for AJAX requests (not so relevant for me atm, but fyi)
- implementing proper session management
- re-authentication for extra sensitive operations
but those will have to be a topic for another time. If anything I’d like to revisit CSRF tokens again next.
Conclusion
XSS, SQL Injection, and CSRF are big web security concerns that continue to demand our attention due to lack of awareness and insufficient preventative measures. Even the biggest companies with HUGE corporate budgets get compromised and unthinkable amounts of data get leaked (don’t worry I won’t single you out Facebook :) )
There are a million and one topics in the world of software engineering and sometimes its overwhelming keeping up to date with EVERYTHING when it comes to creating secure web applications. For every positive white-hat topic you’re learning there’s somebody out there investing their time into all the wrong things…
Most of the fixes and “robust” solutions in place just haven’t been hacked yet and its impossible to anticipate everything; shown by all the companies who offer bug bounties.
STILL, even as non-malicious developers (hopefully you’re not using this for evil), it’s our responsibility to our users to be aware of potential compromises we might be overlooking in our applications (especially obvious and easily preventable ones).
Also the main reason, I’d feel pretty dumb working as a software dev this long and getting bamboozled by some chump via a basic vulnerability but hey, knock on wood, Sun Tzu said “All warfare is based on deception”.
Watch your step (and protect ya neck)!