 So, welcome to Cracking Drupal. This is a sort of, it's in the PHP track. This is meant to be a general interest to PHP developers, but it's definitely a developer talk. I'll show you some code samples, but not too much in depth, but mostly focused on concepts, and then also connecting it back to Drupal and talking about how Drupal helps prevent some of the most common vulnerabilities we'll talk about, and in which cases Drupal can't really help you, and you do things right yourself. Moche, assuming he shows up, and me are members of the Drupal security team. So I get to put on my official Drupal security team hat. So we do these kind of presentations. So I've done this one actually with Klaus a couple times. He handed it off to me, and Moche did this time, but we do them to basically help improve the general state of security knowledge and improve the overall security posture of Drupal code, especially a contributed module, since obviously contributed modules get a lot less attention than Drupal core in terms of people looking for security vulnerabilities. One of the other things you should know about the security team, I think we'll mention at the end, is that we don't actively look for problems. We basically handle things that are reported to us. So you should not imagine that we are proactively scanning your code at this point, but instead usually it's another contributor. If there's a module on Drupal.org, a contributor will notice there's a problem reported to us, and then we work together with a maintainer to fix it, as opposed to us being proactively looking for problems. Okay. So the overall kind of framework for the talk here is we're just going to talk about security strategies, and we're going to talk then, as I said, particularly about PHP and Drupal. And overall, think about your security strategies. This is a big picture for your website. So in terms of your website, any kind of application, you need to know who you trust and what you trust them to do. So for example, do you trust your editors to reconfigure the site, enable modules? I hope not. You should instead be thinking about how do I give the editors the least amount of privilege that they need to do their jobs. So this principle of trust, knowing who to trust to do what feeds in to the principle of least privilege, principle of trust is also very important about data that you're dealing with. Do you trust the data? And you'll see over and over again, these vulnerabilities basically come down to the case where you trust data that came from a user when you should not have trusted it, because that user might be an attacker. Basically, user is synonymous with attacker. In most examples I'm showing you here, any user of your site could potentially be an attacker. So you don't want to trust the data that came from the user. So don't trust the data. Figure out who you want to trust to do what. Edit, audit your permissions, set them up so you give people the least number of permissions they need to do their job. And we'll talk about that in depth later. And then think about defense and depth. So you don't want to have a single point of failure where if someone gets through that, they basically put the missile into the desk and it blows up. So you want to have, if possible, in all these different attacks scenarios, you want to have some fallback, some possible mitigation, something that makes it not as bad as it might have been otherwise. If you do that, if you have those layers of defense, then any single one of them failing doesn't mean a catastrophic failure. This is a broad principle. Not always possible, but something you should strive for. And then one of the most important, yet obvious, things that people fail to do is just keep their software up to date. So if you're running a Drupal site or if you're running a server, no matter even if you're running your laptop and you aren't updating your browser, the browser software, all these things make you vulnerable to exploits that are commonly known and people automate those exploits. They will exploit you over and over again. They'll exploit all your sites. They will exploit everyone running the out of date browser. So the best way, really, you have as a normal human to not be exploited is keep that software as up to date as you can in all the different layers, your laptop, your server, the web application running on top of the server, the database, server software. All those things has to be kept up to date as quickly as you can when you see security announcements come out. So the framework for this talk is going to be the OWASP top 10. People know about the OWASP project. Good, some, but definitely not everyone, maybe a third. So this is a sort of open knowledge sharing project. It's called the Open Web Application Security Project. It focuses on PHP applications and it strives to disseminate sort of best practices, information and lists of the most critical security vulnerabilities and sort of their attack vectors. And that list is called the OWASP top 10. So that's going to be the framework for this talk, but I'm going to run through the OWASP top 10 and show you how that relates to PHP code in Drupal and specific and then how you can avoid being a victim of one of those OWASP top 10. People often say, basically, if you're a victim of one of these things, you weren't even really trying because it's the top 10. Now, you know, if you fell victim to top 10, you weren't doing your job. You at least fall victim to number 11, something a little more obscure. So they update this less every few years based on doing surveys of the PHP community and they order them through a combination of frequency and severity. So you'll see that the number one is not necessarily the most frequent, but is the most absolutely most severe. So the most important thing to avoid and I'll talk a little bit about the frequency of these things within Drupal as we go through them. So OWASP top 10 number one, this is the thing you must avoid at all possible cost. So they broadly term this injection and basically injection means that the attacker is able to send some data to your site and that data is executed in some way as a programming language or as SQL. So two obvious and slightly distinct things are SQL injection, right, where the attacker's string is executed as SQL and runs a database query versus code execution, commonly called remote code execution, where the attacker is in some way able to actually upload PHP code or cause PHP code to be executed. So these are both very bad. They basically both will likely mean all the data on your site can be disclosed. The attacker may well be able to take over your site, but they're relatively easy to avoid in the Drupal context. So if you look at this first example, so most of the code examples are sort of Drupal 7 style. I'll talk a little bit about Drupal 8 also, but just, you know, most people are still using Drupal 7. So here we see a typical database query. We're selecting some data. Hopefully you see what's wrong there. And what's wrong is we're taking user input. The user input is coming from the query string and directly concatenating it into the query, to the SQL query. This is like, you know, unfortunately, you see this more often than you should. If you go look through contrib modules, that's something like this is happening, but this is extremely bad and very easy to avoid, right? So the easy way to avoid this is use the database placeholders. Just use the API correctly. You're going to avoid this. It's not a problem. And those database placeholders, what they do is they escape that user input. So that it cannot get out and be executed as an SQL statement on its own. So the problem with this is that if someone can append to your SQL statement, they can select additional data into the query. Or depending on which version of Drupal and PHP and MySQL you're running, they may be able to execute multiple SQL commands. And you may have remembered in 2014, there was an SQL injection vulnerability affecting Drupal 7 core. And people that were able to exploit that could basically write new rows in the user table. They could write new cache entries. They could write new menu callbacks into the database. They could basically do anything they wanted to your site and very quickly actually leverage it into remote code execution. They could basically turn that database exploit into executing whatever PHP code they wanted and literally hundreds, maybe thousands of sites were compromised within a day of that vulnerability being announced. So you get back to the first point of you have to keep your code up to date or you will be exploited also. So the second example is something that hopefully you will never see in a Drupal contributed module, though I have once or twice, seen something like this where someone thought it would be clever to write a PHP shell into their module where you could just write whatever PHP you wanted and maybe they didn't actually secure it very well. But this is also something that you commonly see if you have a file uploaded vulnerability and the attacker is able to upload what's called like a PHP shell. So basically they upload a file and if they're able to execute that file then they can run other PHP on your server. So this is basically a second level exploit a lot of people would try. So Drupal does try to protect you from some of those file upload vulnerabilities but depending on your server configuration Drupal may not be able to save you and so something like this could happen where the attacker is able to upload a file. That file you see will take some post data and then translate the post data and eval it as PHP and then again the user can do essentially anything they want on your server as the PHP user. So again, this is injection the worst possible thing use the database API correctly, avoid eval code in your modules. Fortunately we rarely see this in Drupal. So this 2014 one was kind of a once in a decade level of severity vulnerability for Drupal. Okay, so number two OOSP.10 is when people have problems with authentication and sessions. So this means you have somehow someone is able to bypass the authentication system and be logged in when not supposed to or they will steal a session and get their browser to essentially get them logged in to the site without knowing the password. So this is an area where we don't see problems too often with Drupal. If you use Drupal cores built in user handling these things are generally not a problem but Drupal doesn't provide any enforcement of password policy out of the box. So you guys have probably run into this right you can have an administrator who and it picks a one letter password if they feel that's the thing for them to do. So especially for site administrators people who can enable modules or change the site configuration you should definitely think about adding on some kind of password policy or writing a simple version yourself where you just say your password has to be at least 10 characters long if you're a site administrator, if you have that role or this password policy module is already written you can basically just configure that. Two factor authentication, hopefully people are familiar with this more and more so Gmail offers this an option, GitHub offers this an option. There's a module, a TFA module for Drupal that basically uses the same mechanism so you can use Google Authenticator and you can basically force your administrators based on the role to have to set up two factor authentication to log into the site. And so you can basically have the best of both worlds so you don't have to bother your less privileged users remember, because you only gave the users the privileges they needed to do their job so your editors, your regular site users shouldn't be able to reconfigure the site so you don't necessarily need to force them to go through two factor authentication but the site admins who have full control of the site you probably want to be much more careful about who's logging in as those administrators in case they picked a bad password or it got stolen. So I would definitely recommend this. Password storage, a lot of bespoke web applications have problems and don't do this correctly. Drupal core does cover this, I'll mention that later also. And then session IDs. So if you're on basically like a cafe Wi-Fi and you log into a site that doesn't use HTTPS an attacker who's also sitting at the cafe can actually see that web request go by and they can see the headers in that web request and they can pick out your session ID. They can put it in their browser as a cookie and they're logged in as you. So this is a very serious problem and it's easy to avoid if you survey website over HTTPS. The really best practice is to do it all over HTTPS now and Google will actually give you a burst boost in your search result ranking if your site is all HTTPS. So there's a little extra reason to convince someone who's not convinced. If you for some reason need to serve, for example, anonymous users still over HTTPS. Again, Contrib has many modules, the secure login module will basically switch the users and force them to HTTPS once they log in. So good options there. Number three on the OWASP POP10 and one we're gonna spend some time on is cross-site scripting. So this is the absolute most frequent vulnerability in Drupal, especially Drupal before Drupal 8. Probably half of all module vulnerabilities would fall into this category. And cross-site scripting sounds a little esoteric but really what it means just is that the attacker is able to in some way inject JavaScript tags or some kind of object tags that runs code like JavaScript into your page content. So there's a couple of different variants in that but that's simply what it means. And the way to protect against it is just that again that untrusted user data has to be sanitized, has to be escaped before it's printed out. One reason why this is less severe than number one, which is injection is that a site administrator has to interact with the site in some way for this attack to execute. So with injection, the attacker could directly go directly execute their code and take over your site. With cross-site scripting, you as the administrator while you're logged in in some way need to interact with the site. But that's not necessarily very hard to do because the attacker could just send you an email with a shortened link, let's say, and they said, hey, check out this picture of kittens and you go click that link and it's actually redirect redirect you to your site to the admin page where this JavaScript is waiting to execute and take over your site. So do not be fooled into thinking that it's hard to trick someone into visiting a page with a crafted URL where, which will actually JavaScript if that's possible. So first example of cross-site scripting is what's called a reflected cross-site scripting attack. And it's reflected because it basically takes some input from the current request, in this case, the query string and prints it out into the page. So it's basically the user's input, the query string reflected back through the browser content to create the attack. And in this case again, so the attacker would basically send you, let's say a redirect link to a very long URL that basically has an entire JavaScript snippet in the query string. If you visit that, depending on your browser, it would actually execute that JavaScript and could take over your site. A lot of times people use the snippet at the bottom as a penetration test. So they will go through their forms, either manually or automatically, and put in this kind of a script tag into each form, into each possible user input, and then look to see if there's a JavaScript pop-up in the page afterwards. And that's a great way to alert yourself to a problem, but people often equate that probe with the actual attack. And the probe is harmless, but the attack can be devastating. So don't be fooled in thinking that cross-site scripting means a pop-up. A pop-up is just a way to find those vulnerabilities before the attacker finds them. So in contrast to reflected cross-site scripting, we have persistent cross-site scripting. So that's where the attacker's JavaScript is actually stored in your database. Most typically it's the node title, the node body, some field on content that you allow a comment title, something that you allow site visitors to enter. And in this case, we see an example where we're doing something that looks like it ought to be safe, right? We're loading a node, we're creating an array of rows of the node ID and the node title, and then we're sending it through a theme function. That should, that's safe, right? It's not obvious here that you see the vulnerability, right, the first glance. If you just saw that good snippet, it wouldn't necessarily scream at you the way that SQL injection one did. But this is not actually safe because theme table doesn't do any escaping of the data for you. So if you wanna be safe, you actually have to go ahead and call check plane, or the equivalent of Drupal 8 on each of those node titles. If you don't, the user input, the node title is printed without escaping, the user can store script tags in the node title, and when you visit that node, that script will execute in the browser. So there's a handbook page here on Drupal.org about handling text securely, which basically describes the different functions you can use, like check plane to escape text. But we also have a table I'll get to run through. But again, I wanna emphasize this cross-site scripting, again, it's the number one vulnerability we see in Drupal, and it is really, really dangerous. As I said, people think that a pop-up is cross-site scripting, but in fact, cross-site scripting can do anything that your user account can do while you're logged in. And this link here has a video showing an attack on a Drupal 6 site, where the cross-site scripting attack basically goes ahead, changes the admin password, changes the site name, takes the site offline, changes the admin's email, and then logs them out so they can't get back into the site. So again, that's the kind of thing you can do with a cross-site scripting attack. So don't, again, don't equate it with that pop-up, equate it with JavaScript doing things on your site. So the golden rule when handling this output, and I mentioned this before, is we filter on output. And that's very important from the perspective of users coming to your site, and they wanna type something into the comment form, the node form, right, and save it, and then they might wanna edit it later. When they go to edit it, they don't wanna see mangled, escaped HTML tags. They wanna see exactly the same thing they typed so they can fix it and edit it, save it again, right? So the golden rule is that we store the user's input exactly as they type it, but we have to know that that user input is not trusted, and then when we output it, we have to escape it. So again, you have this escaping or any kind of conversion that's formed on output, on input, we accept what the user types exactly and we store it for them. So that's, you'll see that principle throughout Drupal. People often wonder, like, why don't we escape on input? Why do we ever let this bad content go into our database? But again, it's like all user input must be untrusted. Therefore, we must filter all user input when we display it, and that means storing it as typed and then filtering it on output. Okay, so here's kind of the hierarchy of escaping text and a link that shows a version of this also, and so you might think the safest text, if you know that it's something as a URL, you can escape it specifically as a URL. You can make sure it has a valid protocol, that it's formatted correctly. So there's a check URL function. There's a check plane function I already mentioned. That will basically escape all HTML tags and present them. That's kind of what you might use also on like a code snippet where you wanna see everything as it sort of preformatted the actual HTML tags and not have them execute in the page. Check markup is what we use with, for example, a text format. So check markup needs to know what text format to apply to the text. And so in fact, check markup may or may not actually fully sanitize the output. So you have to be careful and know what text formats you've allowed your users to use. If you allow your users to use a full HTML format, that doesn't escape anything. That's the same thing as giving them permission to store and execute cross-site scripting attacks against you. So again, your editors, you don't trust them fully. You should not have full HTML. They should have a filtered format that strips out script tags and other risky tags. If you don't know what user is going to be typing in the text or you don't know, you don't have access to a particular text format to filter against, there's a filter XSS and filter admin XSS functions. And you can use those basically just to arbitrarily allow or deny a list of HTML tags. Filter XSS admin is used basically in admin areas where the only thing we wanna block is things like scripted into object tags and we'll let everything else through. And finally, in very rare cases, you can trust the text. An example where we trust text is the node ID in that previous slide. So node ID we know is coming from the database. It has to be an integer. There's simply impossible in any reasonable case for it to be an attack is not user input. It's system-generated integers. So we trust that. We can just print it out. We don't have to go through trouble of escaping it. Okay, so what does Drupal Core do for us in terms of mitigating cross-site scripting? So obviously you have to be careful when you're coding. Drupal Core does a few things also. One of the nice things it does, since some version of Drupal 6, I think, certainly Drupal 7, is it restricts the session cookie so that the session cookie cannot be accessed by JavaScript. And in earlier versions of Drupal and in older web applications, it was a very common attack that the attacker would actually use a JavaScript to copy the session cookie out and then send it to the attacker through some web request. And that meant the attacker could then just enter that session cookie in their browser and be logged in as you to the site. So that fortunately is not possible anymore, basically. The user edit form since Drupal 7 requires the current user to enter their password in order to change their password or email. So this is a protection. It protects against cross-site scripting, also protects against you walking away from your computer at a coffee shop and not locking the screen so that someone can't just walk up and type in a new password for your account or a new email address. There's a caveat here that administrators, while their own password cannot be changed, can change someone else's password or roles. So this is just a partial mitigation, not a complete mitigation. You can ask me in the question section why that's the way it is. Again, I mentioned text formats and giving people the least privilege they need. So your editors should have a text format that strips out dangerous HTML tags. Maybe for the rare cases where someone needs a full HTML access, your site administrators could do that, but it should generally be blocked and it should be hierarchical. So you give the format with the most permissions to the most trusted users. The final thing that we're sort of moving towards with Drupal but is not yet implemented in Drupal Core, though it is relatively, it is possible to do with Drupal 8 without too many hacks is content security policy. So content security policy is a new standard, relatively new, supported by pretty much all browsers. And basically it's a set of headers that you configure your site to send. And those headers can do things like say, there is no inline JavaScript on this page, so do not execute any. And if your browser respects that header, if an attacker managed to get that reflected or stored cross-site scripting into your site, the browser would just say, well, you've told me that there is no inline JavaScript. So I'm just gonna ignore this attack and not execute it at all. So this is a great possibility. There is a sec kit module all linked at the end, which you can add on to your site. But there are some, it's harder to implement this in Drupal 7 because Drupal 7 actually has inline JavaScript for things like Drupal settings. In Drupal 8, we removed all of the inline JavaScript so you can more easily implement these kind of policies in Drupal 8. And regardless, not all browsers respect these or there could be a browser bug that allows the attacker to bypass them. So we still need to keep those principles of always escaping the user input, use check plane, use filter XSS, whenever you have user input. Okay. Our Waspop 10 number four is sort of a one that doesn't happen too often in Drupal, insecure direct object references. And this is basically just, there's a way to type in a URL that loads some data the user shouldn't have access to. You know, don't do that. Basically, if you use access checks, access callbacks in the Drupal 7 menu system, the Drupal 8 routing system in general, unless you make a mistake in writing that, you'll be protected from that. Waspop 10 number five is security misconfiguration. And this is sort of a catch all topic. I don't really like it, but we'll cover a couple of points here. So one example of a common misconfiguration in Drupal sites is having error reporting turned on in production. Now that might not seem like a severe thing, but it actually allows attackers often to figure out the actual path on disk to your Drupal site on the server, and that can help them carry out other exploits. It may show them SQL errors. And if they see an SQL error, they can figure out, for example, which database server you're running, maybe in which version of the database server you're running. And it may give them clues if they're trying to execute SQL injection when they're getting warm or cold by seeing whether they are able to trigger an error. So turn off error reporting for non-admin users. If you're using Drupal 7, strongly recommend you disable or even delete from the code base, the PHP filter module. This, in earlier versions of Drupal was used very often for little snippets of code to configure the site. In current versions of Drupal, you should keep that code in your code base under version control and don't use this module at all. That's not really any good things about it. Another common security misconfiguration and something that's actually hard to avoid sometimes on cheap shared hosting is that the PHP process has access to write its own files. So Drupal can overwrite the Drupal files. Some projects think this is an advantage because you can have auto-updating sites. But if you can have an auto-updating site, that also means the attacker potentially can write their code over top of your site's code and take over that site or server. So we strongly recommend for Drupal that you do not configure it that way. In a best practice example here, you can see the Unix users and permissions is that we have a separate Unix user who's responsible for checking out and deploying the site code. And that Unix user is different than the web server user. So a typical Linux web server user is wwwdata. So wwwdata can read all these files but cannot write the files. Except, of course, for the upload directory where you have to basically invert the logic and allow the web server that one place to upload the user's files, but your deployer may need to read things there also. Handbook page on Drupal.org, security, secure configuration, talks about a bunch of these issues. So please do look at Drupal.org. There's a lot of great security documentation there in the handbook and will help you avoid these common mistakes. Last couple of things here. Again, we talked about principle of least privilege. Who do you want to have access to enable disabled modules, reconfigure the site, make sure that those permissions are not given out to roles where people have the roles and you don't fully trust them? As again, same for text formats. Full HTML means I give you permission to execute cross-site scripting against me. If you trust the person that much, you want them to execute arbitrary JavaScript against you. If yes, give them this full HTML. If no, then you should be giving them a more restrictive text format. Best practice, don't use user one account in your daily work. In fact, even I would recommend blocking it. Have every site administrator have their own login, have their own passwords that are distinct. And you can also change the user one login to something other than admin, something that people can't guess as readily if you don't block it. One other common thing we see is that people put their private files under their document route. So if you're setting up the server, you want to make sure your private files are outside the document route. You can see here where index.php is. That's where Drupal serves web requests, everything under that. And we want to put the private files directory at the same level or above. So there is no possibility you can make a direct web request and access one of those private files. So people make mistakes in their server configuration. They think they blocked access to the private files directory. But if it's under the doc route, if they made a mistake in that server configuration, the hacker can come in and directly read those files out through the web server. So again, another thing that you might want to have outside of your document route is any kind of configuration or any kind of files, let's say containing API keys. You might have a configuration directory that's shown here on the diagram. And again, keep that outside the document route. So even if you make a terrible mistake in your web server configuration, there's basically no possibility that the attacker can directly read those files out of the file system and display them. A little more on secure configuration. So PHP file execution, Drupal, basically every single request hits index.php. And then on normal request, there's no other PHP file that runs. So you can actually basically block access to every other PHP file in the Drupal file hierarchy. And that gives you a little more defense in depth against someone uploading a PHP file and trying to execute it. So Drupal 8 actually comes with this baked into the HE access file. And you can add a rule to your web server like shown here to help protect your Drupal 7 or before sites. Yeah, there's a few cases where people have something else like they have an analytic script in a subdirectory that they do need to make PHP calls to. But you can definitely, you know, you can whitelist those specific scripts and just don't allow arbitrary PHP files to be accessed. Okay, so the last thing I'm gonna talk about before turning over to Moosh is sensitive data exposure, OWASP top 10, number six. So if you are handling sensitive data in your database, such as credit card numbers, you really probably should be encrypting them. Same with people's medical records or their personal, other personal information. You need to encrypt those, make sure if there's a database backup somewhere that someone gets access to, they can't actually read out that raw data. But even better than encryption is don't ever have that data. Don't ever have someone's credit card number if you can avoid it. There are a lot of services now where you can integrate with them and all you will ever get is a payment token. Your web server will never actually get the credit card number and that's a lot more secure for you. It's a lot less liability for you. It's a lot easier to be compliant with the PCI requirements. Same thing for things like medical records. Yeah, you should, and other personal information, you know, you should make really, really sure that you need that information before you ever store it into your Drupal database. And then if you do have to store it, you have to figure out how you're encrypting maybe your data backups. You need to make sure that if you're giving developers copies of the database that you've scrubbed that information out before the developers ever see it and before they put it on the laptop because developer has a copy of the database dump on their laptop. The laptop's stolen, now someone has all the credit card numbers or all the health records and that's a big problem. Another way sensitive data is exposed, of course, is through web traffic. We talked about, you know, sitting in the cafe, someone read your web requests. Maybe that web request, the response contains, again, someone's medical record. Now the other guy in the cafe just got a medical record of one of your clients. If the client finds out, they're probably gonna sue you. So don't do that. Again, set your site up, use HTTPS. We talked about passwords being properly hashed. Drupal takes care of this for you. Since Drupal 7, if you're still using a Drupal 6 or even Drupal 5 site, there's a PHP, PHPAS module will enable a stronger password storage. So I recommend turning those on for your site. Now I will give it to Moe here. Okay, I want to apologize for being late at the beginning here. I hope there wasn't too much drama. I missed it if there was. Okay, we're gonna keep going. Oaf number seven, missing function level access control. Here we have an example of hook menu, which applies to Drupal 7 and before. And the last element there is called access callback and the value is true. All right, that is occasionally the right thing to do. But we're saying it's not in this example. Here's probably what you meant to say. Access arguments and the value is administer my module. All right, so now this page admin my module settings is properly protected by permissions check, all right? So this Oafs thing is like actually use the access control that your framework provides. Definitely a good idea. Similarly, we have access control on listings of entities in Drupal. And you'll see halfway down here the add tag node access. That is what triggers the node access control to add its SQL conditions and to restrict access for people who don't have the right grants. So that's required at any time you're doing a listing in Drupal. If you're all the way back at 6.x, look at the DB reWrite SQL function, okay? Number eight is cross site request forgery. This is kind of a cool attack. What we have here in this example is, what happened? It's back. I think it was a power thing. Okay, so, yes, this one. Okay, so we're deleting a pair of pants in this example. We are taking the second argument. You can see page arguments in the first array and the values too. So the ID of the pants is getting passed to the my module delete pants function and that ID is getting, that pant is getting deleted by ID in the second function there. So if someone can trick you to go into this page then you have just deleted a pair of pants. So the way this attack really works is that oftentimes an image that is posted somewhere on the web and you are encouraged to visit this page, the image instead of actually pointing to the cat image on this somewhere will point to the pants deletion page, all right? Which is pants 1337 delete in this example. So the admin visits what he wants to visit which is the cat image, doesn't get the cat image, instead makes a request back to his own site. His browser will go request pants 1337 delete. He's logged into his own site. He has the proper permissions to visit that page and now the attacker has caused a right operation in the database, okay? So that's cross site request forgery. We say forgery I think because you had no intention of visiting that pants deletion page. Someone tricked you to doing so and took advantage of the fact that you're logged in and privileged there. Sure. Yes, the question was can you make a post request request forgery and you definitely can, the attacker just writes a little JavaScript, snippet and the JavaScript snippet can make a post or the attacker sets up a form on their site and the action of the form points to your site. You submit the form and the post request goes to your site and takes, so post is not a protection against this. That's why Drupal forms have a form token that protects against it. Exactly, so the way to mitigate this kind of attack or prevent it on your site is to always use the form API. When you're doing forms on your Drupal site don't write just plain HTML form elements. Definitely go through the trouble of using the form API because that is what's gonna check for a token and make sure that you haven't been tricked into visiting this URL. There are a few occasions when you want just a link and not a form to make it easier on the person who needs to do an approval of a pending comment moderation or something like that. In that case your get request and you should have a token on it that will check to make sure the token was actually generated by Drupal and not by an attacker. And the Drupal 8 routing system actually makes this super easy. So if you're using Drupal 8 you can do routes that check these tokens just with the routing YML. There's a link there for more information about CSRF. Okay, so we now are building sites that depend on more than just Drupal. Drupal itself has a nice update status system. You can see a screenshot here of it. It will tell you when you have a pending security update. And just wanna remind everyone that if you have other composer packages that your site depends on those need to be checked as well, okay? The composer outdated command is one thing you might wanna look into to help you with that. And there's also a project that will flag your projects if they are behind on security updates. That one's in the Drupal-composer organization on GitHub. Okay, so just a little bit more about the update status system in Drupal. It will email you if you have stuff you need to do if your modules go out of date. And it can tell you when they go out of date or only when they go out of security compliance. All right, so definitely turn that on. If you aren't gonna visit your site and look at that report all the time. And number 10 on the OWASP top 10 are unvalidated redirects and forward. So Drupal has this Drupal go to function. We use it all the time after you submit a form. And in other cases, and we just wanna make sure that the value that gets passed to that has been checked. And you're going to an internal URL and not some phishing site. And so here you see an example for how to do it correctly. The URL is external function. And there's some equivalent in Drupal 8 that I don't recall right now. So just kind of summarizing again, the main things to keep in mind. We don't wanna trust user-provided data, whether it's coming from the URL or it's coming from the content that people are submitting in comments or in posts. And the attackers are using all kinds of browser features against us in order to trick us to visit pages and delete pants and all that sort of thing. And keep your sites up to date with code and that kind of thing. So some tips for being prepared before there's an attack. We wanna put our code in version control. If it's not in version control, you could visit your site one day and attacker has not only owned your data but has deleted the code. And now you don't have code or data and maybe not a job either. So you definitely don't wanna let that happen. You need to make full backups. You need to have separate logins for each admin. And you guys can see the rest of the bullet points here. If you do happen to get attacked, it does happen. Okay, here's a quick list of what you should do. You'll find longer lists on the internet. But maybe become familiar with this and that will motivate you to not become a person in this situation because you're gonna go through this list in a very unhappy state. And some of these bullet points are like, save and scan all your logs for traces of the attack. And that sums up weeks of work in one bullet point. So this is just a word of caution here. I wanna put another pitch for a few modules on Drupal.org that are really helpful for security. Peter mentioned a couple of these. Security review is like a checklist module. Paranoia is a great module that will disable things that you probably shouldn't have enabled on your site. And SecKit, right here for Connet security policy. A lot of the examples here are still Drupal 7 focused. That's deliberate. We have very few Drupal 8 sites in the wild compared to Drupal 7. So at least for a security talk, we wanna still be talking about the sites that people are running and using. We made a lot of improvements in the five years that we were developing Drupal 8. And you can just see a list of them here. Twig autoscape is huge for getting rid of those XSS vulnerabilities that Peter emphasized earlier. And the HD axis is better for executing PHP and subfolders and so forth and so on. So we touched on these. Drupal 8 is a more secure platform. I hope you guys are starting to use it. A special farewell to the PHP module, which is gone in Drupal 8. You'll be missed not by us, but by the attackers. And if you do have security questions, definitely become familiar with the Drupal security team. There's their URL right there. You can read about what they do. It's an all volunteer force that is looking after thousands and thousands of contrib modules and putting out vulnerable essays, security advisories on them. So if you come across a security team member, please give them a hug and say thank you. And- Are you asking for a husband? No, no, I am not. Maybe Peter is, but they do a lot of work for free. So provide a great service to Drupal. A few others at the conference. All the core committers obviously are on the security team also so they can coordinate Drupal core. But if you go to security.drupal.org there, everyone who has a Drupal.org account can be logged in and can submit issues there. So if you come across a security issue, if you go to a project page on Drupal.org, there's a direct link, takes you to the security site to submit any security problems you find so that they can remain private until we decide if it needs to be resolved privately or if it can be public. You can also on that site, even if you can't see anything else, you can see the official list of Drupal security team members. So if someone sends you an email saying, hey, I'm on the security team and you need to give me access to your site, at very least make sure there are official lists but trust us we won't ever do that. Yeah, that's not something we do. As I said at the beginning, basically we respond to your report. So we count on the community to look at the code, find the vulnerabilities, report them to security.drupal.org and then we coordinate with the maintainers of the modules or with the core maintainers to fix the problems. So we can open it up for questions and comments and discussion. I don't know if you guys have anything here. Yeah. Okay, thanks. Yeah, right. I think there's a microphone, probably if for the recording we should try to use the microphone. You think that exposing Drupal version? Yeah, so the question was, is exposing the version of Drupal that you're running a security problem? The security team is taking the position that that is not a problem. It's not in our top 50 problems. Is that accurate? Yeah. So there's a lot of different ways you can discover what version people are running. So yeah, we generally slightly scoff at people that recommend, let's say, deleting the change log file so no one can see what your current version is. Well, I would say you would be better off just being up to date rather than trying to hide the information about the fact that you're out of date. Drupal seven and eight, I mean, if you look at the headers we'll at least tell you that you're running Drupal seven or Drupal eight right in the headers by default. And yeah, there's plenty of ways to see. So I don't think hiding the fact that you're running Drupal is very important. Again, keeping up to date is the important thing. Regarding internal systems, intranets and so on. I've seen that self-signed certificates still widely used. What priority would you give fixing them and what do you think about it actually? So an interesting question about HPS and if I'm using internal site with self-signed certificates which means basically with a self-signed certificate the encryption still happens but your browser is not able to determine whether this is a legitimate site. So if you kind of tell your browser ignore all those warnings, I want to go there anyway. Someone might redirect you. Let's say there was an open redirect attack. Maybe we should talk about that a little more. So an open redirect attack would be you think you're going to a site and the attacker has constructed a query string that causes a redirect and you end up landing on the attacker site and the domain is almost the same, maybe one letter off. The login form looks the same. Now you, and you're ignoring your browser warning about an invalid certificate. So they tricked you that way too and you type in your username and password, it's submit and they say, great. Now I have your username and password, I'll send you back to your site to log in. So I think it's part of that defense and depth strategy that if you are always accepting these invalid certificates it means you eliminated one of your defenses in the stack. I wouldn't recommend it, but it's a trade-off. Someone else that question, yeah? If you can, yeah. Look, yeah. So what I find difficult sometimes is how do you know if Drupal's API and the functions are already handling the security side of it? Because when I'm theming, like in views and no templates and stuff, I never know whether it's already helped sanitizing it or whether I need to re-sanitize it. Sometimes I just do the functions just in case. Okay, so that's a great question. So the situation is kind of different between Drupal 7 and Drupal 8. So, and before, so in Drupal 7 in theory, the variables should be sanitized before in the pre-process functions in the theme, but I agree they're not always sanitized. So, especially if you're using some variables from a attributed module, it's hard to know. Yeah, you have to either run it again and look for double escaping or talk to the person who developed that particular theme call and ask them. In principle, it should be in Drupal 8 we have a stronger guarantee. So the twig templates we have auto-escaping turned on, which means that if it wasn't basically sanitized beforehand, it will automatically be sanitized when it's printed. So that's one of the, I think great things about Drupal 8 for front-end developers is that that auto-escaping relieves that entire stress about whether this has been sanitized or not and you can just go ahead and write your templates. Just a comment on that. I was talking to an agency earlier actually this week and they were saying that one of the things that they do is they put in sample data when they're developing a site that includes cross-site scripting attacks and then header it all over the place. So only useful at a certain stage in development but then you would see it if it came up. So I thought it was a pretty cool trick. Okay, any other questions? You said no configurations should be in doc root. What about settings PHP with the database configuration in it? Yeah, since it's a PHP file, it's pretty poor configuration for you to expose the whole source code of your site from regular web requests. It happened to Facebook, so it can happen to anyone for a few minutes. But it's, I wouldn't consider that like a real serious problem to move that out of the doc root. I don't know if you have the same opinion. Well, I'd say one thing you can do and we actually recommend this in some of the help comments in settings PHP is you can actually, you can include another file in settings.php and you can store that file outside of the doc root. So if you do have, let's say in production very sensitive credentials and you wanna make sure they're never accidentally committed or you wanna make sure they're never exposed to your web requests, I would put those in an include file outside your doc root and then load them that way. And that gives you a little bit extra defense in depth. And I guess the other variant on that is that you can read from environment variables, your database credentials and then they're never on the file system at all. I believe that Pantheon takes that approach, which is great. Thanks. So if you are not already planning to attend, please do come on Friday. Contribution sprints are really a lot of fun. If you haven't done it before, there will be mentors there. You can find like-minded people to work on contributed modules, talk about themes. Also, we appreciate your feedback on these sessions. The session slides are already posted as a PDF. So if you wanna review, you wanna go to those links, review the content, please look at the PDF. This recording will be live, I think, within a day. But also go to the session note and please give us feedback. Rate us, give us comments if there's anything we can improve for next time. I said we're doing this kind of as a service to the community, help improve everyone's security awareness. So we would appreciate your feedback if you have any improvements we could make. Thanks. Thank you. Sorry, I wasn't here at the beginning. That's all right. It was kinda funny. It was good thing that I was here the first half. Yes. Really good thing. Yeah. Questions? What can I do?