{"id":4817,"date":"2009-11-27T07:01:52","date_gmt":"2009-11-27T14:01:52","guid":{"rendered":"http:\/\/css-tricks.com\/?p=4817"},"modified":"2019-04-09T16:25:58","modified_gmt":"2019-04-09T23:25:58","slug":"app-from-scratch-8-finishing","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/app-from-scratch-8-finishing\/","title":{"rendered":"Creating a Web App from Scratch – Part 8 of 8: Security & The Future"},"content":{"rendered":"
👋 Hey there!<\/strong> We want to give you a heads up that the source code that accompanies this series is no longer available to download. We still think there are valuable bits of information to get from the series, but given that we’re 10+ years down the road, we also think it’s worth considering a modern PHP framework (like Laravel<\/a>) or even a JavaScript framework (like React<\/a> or Vue<\/a>) to create a progressive web app.<\/p>\n Hooray we made it! First of all, thanks for following along this whole journey.<\/p>\n Below we’re going to wrap up a few things by talking about some of the choices we made, security precautions, and ideas we (and you) have for a version 2.0 of this app.<\/p>\n <\/p>\n Because we should always aim to be efficient when programming, we built this app with the concept of DRY programming in mind. DRY stands for “Don’t Repeat Yourself” and should lie somewhere near the core of our programming philosophy.<\/p>\n In our opinion, taking the object-oriented programming (OOP) approach was the best way to keep this app DRY. OOP allows us to group common methods together and separate tasks out without needing to pass parameters from function to function. For a little more information on OOP and why it’s beneficial, read Jason’s introduction to OOP.<\/p>\n Security is incredibly important in any application. We have users with accounts who are storing data with us. Those users are putting their trust in us to make sure their data is safe, which includes their password and all the information they’ve entered into the lists. This app is already pretty darn secure. Passwords are stored in encrypted formats and never sent in the clear via Email. All the interaction that happens with the database is secure. Only users who are logged in can issue commands which result in database changes, and those users are only able to issue commands that affect their own data.<\/p>\n But because there is a variety of AJAX stuff going on in this app, our security needs to take into account a few more scenarios. First, our JavaScript (like all JavaScript) is publically viewable. This JavaScript contains the code for making AJAX calls, meaning the URL we are sending to and what data that URL is expecting. This tells potential attackers a good bit of information regarding how they might send malicious requests. Because of this, we need to be very careful and ensure that all incoming data is escaped properly.<\/p>\n Avoiding attacks on the server side involves two major risk factors: first, the potential for database attacks; and second, the potential that a malicious user could submit dangerous data that hurts our app or users in some way when read out of the database and displayed. Fortunately, PHP provides us with several methods to combat these risks.<\/p>\n Database attacks, called SQL injection, are a particularly nasty form of attack. A vulnerable database can be read, manipulated, or deleted entirely by a malicious user. This means that it is really important that we keep any kind of SQL injection from happening.<\/p>\n Lucky for us, PHP Data Objects (PDO) virtually eliminates the risk for SQL injection through the use of prepared statements, which are like query templates that we can customize with parameters. All the escaping is done for us when the parameters are inserted into the query, so it’s virtually impossible for SQL injection to occur while using prepared statements.<\/p>\n It was because of this powerful security advantage that we chose PDO for this app. (Keep in mind that prepared statements are not exclusive to PDO; other database extensions, such as MySQLi, also support them.)<\/p>\n While PDO is powerful against SQL injection, it doesn’t help us when we’ve read the information out of the database. If a malicious user injects dangerous tags into our database, they’ll still be dangerous when they’re retrieved unless we take further measures to sanitize user data.<\/p>\n Fortunately, PHP has built-in functions that will allow us to perform basic sanitization of user input. We’re namely using strip_tags() with a whitelist to make sure no <script> tags or other potentially dangerous tags make it into the database. Also, because we never want that sort of thing to be allowed, we’re performing this escaping before the data is inserted into the database.<\/p>\n First, a good measure is to “Pack” the javascript so it isn’t so easily readable, as well as downloads faster. There are a lot of tools available to do this, including this one<\/a> by Dean Edwards.<\/p>\n Secondly, because we are inputting data and turn it around to display immediately on the screen, it’s best to do some of that input scrubbing directly in the JavaScript. When a user enters a new list item, we’ll take two steps to scrub it. First we’ll ensure they aren’t naughtily trying to insert immediately executable JavaScript into links:<\/p>\n Then we’ll also scrub that input text for any other HTML. Some HTML we will allow, in case users want to format their lists a bit like with <strong> tags and the like. With the function below, we’ll strip away all tags except those set up in a whitelist.<\/p>\nArticle Series<\/h4>\n
\n
Object-Oriented Programming<\/h3>\n
Security<\/h3>\n
Security on the Server Side<\/h3>\n
PDO<\/h4>\n
Data Escaping<\/h4>\n
Security in the JavaScript<\/h3>\n
Client Side Sanitization<\/h4>\n
\/\/ Check for JS in the href attribute\r\nfunction cleanHREF(str) {\r\n return str.replace(\/\\<a(.*?)href=['\"](javascript:)(.+?)<\\\/a>\/gi, \"Naughty!\");\r\n}<\/code><\/pre>\n