Hackable Chat
Hackable Chat, a tool for understanding the basics of SQL injection.
Hackable Chat is a mini chat app inspired by my Chat App: Let's Chat Day-2-Nite which is vulnerable by design, built with Vanilla Javascript/HTML/CSS, Node.JS and PostgreSQL. You can't actually chat with others in the app, and you can't create a log in - however, you can hack Spongebob's account to view his chats using a technique known as SQL injection.
Try typing this into both the username and password fields to access the Spongebob chats:
' OR 1=1; --
Why does this work?
- The initial single quote (') creates an empty string
- The 2nd part of the OR statement evaluates to true (empty string OR 1=1) effectively bypassing authentication
- The two dashes (--) create a comment, which enables the hacker to pass in everything before the semicolon (;) as a SQL command into the login form, instead of just a string.
This is an example of why we should always use parameterized queries to avoid SQL injection. Node-Postgres supports parameterized queries; use them liberally! (You'll be able to read more about Node-Postgres below).
If you look at the comments in server.js, you'll see I commented out the 'check username and password if...else' logic for a simpler demonstration of how SQL injection works, but even with it in place, a bad actor can still do damage to your database, access sensitive info, and possibly more by injecting SQL commands like so:
' OR 1=1; SELECT crabbypattyrecipe FROM bikinibottom_messages WHERE username = 'mrCrabs'; --
With this command, the hacker could access Mr. Crab's crabby patty recipe from the database.
' OR 1=1; SELECT text, user_id FROM bikinibottom_messages UNION ALL SELECT username, password, creditcard, socialsecuritynumber FROM bikinibottom_users
This 'union' command could allow the hacker to access sensitive user information from the database by combining data from the messages and the users table and returning all of it in one fell swoop.
(By the way, there is absolutely no valuable information in the database of this app; all there is is some fake chat info I made up using Spongebob characters).
So, how do we as developers prevent SQL injection? Here are just a few...
-
Validate user inputs. Essentially this means coding your login form, text box, etc. in a way so that a user can only submit an email in the email field, text in the text field, a number in a number field, etc.
-
Sanitize data. This means making sure that hackers can't pass information through your app that could be passed to the database as a SQL command. On the front end, React.js offers automatic character escaping, but if you ever need to use the DangerouslySetInnerHTML attribute in your front end, please check out a tool for sanitizing inputs such as npm's DOMpurify.
-
Never use string-concatenated queries - use parameterized queries instead. This means using a type of syntax that will only pass the SQL commands you want to allow through to your database, preventing SQL injection. For all you node.js developers out there, Node-Postgres offers easy-to-build parameterized queries.
There are many other ways to keep your application secure, but for the sake of brevity I'll stop here for now. Stay tuned for more secure coding examples and blog posts coming your way from yours truly!
-- Check out Hackable Chat HERE. -- View the code on Github HERE.
Follow me on Linked In
View more of my work on my website at www.casspicer.com