 Okay. Good morning, everyone. I think we can start. So this session is about cracking Drupal. We will talk a little bit about Drupal security and the most common vulnerabilities that can be exploited and how you can prevent them. My name is Klaus Purra, and this is Peter Wohlenin. We are both members of the Drupal security team. So first, when you think about security, you have to consider some strategies. Security is based on trust, so it's important to specify on your site who can do what, who are the administrators, what are they allowed to do, who are the editors, maybe, maybe have an editor role, what are they allowed to do. And that plays into the principle of least privilege, meaning that each user should only have the necessary permissions to do their job on the site. So they shouldn't have any more permissions because things can go wrong with that. If their account is compromised, you want to keep the impact as low as possible, so you only give them the privilege that they need. For example, an editor most of the time will not need the permission to enable new modules or to disable modules, so don't give that permission to them. And the next thing to consider is the defense in depth strategy, which means you're not protecting yourself at one single point, but you're protecting you on as many levels as possible. For example, you make sure that your server is configured in a secure way. You make sure that your Drupal installation is configured in a secure way. You do your software updates regularly. And yeah, talking about software updates, that's the most important thing to do because there are obvious exploits out there. People have discovered exploits and they have been fixed in new releases, so you should apply those updates to your installation. And those exploits can be basically anywhere in your software stack, like for example in Drupal itself, in PHP, or in your operating system, even on the client side in your browser there can be security vulnerabilities. So when you're working as an admin on your site, it's important to use a secure browser because if you're using Internet Explorer 6, which has a couple of known vulnerabilities and somebody is able to compromise your browser, then they have the admin rights on your Drupal site, right? So yeah. And we have structured this presentation around the OWASP top 10. So the OWASP is the open web application security project. And what they do, they collect material around vulnerabilities in web applications, they list the most critical security risks, which is this top 10 list that we will go through and how it applies to Drupal. They also do some assessment of what is the attack vector of certain vulnerabilities and how can the weakness be exploited? What is the impact of invulnerability? They provide, for example, cheat sheets to prevent cross-site scripting attacks, so what you can do as a web developer to prevent that. Yeah, it's really an interesting project and you should definitely check that out. They have a useful wiki where you can get lots and lots of information, reference implementations and whatnot. So the first thing on that list which has really, really high impact when you have such invulnerability is injection. Injection means that you take user-provided input, which, for example, comes from something in the HTTP request that arrives on your site. It can be a part of the URL, like the get parameters, or it can be part of the post request that arrives. So if you have SQL injection, you should never directly concatenate user-provided text. In this example, the get query parameter into the query string, because what happens? PHP would just concatenate these two strings together and then pass it off to dbQuery. It doesn't look into $get here. It just passes it on. So what you should do instead and how you would use this API correctly is by using named parameters. And if you use named parameters, then everything that is provided to such a parameter is sanitized for you and the database can handle it securely. Same thing applies for remote code execution. So there are two problems with using Eva. First, you shouldn't use Eva at all, because everything that you execute should only be in files that you, as a developer, wrote. And the second problem here is that you just take whatever comes in with a post request and passing that to Eva. So this is a typical remote code execution vulnerability where an attacker can pass arbitrary PHP codes to your Drupal installation and it will just execute it. So don't do that. And as I already said, those are really high impact vulnerabilities because if an attacker finds a hole like this, they can basically do anything with your site. They can hide checkers. They can read all the data. They can steal the data. They can just abuse your site for some different purpose. Yeah. Second point is authentication and sessions. So you should choose good passwords. So I think Drupal core doesn't restrict you in any way what password you use. You can use contributed modules like the password policy module to improve the security of your password. So you're forcing users to use, I don't know, extra characters, more numbers, whatever. You should hash your passwords. Drupal core already does this for us. So we don't have to be bothered by that. And you should protect your session at ease because in an HTTP request, there's a cookie travels along that carries the information which user is performing this request. And if you're not using HTTPS, this cookie is transmitted in plain text and everybody who is able to intercept the traffic to your site can hijack the cookie and then pose as your user to the Drupal site. So really, you should use HTTPS whenever possible. And yeah, it's not possible for every site. So if you are embedding iframes, for example, where you talk to HTTP sites, then you might need some additional modules like, for example, the secure pages module where you can decide which page will be delivered on HTTP and which on HTTPS. Or another example is the secure login site so that you at least have HTTPS for your authenticated user and have the anonymous traffic on HTTP. The third point, and this is really an important one is cross-site scripting. And this is the vulnerability that we see most often in Drupal. So we see that in country we see it in Drupal core. And it works like this that an attacker is able to inject JavaScript tags. And because Drupal is a content management system, lots and lots of data is inputted by users, by administrators into the database. And then the HTML is assembled dynamically from those pieces of the database. And everything that the user provided text needs to be properly sanitized before printing into HTML because a browser just walked through the HTML and executes every piece of JavaScript it finds. It doesn't distinguish where the JavaScript came from if that is on purpose there from a developer that put it in the theme or in some template file, or if it was injected by some malicious attacker. And the thing about cross-site scripting is that you always need a user interaction from an administrator, for example, or from another user. Meaning if I'm able to inject some JavaScript snippet into your Drupal installation, it's pretty boring if that executes on myself if I'm the attacker. So I want to maybe hand a link to some administrator of the site, and when they visit the site, the JavaScript is executed on their behalf, and then their account can be hijacked and evil things can be done with their account. So there are two types of cross-site scripting. The first one is reflected cross-site scripting, where something that is currently in the request, like a query parameter here, is directly reflected in the HTML output, like some get parameter here. That would be an excess cross-site scripting vulnerability. And the typical penetration test that people use to find out if a page is vulnerable to cross-site scripting is just using an alert pop-up in JavaScript, right? So you put it in where I think the vulnerability will happen, and then visit the site, and then you see a pop-up. If you see the pop-up, yeah, that's bad. Then at the JavaScript that you injected before gets executed, and you are vulnerable at that place. But there are also more subtle vulnerabilities regarding cross-site scripting, like the persistent cross-site scripting vulnerabilities, where the injected JavaScript is stored in the database. So in this example, what an attacker would do, they would have permissions on the site to create nodes, and they put something evil in the node title, like some tags. And usually what Drupal Core will do for you, when you visit the node page, it will just sanitize the title for you, and yeah, the script text will not get executed. But then you, as Drupal developers, write your own page callback where you want to list, for example, some nodes as done here. So I have a list of nodes, I walk through them, and I built table rows here. The first cell in one row is the node ID, and the second one is the title. So this doesn't look suspicious, right? But one important thing, why this is vulnerable here, is that the render array that we have built for this table does not escape the node title for you. It would just print out each cell for you. So what you have to do instead, in this case, so the example why I'm using a table here, because I see that happen all the time when I review contributed modules on Drupal.org, Drupal is pretty secure out of the box in the form API in other places, and then people forget that, for example, in tables, it's not escaping for you. And what you should do here instead, if you're building this table manually, you should check plain the node title, because we are assuming that there is nothing malicious in the node title, it should be just plain deck, so we make sure with the check plain call that it is escaped. There's the documentation page on handling text security, I suggest you check that out if you haven't already in the security handbook on Drupal.org. And yeah, cross that scripting is really dangerous. So I was just talking about some JavaScript pop up that you can do as penetration test, but of course, an actual attack will use either some much more JavaScript, which has a much higher impact than just a pop up, they can load any script from another side and execute stuff. So and then the JavaScript can, whatever you can do, whatever you can do as an administrator, they can change site settings, they can change passwords of other users, they can change user roles, depending on what your account can do. If they trick you into executing the cross-site scripting, then they can do whatever you do. So there's also some interesting documentation from Acura, I think it was previous to Drupal scout on how you can handle cross-site scripting. And what Drupal does is it always filters on output. So this is the golden rule when handling data that we store exactly what the user types. So for example, whatever comes in over the form API is stored as is in the database. It doesn't get sanitized there. So there can still be dangerous things in the database. That's what you always have to consider. The no title, if it contains script tags, it goes with the script tabs into the database. And what we do, what the philosophy in handling this securely in Drupal is, when you pull out the no title from the database and then render it to the output, then you do the escaping. So conversions are performed when content is output and not when saved to the database. And the reason for this is that you might not always want to have an HTML output. So if you would sanitize it beforehand and then write it to some log file or to some PDF file, you would have garbled marker which wouldn't fit there. That's why we do it on output. And there is this gchid, what you should use in which situation. So the most restrictive thing that you can have is a URL with which you would check with check URL, which is basically just check plane plus filtering some dangerous protocols that you might not want on your site. The next thing is check plane. So if you know this is plain text, there will never be any HTML tags allowed here, then you would use check plane. If you have some rich tags where you want to allow bold text, for example, or you might allow want to allow some headings, then you would use check markup with a text format for that user. For example, there's in Drupal, we always have the filter text format which allows some tags, but it of course it doesn't allow script tags and other malicious stuff. That's a typical use case for check markup. And if you have just HTML and you don't have a text format available, then you would use a function like filter XSS where you can provide a list of allow tags yourself and everything, every, all other tags get stripped and removed. And only if you are absolutely certain that this is absolutely trusted, trusted data, then you can print it as is to the HTML output. But you would, you would rarely do that, you know, mitigating cross-site scripting. So Drupal core does a couple of things for us. So it sets the HTTP only flag on the session cookie. So if you have cross-site scripting attack, the attacker cannot access the cookie because it's protected by the browser. There are some things on the user form so you can only change your current password if, if you can only change your password if you provide the current password. So if an attacker would like to change the password for your account, they cannot do that without using your password. There are also text formats for different user roles. And this is an important configuration detail so you should configure text formats right on your site. But there are also new approaches like the content security policy standard, which is standardized in the W3C, which says that new browsers support that and no inline JavaScript will be executed. And in your HTTP response from a server, you will have a white list of domains where you can load JavaScript from, which is executed. So if, if an attacker would leverage a cross-site scripting on your site and they would like to load the script from their own server or whatever, it will not work because it's a part of the, of the white list. Unfortunately, not all browsers supported yet. I think some old Android browsers don't and I don't know since when Internet Explorer supports it. So we still need to rigorously escape user input. We cannot do away with that for now. Insecure direct object references. So this would qualify as access bypass vulnerabilities in Drupal. We rarely have that because we are using the permissions API and access APIs pretty much consistently. So the, the vulnerability, vulnerability here would be if you go to some random path and just fiddle around with some, with some ID suddenly you have access. So that, that happens rarely for Drupal, but it's more common for other web applications and framework where people program everything manually. Security misconfiguration. So you can do a lot to protect yourself on the server side and when configuring a Drupal installation. First thing to do is to disable PHP error reporting, which is useful on development side because you see exception, what goes wrong on a certain page request. It's helpful for development, of course, but you should never enable that on a production site because it would leak information to the attacker where on the server the document root is located, for example, or other details what database driver you are using, what not. Of course, you shouldn't use the PHP filter module. So you can disable that on the modules page, of course, because you shouldn't have any inline PHP snippets on your site. This is, it's a nightmare for maintenance because you never know which code did actually execute on a page. Oh, it gets load, loaded from database because somebody saved the PHP snippet there. I really would encourage you to implement preprocess hooks or whatever you do in your modules to implement your custom PHP logic, but please don't do it in some text fields. PHP files right to a private web server is also a mistake. So your Drupal installation and every PHP file that gets read and processed for a request should be read only because if an attacker can take over some request and write files, they shouldn't be able to change your code files. They shouldn't be able to change Drupal core and place some malicious script there. So a secure permissions configuration on your server would be in this example, where you have the WWW data user, which is the web server user, and you have some deployer user. In this example, I'm using the deployer user to update Drupal. For example, when a new security release app comes out, the deploy user is able to write all the files and replace them. And the WWW data user only has read access. So they can only read the files. With one exception, it's the files directory, because when people upload files, they have to be written to the file directory, but that should be your only exception. Everything else in your Drupal installation, your modules, your themes, your libraries folder, Drupal core should not be writable by the web server user. There's a documentation page for that on Drupal.org, which describes this in more detail, something to consider. Permissions. Yeah, I'm talking about Drupal user permissions here. So there are some restricted site owning permissions, and of course, you should never give them away to untrusted user roles. Always bear in mind, as I said in the beginning, you should only give away permissions to users that they actually need. Everything else can be removed. The same for text format. So there's the infamous full HTML format where you can put everything in, even JavaScript. And that also medically means whoever is able to access the full HTML text format can also inject script tags and then open up cross-site scripting vulnerabilities. So whoever is able to use the full HTML text format on your site can take over your site. You have to be aware of that. So don't use the user one account in a daily work because it has all its permissions. Usually permissions apply to every user account, but not for user one in Drupal. The best practice is just to block the account and not use it and create separate admin account for your own tasks. Even for yourself, you as a developer working with the site should not use user one, use your own admin account. Same for the editors or content creators on your site. Yeah, there are some obscure things that you even can do. Don't use the username admin for a user one name or for your own admin name. You shouldn't use user one anyway, but for your own admin account, you shouldn't use the username admin because it's used everywhere in private files configurations. So Drupal allows you to have private files that cannot be directly downloaded and it protects the private files directory with an HD access files. You can even go farther and just move the private files directory out of your document route. So we have this doc root folder here, which contains index PHP and audio Drupal files. And instead of having the private files directory somewhere in there, you put it side by side with the document route. So the web server can only deliver files that are in the doc root, but it will not deliver files that are in the private files directory end. Drupal can still read from there and deliver the files, but you cannot directly go there on the web server and access them. Same for the temporary files directory, it should also be outside of your doc root. PHP file execution. So Drupal uses the front controller pattern, which means most of the request, if not almost every request go through index PHP with a couple of exceptions like update PHP and grounded PHP. And there are some modules out there that require a PHP file that is directly executable. But there are actually not many files that that need that permission. So what we can do we just disallow execution of PHP files in all sub directories. And this is a great security improvement because even if an attacker is able to upload a PHP file to your server and place it in the in the files directory, for example, it cannot get executed because the sub folders are locked down and only things that are in the root directory can be executed. And if you have configured your server correctly, as I explained before, the attacker will also not be able to write into your root directory because they don't have the permissions to write it because the web server doesn't have the permission to write there. So this is a great combination having secure permissions on one hand and restricting PHP file execution, you get rid of a lot of security problems. And I also put the example configuration here for Apache, how you can configure that and for HNX. And we managed to get this into the HD access configuration default five for Drupal 8. So yeah, Peter, it's your turn. So we're halfway through the list of the top 10. Number six is sensitive data. So if you're using your Drupal site to store sensitive data, something like credit cards, personal information, you should encrypt that. So if someone gets access to your database backup, they won't be able to read the data. This actually presents though a lot of operational difficulties to actually have a password for the encryption that you can enter when Drupal is running, but yet not have that password be exposed together with the database backup or with your code. So really the best option here is if at all possible don't handle this kind of data. Do not put credit cards ever into your Drupal database, PCI compliance. The credit card standards are very difficult to meet and getting the difficult now and they're getting dramatically harder next year. If you're storing credit cards on your server in any form, you're going to have to go through tremendous compliance procedures to meet the credit card company's demands. So don't do it. Same thing for medical records. If you're storing someone's medical records on your server, you should really be at the level of an enterprise corporation that's going to have penetration testing, have security compliance and audits. If you're a small Drupal site and someone says, hey, I have this project just to our medical records, I would basically just walk away and say I don't want that liability. So we've talked before about secure transmittal of data, HTTPS. So just remember, especially someplace like a conference here, every piece of data transmitted over HTTP is potentially accessible to every person at this conference. So if you're visiting any website with any sensitive data and it's not using HTTPS, someone else at this conference could be reading it at the same time as you. So if your Drupal site presents private user data, your site should only be running over HTTPS. We mentioned before password hashing. You guys have probably heard a lot of cases Adobe, other large corporations, their password database is getting exposed, the good news. So this password hashing that we're talking about protects people with secure passwords. It doesn't protect people with insecure passwords. If your password is 1234, it can still be easily recovered even with the secure hashing. But if you have a secure password, basically the time it would take an attacker to recover that is going to be quite long. I mean, potentially days, weeks for them to crack it. So it gives you a lot more time to recover from a compromise of your site. So Drupal core seven and obviously eight will include a very secure hashing algorithm. Drupal six does not include one in core by default. So there's a back port of the Drupal seven algorithm that I would recommend that you apply to your Drupal six sites if you're still running them. You won't see any really operational effect, but it will make your database backups and accidental database tier. If someone gets access to your data, it'll make it much harder for them to reveal the passwords of all the users. Basically Drupal six as it is, it would be almost trivial to crack almost any password from the Drupal six database that's compromised. So this is actually an important security measure if you're still running Drupal six. Point seven on the El Wasp list is missing function level access control. And that sounds a bit confusing, but let me give you a concrete Drupal example. So you guys have probably written hook menu implementations. And often when you develop a new module, you don't really want to worry about how what roles are going to access the new functionality. You just want to see if it works and you just put this line access call back true. Or occasionally people make a mistake and they use the return of a function call on this line instead of a constant or instead of an array specifying a function to call at runtime. So if this gets saved to the database with something that evaluates as true, anyone on the internet can access this page. So if you accidentally ship your module like this, you post it, people download it, start using it. They'll probably never notice the problem as administrators. They expect to access it, but someone can browse this page. Do you guys maybe close the doors? They could browse this. Anyone on the internet can browse this page and now can change the settings for this custom module. So in this example, the correct way to do it is to supply instead of the access callback, we can just use access arguments. So the default access callback is user access. And the first thing in the array here is the permission that we're looking for. So access administrator on my module, now that permission is enforced to access this page callback. Another example of this is node access. So failing to use a node access system when you're making a list of nodes in custom code. So this example here shows you the correct thing to do in Drupal 7, which is you need to tag your query and say this is a node access query. So any time you're making a custom list of nodes, you need to add this tag and then Drupal will automatically apply node access in addition, if that's necessary, if you have a node access module enabled. Again, the problem with this as a custom module developer, you might forget to do this. And at first, you'll never notice the bug because, of course, administrator, you can access all the content. And potentially, even the people using this module wouldn't notice because they don't have an access control module. Then someone adopts this module for the site. And this listing might include something that should only be accessed by authenticated users or only should be accessed by administrative users. For example, here, the expense report type should only be accessed by the administrators of the site. But without that tag, any user who visits that listing page will get the list of expense reports. So Drupal 6 has a different strategy. There's this function called db rewrite SQL. So if you're using Drupal 6, look that one up and use that. But Drupal 7 simply applying this tag just makes the magic happen. That's all you need to do. 0.8. So 0.8. This is actually, again, something that we see fairly commonly in Drupal, I would say after cross site scripting is probably the most common dangerous vulnerability we see in Drupal. And this is a vulnerability that I think a lot of people struggle to understand what it means and how it operates. So we want to walk through a little bit of the details here. And again, we'll use hook menu example, because this is exactly the kind of thing you might write in a custom module. So in this case, we have a path that allows us to delete an object from the database. And this is a pants object. So you don't want to go without pants to the conference. So you don't want someone accidentally delete your pants. So looking at this, you might think this looks okay. From our previous example, we talked about access arguments. This has access arguments, right? So only, if you were just looking at this naively, you would think only administrators can access this path. If they have that permission. So we're safe. But in fact, you're vulnerable in this example to cross-site request forgery. And let me show you why. So imagine that the attacker knows that you're running this module, and they want to take off your pants. All they have to do is post in their blog an image tag like this with a source attribute pointing to the delete path for your pants. They maybe now send you a friendly email saying, could you please look at my blog post and tell me what you think. You go to their blog post. Your browser will load this image tag. The browser will then fetch the URL for the image. It will send along your session cookie. Automatically, you don't have to do it. You can't see that there's an image tag on the page. Now your session cookie came along with a request. Drupal says, great. I'm deleting your pants. Delete query executes. Your pants are gone. So this is actually a can be a devastating attack. There were some views UI had one not so long ago where people could come in and delete or disable all the views on your site if you had views UI module enabled. So that could be pretty crippling for a lot of sites. Maybe it wouldn't be something you couldn't recover for, but your site would be down for an extended period of time if that happened. So Clusty has a blog post linked there explaining a little bit in more detail about that. But again, this is an exploit to take very seriously and to think about. And the good news is that Drupal has pretty good ways to protect yourself against this. The most easy and obvious way to do this is to use the form API any time you do a write operation or a delete operation or an update operation, anything that changes data, anything you might think of as destructive, anything only administrators should do that, for example, affects a user like blocking a user. The best way to do that is to use form API because form API has built in protection against cross site request forgery. If for whatever reason you actually need to do these things on a get request. So just a link that someone can click. It's not recommended, but once in a while for usability reasons or whatever you need to do that. Or maybe as an Ajax callback, the Ajax needs to fetch some data or needs to make an update. You should put a cross site request forgery protection token in the URL. So this is a token that the user making their request can access out of the page content, but the attacker cannot access. Unfortunately Drupal 7 doesn't have fully built-in support for this, but you can use the Drupal get token function to generate the token and to check the token. And there's a lot of examples in contrib that would show you how to do this for Drupal 7. For post requests again, always use the form API. People sometimes mistakenly think that a post request is safe from cross site request forgery because they think, well, I can't click a link. There can't be an image tag that will make a post request. But in fact, JavaScript on someone's site can make a cross site request for post request on your behalf. And your session cookie will go along with it. And if there's not this token to be checked, it will execute whatever that post request is asking to do. Also, even a more sort of dumb and old fashioned way, someone can put a form on their website and put the action of the form pointing to your administrative interface. They might, you know, it might look like a comment form. You enter a comment, you submit it, boom, your custom form that didn't use Drupal form API was vulnerable. The data comes through and Drupal executes whatever they ask to do hidden probably in the attributes of that form on their fake comment form. So this documentation page explains more. It's under the secure coding handbook section that we'll mention at the end. But if you want to know specifically about cross site request forgery, take a look at that page. OSP number nine, which should probably be really number one is using components with known vulnerabilities and closely started off the talk talking about how you need to keep your software up to date. Keep your software up to date is probably the most important. And yet the the thing that people have the greatest difficulty doing. You need the problem is that once an attack factor is known, people can automate this. There will be scripts that simply test every Drupal site in the world to see if they have the vulnerability. So it's not it no longer becomes personal. It's simply if you have your site up to date, you're safe. Your site is outdated, you're not safe. So you do need to update your Drupal software, your server software, PHP, regularly. There's a Drupal.org has a security mailing list, which will automatically mail you all security advisories. So you can sign up for that. You should be automatically signed up for it if you're a module maintainer. But anyone who has a Drupal.org account can sign up for it. There are also RSS feeds. And Drupal itself has update status notifications. So hopefully everyone is familiar with the update module hands, anyone who doesn't know about update module. Okay, hands for everyone who enables update module on their sites. I wasn't 100%. Okay, so you should enable update module on your Drupal site. It will tell you in the Matt administrative interface about Drupal security updates and even more conveniently, and I'll show you on the next slide, it can email you every time there's a security update directly from your Drupal site, letting you know that this security vulnerability applies specifically to your Drupal site. In general, you can keep track also at this slash security page on Drupal.org. And sometimes not thoroughly considered option is that you should disable software you're not using. If your server is using software you're not using, disable it. If Drupal has modules installed that you're not using it, disable them. Just by reducing the number of things you have to keep track of and keep up to date, you make your job easier, keeping them up to date. And you reduce the chance that there's some vulnerability that is exploited before the fix is done. So here's an important tip for anyone who hasn't done this, hasn't found this page. This page is actually a bit hidden, which is why I wanted to specifically call it out. So it's under the report section. So you might not find it as a site setting. But under the upstate status listing, there's a settings tab. You can go in there, enter one or more email addresses. If you don't want noise, just about module updates, you can toggle it to security updates only. I would recommend you do this for every Drupal site you put in production. Put the list of people here who might possibly respond. And you won't see very many, right? There's not tons of security updates that can affect your Drupal site. So once a month, maybe you'll get an email, and that's a great time for you to know that you need to respond immediately. You don't have to pay attention to mailing lists, other things. Your Drupal site will tell you, my module is up to date. Come update me. So please do this for your production sites. It will help you keep Drupal itself up to date. The final AUSP point in the top 10 is unvalidated redirects and forwards. And this is actually something where we close the number of security holes in Drupal core, not long ago. So again, I hope everyone is running an updated version of Drupal core. So as an example, Drupal has this function Drupal go to. And if in your custom module, you look for a query string parameter, that's the target. So for some reason you want to forward people to another page when an action is done. Drupal commonly does this with the destination query parameter. You guys have probably seen destination. But your module decided to use target instead. And you say Drupal go to get target. Looks safe. However, Drupal will happily send the user to an external site. And this gives an opportunity for an attacker to basically perform a phishing attack on any user of your site. The user trusts your site. The attacker sends them a link with this query string. The query string, when they go visit the page, will redirect them to the attacker's site. The attacker's site might look like your Drupal site or might look like a banking site. Might look like something they're expecting to see. They might then log in. They might enter their personal information, not realizing that they've been redirected to the attacker's site and are not still on your Drupal site that they trust. So in this case, we have a custom query string. You need to sanitize it using and check that the URL is not external before you send a user there. The good news is with these recent fixes, the destination query string that Drupal uses all over the place is saved by default. So that will no longer allow forwarding the user to an external URL. So if you use again the built-in form API, use Drupal's built-in, you know, destination query string handling, that's handled for you. But if not, make sure you check whether URL is external before you send the user there. Okay. So this is where we start summing up. So we have these top 10 vulnerabilities. And we could see all these vulnerabilities kind of fitting into a broad pattern, especially the ones that come from code mistakes and your custom code. And the broad pattern is that you should not trust any user data. And user data can come in a lot of different forms. So user data can come through the URL. It can come through the request in the form of HTTP headers. Or it can come from content that users have submitted and lives in your database and you load back from the database. So all these things are user-provided data. They should not be trusted. They're basically toxic, dangerous. You should consider all of them to be attacks on your site, in a sense. The thing is once you, if you accidentally trust some of this, attackers can use browser features to perform actions behind the user's back. So users don't have to make a mistake. They could simply visit the wrong site. They could follow a link and get attacked. So again, cross-site scripting allows JavaScript to run automatically without the user knowing it, perform some action. Cross-site request forgery, as I show you, you could even use an image tag. You could use JavaScript on another site. Perform that. The user doesn't have to know what happened. Or these open redirects where they think they're going to your site and they end up on some third party attacker site. Again, software updates. If there are known vulnerabilities, if your site still has them, attackers can use automated tools and you're going to be exploited eventually. So make sure you keep Drupal, your contrib modules, your server up to date. And really, you should ask yourself if you're prepared for an attack. Yeah, we're hitting a lot of these points again and again, but I feel like if you're prepared for attack, you're either going to prevent the attack or be able to recover quickly versus being basically down for a week. So you ask yourself, is your code in version control? Do you have a history of all the changes you code who made them? And can you compare the code you expect to be deployed on your server to what's actually there? That's going to prepare you in case there's some problem. Do you make backups? Maybe that sounds like a stupid question, but a lot of people don't make backups or don't check that the backups are valid. If you don't have backups, you can't recover from an attack. Do you have separate logins for each administrator for the account, each administrator for the server? If everyone's sharing the root login to your server and something bad happens, how do you know what person lost their password, what person maybe turned against you? Same thing for administrator accounts in Drupal, you can see who logged in, who took certain actions. If there's separate accounts, if there's one shared account, you have to go through the hassle of, you know, again, communicating the new password to all the users and then realizing that one of those users might have, let's say, a compromised browser or some other problem where that new shared password is again immediately going to be exploited. If you're responsible for the server, including a virtual private server, virtual private servers can be vulnerable to the same exploits as an actual physical server, so make sure that server software is up to date. In general, it's very useful to have an out-of-band way to log in to your Drupal site. That might sound fancy, but simply most people can do this is use SSH and Drush. If someone got into your site, change the email address on your account, change the password on your account, and you couldn't log in, you couldn't reset your password. You could still use Drush to give yourself a password reset URL or even go into the database and change your password so that you can get back into the site. Finally, again, sort of more system level, but also Drupal, do you know where to find the log files? If there was a problem, could you go find the log entries and maybe reconstruct what happened? Ask yourself all these questions, and then the flip side is if you were prepared, you will be able to recover from an attack. You want to determine what was compromised and when, but sometimes that's actually sort of a secondary consideration. Rather, you'd like to get back online quickly, so make sure that you make a copy of all the site files, all the uploaded files, everything you can in the database as it was at the time it was compromised, so you can go back later and figure out what went wrong and when it happened. Restore from backup because, of course, you've been making backups and testing them. Update the code. Replace the Drupal code. Make sure the server software is up to date. Change all the administrative passwords. Again, if you have individual administrators for your site, it's a lot easier to communicate to them individually that they need to reset their password rather than trying to share around a single password. You may need to change server keys or SSL keys if the server was compromised. Then, since you have your code in version control, of course, you can audit your code and compare what was running on the server, what was supposed to be deployed to what you had accepted into your code repository. Finally, I mentioned log files before. An important thing to do right away as well as saving the site code is to save all the log files as soon as you can when you realize there's a compromise. A lot of servers have log rotate set up, which means that after a day or a week, the logs with the data you need will be deleted. As soon as you realize there's a compromise, you should go and save off to a secure location or locally. All the log files you can find so you can go back and analyze them later and look, and you might see the IP address that someone came in on, the post request that they made, what path it was to, things like that that might give you a clue where the vulnerability exists in your Drupal site. If you don't have the log files, you won't be able to drive that information. Now you're all probably a little scared, but good news, there's some things to help you. Some useful modules. If you want to audit your own site, the security review module you can run on your site. It will help you uncover some of the common vulnerabilities. Paranoia module is a long-standing module from Gerhard who will block use of PHP module or PHP in other contrib modules. It will also lock down the user 1 account so no one can edit it. This is very useful just as a baseline. You could deploy this on new projects if you're handing the site over to someone and basically be like, you just can't do it. PHP is disabled, there's no way for you to turn it back on. That will prevent them from feeling that they should take a shortcut and making their site vulnerable. There's also a relatively new module called SecKit. This will help you implement the content security policy that Klaus was talking about, which is special headers that whitelist the JavaScript and other elements of your page and can prevent a lot of these cross-site scripting and cross-site forgery attacks. So check that out, especially if you have a relatively new site where you don't have inline JavaScript. So the inline JavaScript in your theme or you, for whatever reason, allowed users to post inline JavaScript in blocks or pages. It's going to be hard to sanitize it correctly, but if you have a site that does not have those problems, you should think about implementing these and that will protect users on a lot of the modern browsers. Finally, good news, a lot of security improvements in Drupal 8. So Drupal 8, the twig theme layer, twig templating system is now the norm for the theme layer, and twig will automatically escape variables so that check plane function, basically equivalent, is run on all data that's output in twig by default. So this will actually prevent probably 90% of vulnerabilities, which roughly speaking, 90% of the vulnerabilities are cross-site scripting vulnerabilities in custom themes. When we audit sites, actual production sites, that's where the vulnerabilities live. So that will prevent that by default. Klaus mentioned forbidding PHP execution. That comes by default in Drupal 8. Again, a default support for cross-site request forgery tokens in the routing system. Drupal 8 has a security enhancement that we're backporting hopefully to Drupal 7, which is that session IDs in the database are now being hashed. What that means is if someone gets your database back up currently in Drupal 7, if your session is still open, you're still logged in, they can simply copy that session ID out of the database and be logged in as you to your Drupal site. So this hashing prevents that because the user cannot drive back the plain text of the session ID. Drupal 8 uses guzzle, which does a better job of HTTPS peer validation. So if using web services can prevent man-in-the-middle attacks there. And a number of permissions have been split up and become more fine-grained. So administer users in Drupal 7 and before basically lets you do almost anything. Drupal 8 splits that up, seeking again, using that principle of least privilege, give the users only the user permissions that they need to do their job on the site. And a little tombstone here for PHP module, it's not actually dead, but it is in contrib, moved out in contrib now. So again, reducing the temptation that people in Drupal 8 will enable that module and use sort of hackarounds instead of properly writing code and putting it on their file system. So finally, just a note about the Drupal security team. There's a handbook page here about the security team, about what we do, about what our process is. So I do encourage you to read that because people often have misconceptions about what we do. One of the most important misconceptions is that people think that we actively audit code. And we do not actively audit code. We generally receive reports from contributors, from external security researchers, saying, I think I found a vulnerability. And then we go and invalidate the vulnerability and work with them and the module maintainers, the core maintainers to develop and release the fix. So we're not auditing. We will not check your module for you. You need to check your own modules or have someone help you. If there is a vulnerability found in your contrib module, we will work with you to make that security release. And we have a policy of responsible disclosure, which we don't let publicly information about security vulnerabilities out until we have a fix, if at all possible. Another thing to look at security.drupal.org has almost no public content. But you can see there the official list of security team members. So if someone contacts you and says I'm a member of the Drupal security team and you have a bad feeling about it, you can check this official list and make sure they are. The Drupal security team also overall defines the security policies and risk levels. So when you see things in the security advisors about what the risk level is, and or you might see a notice about some issue was allowed to be public and other issues were fixed and made advisory. So the security team defines those policies. Again, an important policy is that we do not protect vulnerabilities in unreleased modules. And unreleased modules, anything without a 1.0. So if you're using an alpha beta RC module and the security vulnerability in it, we will basically say to the reporter, that's great. Please post it publicly. That module is not yet officially released, and we don't support not officially released modules. So people often a bit shocked by this important thing to consider when you're picking modules, pick ones with official releases that are well supported by their maintainers. Finally, here's a list of resources. Again, these slides will be posted. So you don't have to copy all these down. But in the handbook, writing secure code, a great handbook section, a great handbook section also secure configuration for your Drupal site. A little article here on interaction to cross-site scripting, if you have any questions about what that was. Look at the list of security advisors for Drupal.org. In addition to knowing that your site is up today, it will also let you kind of get a sense of where the vulnerabilities tended to crop up and what to think about. And this talk was sort of named based on a book called Cracking Drupal by Greg Madison. So there's a website with a lot of interesting content, as well as the book itself. So I encourage you to check out that site if you're interested in this topic. And thank you, and we'd be happy to take questions. So I think there's a microphone in the middle. If you could reach that, or otherwise we will just repeat the question. There's a question. So the question was whether we have an opinion on Drush and whether when an attacker uploads a shell, what happens to the security around Drush? I think if the attacker uploads a shell, it doesn't matter if you have Drush or not, basically. Because the database credentials can be seen, right? So they can execute that. If PHP is on your server, they can generate PHP files, execute PHP files. So Drush would be a convenience for some attackers. But I think fundamentally, if they get a shell on your server, you know, it's too late. So the question is, based on reports, we have a sense of how many Drupal sites are attacked or compromised. So actually, that's another good point about what the security team does. So if you email us and say my site was compromised, we'll say, I'm very sorry. Here's a handbook page with a list of service providers who might be able to help you. So we don't collect any kind of metrics and we don't help individual sites that were compromised, other than like the Drupal.org site itself, if it was compromised. So I would say 100% of Drupal sites are attacked. I would simply say 100%. If you have a Drupal site on the web, it is being attacked at some point. You can often see in your logs, people will be making requests, even to vulnerabilities in WordPress, because why not? It might be a WordPress site that just looks like Drupal. Or a Drupal site. You know, attackers, it doesn't cost them anything to make these automated attacks. So 100% of all Drupal sites are always being attacked. The percent compromise, I think, is quite low. You know, there have, it's been quite a while since we saw sort of a vulnerability in core that was severe enough. There's sort of effective and widespread automated attacks that I know about. I mean, that was XMLRPC, which is quite a number of years ago now. But again, like if there is a vulnerability, your site is being attacked all the time and it will be exploited. So that's why you need to update quickly. Yes. So what the security team does, it doesn't provide individual support for sites. So we don't accept any payment or work them with one specific site. What we do is work on a Drupal core software itself and on a modules and coordinate that, that we get releases of the open source software out. And what we react, people too, is a list of supporting partners or companies that you can go to that help you fix the problem. Lots of hands up. Okay, so a question about protecting its cross-site request forgery. If you have different links, for example, to different pants that you might want to take off, it would be probably a best practice to have a unique token for each one. So you could use the ID. The main thing that prevents is some kind of replay attack. So if your site is not using HTTPS and someone watches the request go by and you have a shared token, then they could replay that same token to delete some other pants. So best practice would be to use a unique link for each, each object. Yeah. So what you would do is just use Drupal get token and you can pass a value to it. And you can just, whatever that link is, taking just a note ID into that value so that the token is different per link. Okay, so the question was about contributed modules. Yes, unfortunately, we often see that contributors will include feature changes or some other changes along with a security release. We, for certain large models, especially like views, have, have encouraged security only releases, but we don't sort of have the ability to force maintainers. We do recommend that they do that. And maybe we need to improve our documentation. We did do that for Drupal core. You may have noticed that we now have security only releases for Drupal core. That policy we started maybe two years ago, roughly, but for exactly this reason that people didn't want, you know, other fixes mixed in with their security fixes. So we do encourage module maintainers to do that, but we can't force them. Yeah. So, and if you are a contribute module developer, please don't commit all the things before security release. Well, and actually get makes it very easy to have a security only release based on the last table release. So there's no reason ever to that you would have to include other fixes. Unless that's, you know, dependency for the security fix. So, you know, if you're in that position, please do work with the security team. We can help you figure out how to do the get branching create the security only fix that merge that back in and later you can make a feature fix in the back. Good question. So with the update module, is there information on how many people don't update? And yes, in fact, you can go to Drupal.org. And the uses statistics will show you per module version uses statistics. So you can, in fact, for people that have turned on update module, you can see how many of them are ignoring it and not updating the modules to the secure version and even for Drupal core. So yeah, absolutely. You can get a sense from that of how responsive people are. So question is whether we have a known black list of IPs of attackers and short answer is no. I mean, the problem is that someone who's really motivated to do this will use like a, you know, botnet where they have access to thousands of IPs to execute this attack. So if you yeah, clearly, if you see a specific IPs attacking your site repeatedly, you can block them preferably at the server level or at the Drupal level. You can even do that automatically. So you have some intrusion detection system that automatically blocks IP addresses. If they trigger too many permission denied HTTP responses, for example, you can do stuff like that. Okay. Okay. So yet a comment was there's the HTTP BL module that you can use, which I guess, which maintains a list of IP addresses that are currently evil. There you go. There's a module for everything in the back. So I couldn't hear the Drupal six and then what? Okay. So after the support period for Drupal six ends, which is going to be six months after Drupal eight, the current plan is to support Drupal six for another six months after Drupal eight dot zero gets released. Right. So question is, should you consider them basically insecure by default at that point and I would say no, but you are really on your own. So security vulnerabilities might be reported in Drupal seven that are present in Drupal six, and there won't be an official release fixing those. And this happened, you know, in the past for Drupal five for Drupal four seven, we saw this that, you know, there were known vulnerabilities and people still kept running the Drupal five sites because they felt comfortable self supporting. So I would say it's not definitively vulnerable. But as time goes on, there will be more and more potential exploits that are found, you know, so so I definitely consider now thinking about your migration plan. Again, it depends how comfortable you are supporting the site on your own without having official releases. You know, I definitely think you if you can be off Drupal six by the time this window runs out, that's the best option. But it's not automatic that there's a problem. It's simply if someone finds something, you won't have a release to help you fix it. Yeah, so there's the offer from the Drupal security team that sites that are heavily invested in Drupal six can team together and extended support. But I think that did not get that much feedback so far. So I guess after six months, Drupal six would just run out. But if you're interested, just talk to this Drupal security team, if you would like to work on supporting Drupal six further. So I think we're at the hour. Do we want to take another question? Maybe one last? Is there an automatic way to update Drupal core modules? I would say Drush is probably the most automated way that people use. You know, and again, if you're using a version control system, you can have a local copy update and then test and push it up. The there is the update module will allow you to update contributed modules, but the configuration for that is is not trivial because Drupal does not want the Drupal files to be writable by the web server. So you have to go through a bunch of steps. So I would say that the best and fastest way to do this is if you have Drush installed and you know how to put the updated modules into your vision control system. But I wouldn't recommend it. So as we heard before, contrib modules often ship with additional features and they have to test that. Again, a reason to have a local version in revision control system and get tested locally, make sure it works and then you can deploy it. So anyway, thank you everyone for coming. I hope that was helpful. And again, we will eventually post these slides complaining to them. They're not yet. So will they'll either be on the session node or a link from there to where they're posted? Then second question. Yeah.