 All right. Are you scared? I hope you are. So let me first introduce myself and Peter as well. My name is Jacob. I'll be giving you the first half of this presentation. And I'm the member of the Drupal security team and been working with Drupal for a couple of years. So hopefully have enough experience with it. Peter, do you want to introduce yourself? Yeah. I'm Peter Willanen also on the Drupal security team. We've been doing these sorts of talks among different members of the team as sort of a public service to try to get at least an overview in people's minds of what important topics in Drupal security are that you should be thinking about, especially as a developer, as a themeer. Some of the other Drupal cons we've had talks also more focused at site administrators, but we didn't get one this time. So truly this is an overview to give you the concepts. You're not going to learn everything you need to know, but hopefully you'll learn the key phrases and things to look for later and things to think about. It's going to get you interested enough so you learn more about what security really means. Yeah. So as Peter said, this is really going to be an overview. And I wanted to start by talking about why should you even care about security. And security is pretty important. And if you take a look at the history of what was happening before and what's happening now, if you take a look at, I don't know, 15 years ago, 20 years ago, the real start of the public internet as we know it, security was really fun. It was something that people did because they were interested in it. It was really hacking, trying to find holes in systems. While right now it's something else, it's a business. And it's a multi-billion dollar business that's focused on all of you guys. And it does a lot of stuff. It affects your good name, but not only that, it affects your revenue, your margins. It affects everything that you do online. And as you pointed out, it also can affect your customers because if somebody hacks your site and put something there, it's not only in danger in you and your business, but it's also in danger in everybody who comes to the site if you will be, for example, serving some malware or spyware on your site. So it's also important for your customers. And what I saw when I did this talk for the first time in a different format, this is by the way the first time they're using Prezi, so it might be fun. People said, well, you know, my site is not important. But in the end, every site is important no matter who you are. Maybe you have a site for your family that your family accesses once a month. Then you probably don't want to be serving malware to your family. And at the same time, if you're, I don't know, PayPal, then you are important because your site is so large that people will attack you no matter what. So I'm pretty sure that PayPal is constantly under some attacks. So one thing I wanted to talk about is that Drupal security, especially in Drupal, is not just about that. And we have some customers like that that come to us and say, I want a web application firewall because I want to be sure of security. This is just not enough. And it's some kind of layer that you can add, but it's like a insurance. In Drupal, it works a little bit differently because Drupal security is based on layers and is basically bound to everything that you do in Drupal. So for example, take a look at menu and node access. By menu and node access, you control who accesses your nodes, who can access your administration interface, for example. Or when you pass that, basically, because you have access to some administration interface, you come to form API and form API makes sure that you are protected against cross-site request forgery, which we will talk about later. Then you go to the next step and you have database API to make sure that you're protected against something like SQL injection, for example. And as a last step, and it's probably the most important one, it's on the top of the list, is the theme in layer or you can say rendering layer that takes care of all the functions that, for example, output some user input and take care of cross-site scripting. So that's Drupal security in layers and it's very important to understand that. It's not just about cross-site scripting. It's all about all the layers that you have. So before we talk a bit more in detail about the stuff we came here to do, code in, one important thing and a few other things that I'll show you. One of them is keep up to date. Please update your modules. Please don't forget about it. It's very important and Drupal is trying to make this as easy as possible for you. So there's an update module that will send you an email if there's any security update for your site and you just go to the update module settings and set it up there. Or if you go to Drupal.org, I'm sure all of you have Drupal.org account and you can use a profile. You can subscribe to all security announcements. So whenever a security team like Greg over here announces some kind of vulnerability that's in any code and any fix, you will receive an email that something's happening. And at the same time, it's very important to have some kind of method, how you update your site because if you do FTP or if you do Git or if you do subversion or anything else, be consistent. Choose your method, create some kind of procedure and stick to it. If you do it differently all the time, it's going to be difficult for you. So let's talk about checklists. I like checklists because I've seen some research from medical surgeries when they actually found out that if they do a quick checklist at the start of the surgery and the same checklist at the end of the surgery, the amount of problems that arise from the surgery lowers significantly and they found out that they actually leave the tools in your stomach far too often and so they just do a checklist, you know, knives, retractor or anything else and at the end of the surgery, they do the same to make sure they didn't leave any tools inside you. So that's why I like checklists because it really works. So a couple of very quick rules that we usually say to users, please do not use PHP filter and at the same time, you know, it's very important to know what's the concept of text filters and what's the concept of full HTML and filter HTML and don't let anyone who's not trusted have full HTML access. What's also important and we'll talk about it a little bit later is that actually most of the problems that we found are in custom theme and templates. It's not in the custom code because it's very easy to do it with custom modules. Let me clarify that. So that's if you do a site audit. So if you go out and look at real protection sites that someone has built and deployed, you look at Drupal.org, obviously, most of the vulnerabilities that we publish are in modules, but there are many, many more modules on Drupal.org than themes. So this is this statement and we're going to, you know, come back to it a few times and just reemphasizes as you, as a site developer, with your custom theme that no one else is looking at that's not published on Drupal.org, that's where the vulnerabilities are most likely to occur. Absolutely. And, you know, in the end, use APIs, whatever the Drupal API is. Once you start going beyond APIs in Drupal, it's a very big chance you're doing something wrong. And when in doubt, check plain, you know, write it down on your monitor or on your screen. In doubt, check plain. So let's talk a bit more about the types of problems that are usually found in Drupal. And this is a very nice chart from the Drupal security report that shows a breakdown of problems for both core and contrary from 2005 to 2010. And you can see it's really sticking out. Cross-site scripting is the most popular, if you could say popular one, in all the modules that are on Drupal.org. And it's a bit different from what you can find in other frameworks because we have found out that other frameworks usually have SQL injection as the most dominant one. But apparently the Drupal database API is so good that people don't have too many problems with it. So cross-site scripting is the most important one. So let's focus on three main problems that you can find in a lot of Drupal modules and then one of my favorites as well. So the first one, SQL injection. What is very important about SQL injection is that it's really bad, you know. If there's a problem that is exploitable in some module on Drupal.org, the Drupal security team usually does a security announcement that's highly critical. So once it's a SQL injection that's exploitable, it's always highly critical. And it's important to know. And so what does SQL injection mean? Imagine some code that looks like this. You know, it selects something from a table where ID, or that could be a node ID, for example, equals to some argument. You probably know the function at the end that's argument one. That means some kind of argument that's coming from a URL usually. So this is okay, you know. You say argument is one to three. It will give you some data for a node one to three. But imagine what happens if the argument is actually one or one equals one. This will all be passed to the SQL server and it will say one equals one, which is true. So that will mean that it will return all the data that's in the table instead of the one node that you are interested in. And it's like a very simple example, but you talked about some very... Yeah, so I mean, this looks, you might say, well, why does that matter? Yeah, why does it matter if someone can, you know, access a piece of content they're not supposed to? Well, there's a couple of things. First off, imagine your site has some access control on nodes. So a very easy example there. You know, are able to bypass the access control and see content that they're not supposed to see. Depending on your business, that might be actually a really big problem. The other thing is that you can use these sort of select queries in combination with the union to pull data from other tables. And an example that should scare you in Drupal 6, we haven't yet finished back porting a patch that we hardened in Drupal 7 against stealing the data necessary to generate a one-time login link. So if you had this sort of injection in Drupal 6, you could pull out all the pieces necessary and generate a one-time login link for any user on that Drupal 6 site. Yeah, just out of curiosity, does anyone know what the data necessary to generate a user, the one-time login is? It's the last login time. It's the username and password, I think. The hash password, yeah. That's an altogether it makes an MD5 hash. That's the unique string that you see in the one-time login link. So using SQL injection, you can almost very easily get all this data out of the database and then generate your own one-time login link, and then you're done. Yeah? Sure. So yeah, just to repeat the comment, clearly it's more dangerous and more obviously dangerous if this is a delete statement. So where someone was deleting data and you could delete something that they didn't mean to do? Yeah, absolutely. It's much easier if you just put delete instead of select and then it will say delete everything from table where ID equals true. The most common injection we see, though, is a select injection like this. So the other thing I just want to point out is this arg is pulling something from the URL. And we're going to get back later to what user input is to think about what, you know, basically you might think the URL is something fixed that the browser goes to from a link, but in fact it's user input. That's an important concept to think about where user input is entering the system. Absolutely. So how to fix this? This is valid for Drupal 7. It's a bit different in Drupal 6, but we are all on Drupal 7 for the past year, so this should be the most valid. So just to fix the query that we talked about before, basically you use placeholders in your queries instead of the user input. So if you want to do the argument, you basically say where ID is higher or equals and then colon ID, for example. And then as a second argument to the dbCurry function, you pass the argument as the placeholder. And this will make sure that the database layer will escape all of the data so nothing can happen. And at the same time, the Drupal 7 has the new database, the new generation API that allows you to make queries as objects instead of writing SQL queries. If you're, for example, not comfortable with writing SQL queries, you just write objects like this. So, for example, this code will generate something like insert into node, title UID created, and all these values. So this database layer does all the stuff that we talked about automatically. So you just say dbincert, the ID or created equals to the argument. And the database layer will automatically detect what the column type is and how does it have to escape it. Okay. Just as a side note, and yeah, you may run into this. The escaping is done as strings. So in Drupal 6, you could sometimes get away with passing a Boolean value into something that was supposed to be an integer column and it would work, but that won't work in Drupal 7. From a hard one experience, I can tell you. Because if you escape a string that's false, you get an empty string rather than getting zero. Yeah. So let's talk about cross-site scripting. You know, if there's something you take away from this presentation, it's this. So take attention because that's the most important one that we see so often that it's just not good. What's important about cross-site scripting is that you are taking some user input and escaping it on output. And that's very important, especially in Drupal. So imagine you get some kind of, I don't know, username from the user or notes title and you save it to the database. And once you save it to the database, you actually don't care about cross-site scripting. You only start carrying once you display the notes title to the user. And the reason is that when you are saving the data, you don't know what's the context of the data. So you might be displaying the notes title in XML. You might be displaying it as HTML. And the context is different. And, for example, in XML, you escape it differently. And that's a very important concept. And once you get the presentation, there's a great article from Stephen Wittens that he wrote about save string theory for the web. And that talks about this concept. And I definitely encourage you to read about this. And what's very important, again, is the user input. And just out of curiosity, let's do some kind of pop about user input. What do you think user input is? So let's say notes title that, you know, you're a content administrator. You write a notes title. Is that a user input? Raise your hand if you think so. Great. Yes, it is. Username, for example, or password? Yeah. What about a URL, like the note ID? Great. And have you thought about, let's say, user agent? Less hands, but it's important. So, you know, sorry? Hidden fields, yeah. Very important, you know, every time a browser requests a page, it sends headers. And the headers are user agent. The language is supported. The refer and a lot of other stuff. That's user input as well. And you talked about what was the module that had some problem with user agent? I think this is maybe Greg's module. No, with the header. Yeah, so, um, co-maintainer, anyway. So I don't remember the name of the module off him, but basically what this module did was log, I think the user agent string. So you could see, for example, you want to see how many people are using, you know, the iPhone, how many people are using Safari on the Mac. Yeah, it's logging that and it put in a log message every time the user visited the site. Well, someone discovered that this module was not actually escaping that. It was not treating it as unsafe user input. So someone could, in fact, using command line tools, you could very easily write a different kind of header there that's actually a JavaScript. And so when you went to view your log messages, actually the JavaScript would execute as a cross-site scripting attack. Yeah, so anything that's coming from the browser, whatever it is, is user input and cannot be trusted. You cannot trust anything that's coming from the user, no matter what. So, again, just to give you an example, imagine this very simple code, print hello notes title. So it will print the notes title, but imagine if the notes title is actually some kind of JavaScript. And that's a user input, so I write a JavaScript. And what it will do is print hello and then the JavaScript code into HTML. And this JavaScript code will be ran on the user browser, and that means that the JavaScript can do almost anything. And if you can do it, JavaScript can do it better. Which is something we'll show you. Right, an important point of that is the JavaScript is running on the site, and if people know anything about browser security, there's a security policy called the same origin policy. So that means JavaScript running on someone else's site is not allowed to operate on your site. But if the JavaScript is coming from your site, that JavaScript has basically full access to everything that you have access to. So that's an important distinction. That's why cross-site scripting is dangerous. Because of that same origin policy, if the JavaScript originates from your site, then that JavaScript has the same access that you have. So how to fix this? This is a great picture, again, from Greg. I don't know why he does so much stuff. Imagine that the stuff you see, that's the user input. So you basically come from the top and you basically decide in your code if the stuff that came from the user is a URL. Then there's a function in Drupal that's called checkURL. And you should use it on any URL you print from the user. And it will make sure that, for example, the protocol is correct. So it's like HTTP, HTTPS, or it's just a valid protocol. It will make it actually, I think, X-HDML compliant. So it will replace all ampersands with ampersands and stuff like that. And then if it's not a URL, maybe it's a plaintext. So it's a notes title. Notes title is usually plaintext. And this is basically what you are doing yourself when you are coding all your modules. And if it's a plaintext, there's a function that I talked about earlier called checkplane. So when in doubt, checkplane. It's ran almost everywhere in Drupal Core. And maybe the code is richtext, so it's coming from a visovic, for example. So it's the body of the note or something like that. Then there's a function in Drupal called checkMarkup. And the checkMarkup function you probably know. Do you know the concept of text filters or input filters in Drupal? Raise your hand. Almost everybody? Great. So the checkMarkup function, one of the arguments for the function is actually the input filter that he needs to use. So the checkMarkup function will filter the text based on this text format. And important to note there that checkMarkup is the kind of thing you don't want to use very often in custom code because you don't have any guarantee that it's going to make the string safe because someone can reconfigure the text format and make it unsafe. For example, allowing through different, you know, a script tag in that format. Yeah, because if somebody does full HTML for the input format, then checkMarkup does almost nothing, for example. So it's really for stuff where you know it's really richtext. So, and if it's an HTML, you know, if it's richtext, then you use checkMarkup because you don't really know what formats you want or what format the user wants. There's also a function called filterXSS, which is actually usually called by checkMarkup if you use the filtered HTML text format. And that will make sure the string is safe from XSS's point of view. There's a similar function which is called filterXSSAdmin, which can be handy for module development. So if you want the administrators to be able to input almost any HTML tag but not unsafe tags like script tags, you can use that, and it will basically allow almost everything through but still keeps you safe. I think it will remove attributes and stuff like that. It will remove some attributes, remove some things, but yeah, it'll allow almost any, you know, basic markup through. Yeah, and in the end, the last case is trusted. I don't think any user input is trusted, but it might happen, right? So, then you do basically nothing. Yeah, and the example of trusted input is the site administrator, you know, needs to have a full HTML node so they can embed a video which has, you know, object tags and other things that are, you know, basically equivalent to JavaScript. So clearly, you know, that user has to be trusted. They have to trust the code, the tags they're pasting in there, you know, and at that point it's really up to human judgment. Yeah, but I still think that's, that shouldn't be an implicit trust because then it should be checkmarkup and the checkmarkup should decide, where is the embedded code, so it should be, or this field is embedded code, so it's a full HTML and then decides to do nothing, for example. So what's very important is we are all trying to make Drupal multilingual. So what about localization? And that's really important for a couple of reasons. So you probably know the function called T that you use when you need to translate some string. And obviously you shouldn't put any user input into the T function because not only it will not be protected about cross-site scripting, but also the user input can be random, it can be anything, which means every time you run the function it will generate a new string to be translated, which means you just cannot translate anything. Like a perfect example is under every note title submitted by username, right? And you want the submitted by to be translatable, but not a username obviously. So if you just do T, submitted by, and the variable username, then every time there's a new user that creates a blog post, something like that, it will create a new string and you will never be able to translate it. So that's why, again, in T function you use placeholders and these placeholders are designed to protect you from cross-site scripting. So the first one with the add variable means that it is a plain text, so basically Drupal will run check-plain on the variable. The second one with the percentage is again plain text, it will run check-plain, but for some reason it will also add emphasis text, run text. And the last one with the exclamation mark is very important because that's HTML. That basically tells Drupal when you do exclamation mark variable to just pass it through. This is not safe. So the last one is another safe example and when you use that, then you're not protecting yourself against cross-site scripting. So let's talk cross-site request forgery and that's, I think that's an important one, but at the same time it's usually very hard to grasp it and most of the people actually don't know what it means, but if you understand it you'll see that it's throughout Drupal and it's actually very easy. So what it means is some action is taken without user confirmation. So imagine that you have some non-Drupal site, example.com slash admin slash delete PHP ID equals one to three. What this is supposed to do is whenever you go to this URL it will delete the note with ID one to three. It's a non-Drupal example. And there's no confirmation, you know. So imagine what happens when you actually take this whole URL and put it into image source tag and put it on the same website. And then you take a look at the website and you force the administrator to access the website somehow. And that's the easy part. You just post it. You post the link on, I don't know, Facebook or something like that. And the administrator who's usually locked into the site because frankly not very often you log out of Drupal site, right? So the administrator goes to his site and then he goes to this URL and there's an image source tag and his browser will just load the image with the delete PHP URL and it will run the action that's in the delete PHP which means he doesn't know about anything but he just deleted some note, for example. And that's just again a very simple example. Peter has a great demo where we'll show you what exactly you can do with cross-site request forgery. What's very important is that both get and post can be used for cross-site request forgery. So the get part is what I've shown you right now and that's the easy part. But actually post is not protecting you as well because you can very easily post forms with JavaScript. How to protect against this? If you take a look, if you just use Drupal and use Forms API you're done because Forms API does all of this for you. And maybe you have noticed that if you view source of some Drupal page and there's a form there's a hidden field called form token. Have you noticed that before? Great. And it's annoying, right? Because then you reload the page and it says validation error. Try again. Yeah. And that's very annoying if you log out and log in again and you still keep the form. And the form token is actually a request forgery protection. And that token depends on your sessions. That's why if you log out in one tab and submit the form in the other tab it's going to give you a validation error. Yeah. Because the session is no longer the same. Exactly. So how does this work? Let's say imagine that you have a browser. And the browser loads the form from the user. And as part of the form the application, in this case Drupal, will send this unique token, the form token in the form. And once this user submits the form it will do a post back to Drupal. And as part of that it will contain the same token. And what Drupal will do is basically compare the token it knows because once it loads, once it sends the token it will also remember it for your session. And once you say, once you send the page back it will compare those two, the remembered value and the value if they are equal then it will allow the action. If they are not equal then it will not allow the action. It's very easy. I just illustrate how this works and this is also how to do this if you're not using Forms API for example for get requests so you need to do it manually. And a good example is flag module you probably know flag module and if you want to flag something there's a crazy unique string so what flag module does is when it displays the URL it will call a function Drupal gets token with some kind of random string or not random string that's unique for this kind of operation and it will get a token string and put it as part of the URL and once you click on the URL it will go back to Drupal and flag module will do a very simple thing it will say if Drupal valid token that's a function and the token and the unique string I talked about then perform the action if not then don't do anything and it's a very easy way how to protect against cross-site request forgery if you're using get request so let's talk about very quickly my favorite PHP filter and I think it's just a simple fail you shouldn't be using PHP filter on your website no matter what I've seen in my life maybe one example where it makes sense and I've seen a couple of horrible examples where Drupal programmer pseudo programmer didn't know Drupal APIs didn't know modules so a whole business application that was generated a lot of revenue was written as a note it was basically a note with PHP filter and the whole application was part of the note that's good you know but it worked for them and it's bad for security but at the same time it's also bad for speed because once you have PHP filter once you write PHP code in your filter and your note body for example that code cannot be run using APC caching so it will be slow because it will have to be evaled every time you run the code and it also can't be cached by Drupal's page cache yes so definitely not PHP filter so at this time I'll give the microphone to Peter and what we will do is talk a bit more about those two examples of cross-site scripting and actually show you a demo how it works so just a point I wanted to emphasize again it doesn't matter how secure your code is if you let someone configure your site badly as Jacob mentioned if you have a PHP filter and the full HTML basically if you allow untrusted users or even worse anonymous users access to those they can take over your site with essentially zero effort and as an exercise we've done things like typing in certain strings into Google that show up in those filters and you can find people's Drupal sites that are exposed this way and you know if you're really nice you put in a little PHP snippet but again so bad config means an insecure site people in your organization if Joe in marketing this happy guy can misconfigure your site and let anonymous users use full HTML nothing else that we're talking about here matters your site is insecure and it's going to be hacked so that's a take home message that's sort of beyond the code level but it's really important when you're managing a Drupal site so another sort of getting back to sort of the developer level we mentioned again the importance of the theme layer in protecting especially custom sites and so something I just want to talk a little bit here is if you're doing custom development and you have developers and themers working together on the same site you need to have kind of an understanding between them to achieve the harmony to keep your site safe and in particular as a developer it's sort of your responsibility to understand the data that you need to know whether it's user input whether it's unsafe and how to make it safe the theme are often that's not their responsibility their responsibility is markup their responsibility is printing things out getting to show on the page and so if you deliver to them unsafe unfiltered user content that's when these sorts of mistakes happen that expose the site to cross-site scripting so in general for modules so that's basically a function that runs before a theme template or in Drupal 7 also before a theme function that allows the module developer to alter the data between when it came in to the original function call and when it gets delivered to the template and you take that opportunity and you can redefine the variables or you can filter them and make them safe so the themeer can use them directly without having to know anything more about where it came from once the themeer gets that variable in the template then they'll just be free to print it or in Drupal 7 sometimes you also use this function called render so you'll print render the variable if it's a renderable data structure so that's very important so if you're a developer think about the fact you need to give the themeers a safe data you need to give them instructions for example in the template put code comments saying here are the safe variables these are the ones you should be using so an example of Drupal core of this kind of pre-process function here in the book module and you can see that the book title variable is being populated and that's being populated from the book link title which is user input that I think originally comes for example from the no title and so here we're calling check plane we're making it safe we're making it plain text so the themeer can then use it safely without any concerns so just repeating this point if javascript can do something if you can do something and javascript runs on your site it can also do everything you can do and possibly more because it's faster and it can do it algorithmically so protect yourself and think about again if you're developing a custom site your theme is where you should be spending a lot of your time auditing the code for cross-site scripting holes so I'm going to show you a little example now of what cross-site scripting can do and it can be so dangerous and this example what I've done is I installed open atrium version 1.2 which might still be the current release or the last release more or less current release and that has in it the rubik theme shipped and I've reconfigured it so rubik is not the default administrative theme but rubik has a security vulnerability it was a beta release of the theme so that's a publicly known vulnerability if you have rubik theme rubik configured as your administration theme you're potentially vulnerable to this right now and what happens is in rubik theme in certain paths it takes part of the URL the path it's expecting a Drupal path something safe and it puts it in the class of the node body or the page body so it looks at the path that expects admin config and it puts let's say config as a class in your CSS well instead what I can do is I can put some javascript in that URL and the javascript will then get injected into the body tag and execute on the page and now we have our cross-site scripting attack so I'll talk you through this a lot of fun so here I'm on the hacker site the hacker is setting up a trap for our administrator and so if the query string says sucker it will then inject this iframe the iframe is only 0 pixels high so you can't see it and it will load the script called b.js and in the next tab I'll show you this b.js this is a greg update of this for Drupal 6 this is basically a javascript that will edit your user one account and change the name and password to hacked now clearly if you were actually attacking someone you wouldn't change the name since you wouldn't want them to see it but it's great for demo purposes so you can see that dramatic change in the user name of user one so imagine here's my site I'm user one Peter everything looks good someone on Drupal.org sent me a contact message about a great blog post that I might want to see alright and you notice the query string there now I've gone to the page I don't see anything everything looks fine except it was submitted by evil guy that's not good if I reload the page what happened my account has been hacked right that javascript ran edited my account changed my password and changed my username just by loading that page so let's just so we can see that a little more detail we'll load the web console this is a little hard to see but you can watch the stream of requests going I reload the page and you'll see right at the top there there's a really long request where that iframe is loaded and then down below there's a post request where it's sending the form and editing my user account yeah so we mentioned that cross-site scripting is not limited to get so it's not limited right so a side note this this kind of attack has called a reflected cross-site scripting attack so the javascript wasn't stored on the site it was injected through the URL and then reflected on to the user the more common one so that would be a stored cross-site scripting request where it's just stored permanently in the database and it's going to attack the user every time they load the page displaying that note title the distinction isn't really important because they both have the same effect but it's important that any kind of cross-site scripting attack can lead to your site being compromised refreshing again cross-site request forgery this is the other kind of attack this is where you don't have like a form token to protect you so in that example because of the same origin policy that javascript was able to steal the form token from my site from the form and resubmit it and have it execute if there's a cross-site attack the javascript doesn't have access to things like the form token it can't pretend to be me so it has to rely on the fact that there's a URL that takes an action without requiring some form token so just an easy example the evil hacker causes you a redirection in your browser and just sends you to a URL that takes some action and deletes node, unpublishers content blocks the user you can imagine that a lot of developers as they start developing they think hey I want to have one click link that's going to take this action if you're thinking to yourself I want to click a link and take an action you need to have a form token protecting that where people could have for example voted behalf on someone else and voted nodes up or down the example I want to show you is from the views UI module so this vulnerability was actually fixed in 2010 so it should be well out of the public realm of anyone who keeps their site up to date but what happened is that the views UI module did not have a token protection when disabling a view and what I've done is I went back and I found the patch that fixed this vulnerability and I reversed the patch on the same open atrium install so we could see what happens in this attack that was present in the views module in 2010 so again we're in open atrium and one thing I want to show you if you look at something like a view oftentimes the machine name is exposed in the HTML classes so if you look at the page source you can potentially intuit the machine name without even having administrative access to the site so I can set up my attack potentially by just being a user of the site not being an administrator so we're back on my evil site as Jacob said you can use an image tag here so we have an image tag whose source is to disable this view so we're set up with our attack and again so this is a blog it has some pictures imagine I'm the administrator and I'm just attracted I see and my site was fine my home page has the view on it when I go and look at this click through into this blog post again submitted by our friend Evil Guy all we see is some images load we don't see that image tag that linked back to my site but if I go to my site and reload what happened? my home page is now blank my view is gone it's disabled so as you know a lot of sites are built with views you can imagine that this could have been a pretty devastating attack against someone's site who was constructed of views their home page would have been blank users couldn't have found the content they're looking for it wouldn't have destroyed the site but it would have been a real inconvenience and would have been a real black mark and an obvious problem with your site for all your users we talked about it it's actually pretty easy to first the user to visit a URL it doesn't have to be anything very complicated if I now tweet hey check these slides from the security presentation half of you will probably click the link and it can be some tiny URL and it will expand to the tag so we're kind of wrapping up here and then we should have some time for questions but we kind of wanted to get back to things so the two big things as Drupal developers cross-site scripting, cross-site requests for those are the vulnerabilities most often see especially in the theme layer cross-site scripting holes and custom themes there are other topics you should be aware of and I just wanted to run through them real quickly so one of them is access bypass so you'll see some security advisers talk about access bypass that's something like where a user a site has a node access module users not supposed to see content but there's a flaw in some other module for example it has a block listing nodes and so this private content is listed even though the user shouldn't have access to it someone suggested also I talked about caching and if you use especially some kind of custom caching implementation you can run into the same problem so for example if an administrator views a page and it's cached and the cache doesn't properly key by role, user role then some other user might view the same page an anonymous user even and see all the content that the administrator could see so that's another kind of access bypass it could be through caching it could be through mistakes in logic and it could be through failure use Drupal APIs another example of something that we see once in a while is file inclusion which can lead to a code execution and this is basically the same as PHP filter so a file is loaded and any PHP code inside it is run again the access way can be pretty interesting so for example your access log your Apache access log well the user can construct a very long URL that goes into your Apache access log if they can then cause your Drupal site to include the access log as a PHP file they may be able to execute the PHP code that they've saved into your access log as a log entry so again this may not sound like something feasible but this is a sort of attack that does actually happen another example of a sort of slightly more exotic but dangerous attack is directory traversal and this is again where we may be able to include as content in the page a file that the user is not supposed to see so the classic example for Drupal is if they can see your settings.php file they can get your database credentials and depending on your server setup they could then connect to your database so directory traversal often is if you don't escape things like slashes and dots that can let be put into the URL and if you're looking for example for template file based on the URL you may be misled and load the wrong file finally just a note on tools there are a lot of good tools you should be using you should be connecting to servers using secure shell using secure FTP like unencrypted FTP really should be left by the wayside if you're still using those tools it's time to update your tool chain and use secure tools and especially for SSH the best practice is not to use passwords at all you can use key based login and that basically totally prevents brute force attacks on your server so again if you're running a server you should be using SSH you should be using key based login not something we can really get into detail here I just want to place that idea in your mind go think about it if you're in that situation and you're not saying yes we do that already then you should be going back and reviewing your practices the concept is that when you're using SSH as keys it's not only something you know which is the password but it's also something that you have but it's basically two layers of security and just to revisit access bypass again so in Drupal 6 if you're doing a node query you may remember or have used db rewrite sql so in Drupal 6 this is an important function it makes sure that node access is respected when you're listing nodes in Drupal 7 the database layer has changed a little bit and instead of wrapping your query in a rewrite function instead you tag the query and so the tag is the node access query and this ends up having the same effect so in Drupal 7 you'll have access so that it will be filtered for the current users node access in Drupal 6 use db rewrite sql we'll of course post these slides but there's a lot of resources you should be aware of if you're talking to someone about Drupal and whether Drupal is secure the Drupal security report is a great white paper that kind of covers a lot of these things at a high level talks about Drupal's approaches why it's secure, what the Drupal process is that's a great thing for you to have to be trying to sell Drupal to a client on Drupal.org we have documentation pages about writing secure code also documentation about secure configuration for your Drupal site there's a whole site dedicated to hacking and preventing hacks of Drupal called Cracking Drupal there's a corresponding book written by Greg here in the front who would be happy I'm sure to sign it if you buy one so he has blog posts there as well as a lot of good material and Heine who's the former head of the Drupal security team has his own blog post where he's put up a number of interesting discussions and investigations into Drupal security and finally there are two Drupal modules that will help you review your code so if you're writing code and you feel uncertain and think you might have made some kind of basic mistake take a look at the security review module or the coder module and those will run some basic checks on your code and make sure that you haven't made any of the most common or critical mistakes last before we finish at Acquia we have two usability experts Lisa and Darmesh and they're trying to do user experience studies for Drupal if you're willing to help improve Drupal's user experience it would be great if you could get in touch with them particularly I assume most people in this room are site builders or developers so contact Lisa Rex either at Lisa Rex or Lisa.Rex at Acquia it would be really great if you'd be willing to just sit down and do ten minutes of your time and make Drupal better so with that thank you please evaluate the session the direct link is there node 1324 and if anyone has questions we have if I have a minute or so for questions feel free to use the microphone we have a public service announcement recently about security reviews of dev and alpha releases and I'm wondering if you have any comments about under what circumstances is acceptable to use a dev or an alpha release in production I mean it's the rare person who has the luxury of not ever using a dev or alpha release so I think at some level though you have a higher responsibility to use the code you need to be aware that if there's a vulnerability it's going to be publicly announced potentially right away so you're not going to be protected the security team often will work with the maintainer and make sure that there's fix available before the security vulnerability is made public for that dev or alpha release the vulnerability will be made public before there's a fix so you potentially need to be prepared to get involved with the dev you need to be able to evaluate whether that affects you it basically just means you have to be more involved pay more attention I'm not going to say don't do it but the whole process we have set up is really for fully release modules I think the flip side of that is if there's a module that's important to you that's not fully released you should be working with the maintainer and encourage them to get it to 1.0 so that they can take part in this whole security release process and also security awareness basically you all or all of us who are Drupal module developers should be really releasing stable versions it's not like if you do only beta version or alpha version you're protecting yourself from all the security team that's coming to you you're actually if you do stable release you're protecting your users because we all do mistakes and if you do a mistake in a stable release everybody will know about it if you do a mistake in an alpha version it will be public I work with a lot of designers who for example in blocks they like to use PHP filters so I understand from a programmer's perspective how I would do it be a custom module make sure all the user input is filtered but would you recommend me just going to them and telling them stop doing that you need to come to me to create a custom module to make any user input yes yeah and it is an evolutionary process at one point Drupal.org had pages and blocks that were PHP and in a drive to make Drupal.org secure all those removed modules and maybe you can tell them they could prototype it on their local site and give you that PHP code and then they prototype it as a module and double check it but they shouldn't be putting PHP on the live site if you want to be secure that was essentially my question I was just wondering if there's any been any way discovered to essentially sandbox or CH root PHP code so that it can't access the rest of the site basically run it locally run it in a development environment once it's on your Drupal site it has full access to everything yeah I was wondering do you guys have a response ready for the cross-site request forgeries in 7.1.2 so can he repeat that do you guys have any kind of response for the cross-site request forgery vulnerabilities in Drupal 7.1.2 Greg do you want to cover it 7.1.2 which are the reports about the form tokens and sessions yeah form tokens and HTTP first yeah the response is actually documented on groupsdrupal.org basically the response is that we don't feel it's a valid report it's not a no we don't feel it is not a valid report so you just take a look at groupsdrupal.org I think it's a group called security best practices in security and it's documented what the response is so the one concern I always get from clients is well surely we can put images in a node right just inline is there a good place where there's an example of why allowing inline images can be insecure you mean why not put images into Drupal nodes so there's a couple of things so who is posting that content I think is the most important question it's users at the organization but in some cases they are are they trusted users most of them are trusted but they are planning on allowing right so I think part of it is whether or not you trust the users in part because in the example you can see there's an image tag to run a cross-site request forgery attack so if the users weren't trusted especially if they are anonymous there's a risk that they'll post such a if there was a vulnerability on your site they could post that image tag on your site in some place your administrators are likely to visit and that would mean that your administrators are likely to be attacked and I think that you need to understand you can find other ways how to do that you can use iFrames just direct URL using tiny URL or something like that so potentially you can allow your users to put image tags into your content but it needs to be part of filtered HTML filter so you filter anything that's dangerous so the image tag is not the important part so adding it because I know by default the image tag isn't in the filtered HTML so you're saying that if you put it in the filtered HTML but then also are you allowing anonymous or untrusted users to post this content that's the question for you untrusted users will be allowed in a future phase so then you need to take some action and not allow them to post image tags blindly and you can look at what Drupal.org just did which is I'm not sure where the code for this is but it actually checks and the tags are referencing an image on the same site and that's why Drupal.org recently allowed image tag images to be posted by every user whereas for many years it was limited to only more trusted roles on Drupal.org because that extra protection has been added in there so again you might think about a strategy like that if you need untrusted users to be able to post images you need to take some additional steps and I think the image was like image filter but there's also a module that's pretty handy called path filter image filter and path filter yeah I think so I think it's path filter and it's pretty cool because it also does other stuff like making sure that sometimes when you do when you develop content on your development environment users will put absolute URLs into the links and then the code or the content when you put it live or reference the development environment and path filter can make sure that all these URLs are not absolute but relative for example thank you okay thank you very much and please remember to rate the session that are interested in your feedback