📜 ⬆️ ⬇️

Vulnerabilities in your application

Are the threats of XSS still relevant? It has been about 20 years since Cross Site Scripting (XSS) appeared as a type of attack. Since then, we have gained a wealth of experience and knowledge, the protection of our sites has become much more difficult, and numerous frameworks have been designed to protect us from mistakes. But the latest data shows a completely different picture: in the first quarters of 2017, the number of reports of XSS attacks and the number of vulnerabilities found increased several times.


In this habropost, we will tell you how scary to live, why your applications are in danger, why frameworks don't save, how to find vulnerabilities and what tools to use for this.


The prototype of the article is a report at the conference HolyJS 2017 Moscow . Alexey is a frontend team leader / architect at EPAM Systems and one of the leaders of the FrontSpot community in Minsk. The main areas of professional interest are: architecture and application infrastructure, development management.


In this text, a huge number of pictures from the slides. Caution traffic!


I know that many of you have already caught some XSS attacks. I want to tell you a couple of interesting stories, cases that we should pay attention to, and at the end ask the question - how confident are you that your applications are invulnerable?


I will begin with a description of events that occurred more than 12 years ago and made me take a slightly different look at the security of web applications, frontend applications, and, in principle, on security in general. October 4, 2005 Sami Kamkar left a comment on his MySpace page. A comment with a virus that infected over 1 million users in just 20 hours. 20 hours - 1 million users. Fortunately for these very users, the virus did nothing wrong. He added Sami as a friend, and in the Heroes section he wrote: “But most of all, Samy is my hero”. Sami used one of the known vulnerabilities of Internet Explorer at the time and left a comment containing a piece of html. There was a div with a custom attribute in which the script was hidden.




And, with the help of inline-style, he launched this very script. Thus, when someone came to the page to Sami, the script was executed, added Sami as a friend, infected the page, and so on a chain reaction. When you visited an infected page, you yourself were infected and could infect others. 20 hours - 1 million users. This virus was officially recognized as the fastest spreading worm in history. Sami himself said that it was just a joke. "I wanted to joke." So, for his joke Sami got 3 years.




12 years have passed, what has changed during this time? Who among us uses myspace? MySpace is dead. There are new browsers, new frameworks, new libraries, technologies, and the world itself, in principle, has changed.


I work in EPAM in the Minsk office, in the center of competence. And from time to time clients, customers, account managers, project managers come to us so that we can audit their projects. We have a large checklist, for which we check, and one of the items is called security. So, this is the most security, during my work, not a single project passed the first time. When we communicate with customers, we tell them that we have found a vulnerability. And the client replies: "Well, it's just one." And we have to tell the same thing every time. Just one hole, one open window, and someone’s red face will surely appear there.




In your application there should not be security-bugs, zero.


So security is a very broad topic. So much so that if we gather every day and talk about it, we will not have enough a month.


I would like to dwell on the example that I gave at the very beginning, namely the vulnerability of the so-called Cross-Site Scripting (XSS). As a bug, it appeared as much as 20 years ago. During this time, he strongly mutated, spawned a huge number of other types of vulnerabilities. And we will talk about it today. To fuel interest in this particular type of vulnerability, I would like to give you some statistics. There is such a company Akamai. If someone does not know, this is one of the largest distributors of content in the world, which, according to various sources, controls 15-30% of Internet traffic in different regions. This is a lot. Every quarter they issue a report, and one of the reports is called Security Report. What is interesting about this report? That percentage of XSS attacks of the total number of attacks has already reached more than 20%.






This is only for the first quarter of 2017. On average, each site was attacked more than 30 times, namely using XSS. Quite anxious, right?


We are talking about XSS, but what is it? Looking for more examples. Let's imagine that your friend is sending some kind of link. To mail, in Skype, in any instant messenger or chat. Everything in this link is nothing but this parameter.




In this case, the script is very obvious. It so happened that we took and clicked on this link. What happens next? You can follow the link and see the site there, you can see there “Page not found” or “By the criteria you specified, nothing was found”. But the trick is that the script is already on your page. The script has already run and stole your data. The crime is committed.




This type of attack is called “active XSS”, that is, the attacker works directly with users. He sends spam messages, trying to somehow convey to you this very reference. And, we will speak frankly, if you blunted, clicked on this link and went - everything. Consider everything lost. And after all, everyone knows that you should not get into a car to strangers, you should not take sweets from strangers, you should not click links from strangers. Everyone knows, but still click. Why?


It’s Google’s fault maybe. Would you click on such a link?




Why not? A short reference, very convenient, click. And there my script is hidden, my active XSS. Or another example, a QR code.




And what's in there? Here I sfotkal. Think I read this link? I took, moved. Everything, the script was executed, my data was stolen.


The next view is passive XSS. Let's imagine that I am an attacker, I went to a site and left a comment. The comment contains a regular script that redirects to some other page, grabbing your cookies. Why is this type of attack called passive? I already need some deeper knowledge, I need to understand how the page is rendered, how the script is executed. This is a deeper, more serious level. That is, I work directly with the site and look for vulnerabilities there. As soon as I find them, I implement this very script, and that's all, nothing more is required of you. You, as a regular user, again go to this page - everything, the data has already been stolen. And you won't even notice what happened.




To give an example, I will tell the story. More recently, on the St. Petersburg EGE site, on the main page, there was the following inscription: “After passing the EGE, I do not have enough points to enter the computer security department. We'll have to provide jobs for those who entered. " In fact, this hacking was not related to XSS. This was quickly fixed and after half an hour the site worked as if nothing had happened. But another student, a colleague, broke the site again in half an hour. “I sympathize with the guy from St. Petersburg, who did not have enough points to enter the faculty of computer security. I hope I have enough. ” This guy used exactly the vulnerability that I talked about. He left a comment with a redirect. As soon as you entered the St. Petersburg USE site, you immediately redirected to this page and read this inscription. Prank? Yes. Simply? Very simple. Is it possible to break the site? Easy. As you can see, these vulnerabilities are based on the vulnerability of the DOM tree. How we work with it, what we introduce there can lead to very interesting consequences.


Let's look at the usual input.




We can enter numbers, strings, and nothing will happen, everything will be fine. But if our text contains the following script:




We reloaded the page, redrawn this input with a parameter. Everything, our input was closed, the script was executed. Okay, who inserts the script now? This is too obvious, too simple. Suppose I can insert an iframe.


All the same will happen. Input was closed, iframe was loaded, executed some script that I wrote there. Vulnerability.




Another example with a picture. I insert a picture, in it is an invalid url and onerror hook.




As soon as the picture tries to load, of course, there is no such url, the onerror hook will work, my script will be executed, voila. You will say, obviously, that there is a script. And if I hide the same picture and in that way. It is clear that there is a script? Or like this.




Or here are our friends with js-pack.




Alert? Who knows what is happening there in this code. That's serious, what is he doing? This is the usual alert, which is represented in the form of opening and closing brackets. What is it? How to understand that it works?


This is an example of one input. Let's take life examples. eBay (one of the companies that has nothing to do with IT) decided to sell a book a couple of months ago. Here is a book. The most interesting thing is that the name of the book is:




The book is inexpensive, $ 25. As soon as you visit this page on eBay, you see an alert. Believe this page is still relevant, but the bug was fixed. The community liked this joke with the book so much that they started selling it in different countries. Here you have the most popular book selling website in Sweden. Works. Here is Germany. Works.






And many, many different other examples. All is not fixed until now. And we are now talking about the vulnerability of only one input. There is a sample list of all attribute vulnerabilities, tags. A lot of them. And for each of these links there is an even larger list of how your data can be varied, how this or that protection can be circumvented. Fearfully.


But who are these intruders? What do they want from our site? If we know the enemy by sight, we can do something about it. Recall childhood, because children have always been divided into 2 types. Children who built castles with pleasure, and children who with the same pleasure broke these castles. Nothing has changed in the adult world. We write sites, someone breaks them, just for fun. Believe me, they get the same pleasure from broken and broken code as we are from working. There are people who do this for fun. And there are special sites on which we can register and break sites with impunity. Sami would know about it. For the fact that we find a bug, we can even get some kind of reward. On big serious sites - serious money. Only the third part is precisely the attackers who want to steal something from us. And what can we steal from our sites? If we know that they want to steal it, we can hide it away, right? Cookie and what is stolen in the first place, what lies in our repositories. This may be session storage, local storage. With index UDP, believe me, the data is gladly drowned, just to get to them. Okay, now few people use cookies.


What else can you steal? Passwords There are many ways to steal a password. With the usual script, we can just hang some keyup, keydown on the document and log everything that we press. Then we send it all to some site, and there we are already mechanically selecting. Or, say, phishing, if we are smarter guys, we put a fake form on top of the existing form and just take away our submit. The main goal, which appeared quite recently and, in principle, is the cause of the surge in these XSS attacks, is mining. The power of our computers, the power of our phones are growing. Why don't we steal these powers?


I will give an example from Belarus. Luch plant, one of the largest factories in the post-Soviet space for the production of watches. On their main page, they blundered in the most insolent manner. How impudent that they even asked: "Do you mind if we remember a little bit here?"




There was a scandal, a couple of people were fired, the site was returned to its former appearance. But how much of such mining happens without our knowledge? They may not ask us about it. A fairly large company AdGuard, which is engaged in research in the field of advertising, ad blockers, studied for three weeks the top sites from the list of Alexa. Studied, studied and found that 220 of the first 100 thousand minyat. 220 out of 100,000 is 0.22%, a drop, you see. But it turned out that in 3 weeks there were 500,000,000 users on these 220 sites. Imagine what could have been denied during this time. The most popular sites for adults, streaming and pirated content were included in these 220 sites.


How to live on? It seems that the future is no more, everything is scary, everything can be stolen. Even what we do not expect. Someone must save and protect us. And, in principle, frameworks should be the logical answer. After all, other developers have already thought about it. And indeed, by reading the documentation of popular libraries and frameworks, we can see how they evolved in this direction, what they did for this. But if they really saved us, then my next topic would not sound like ... Framework vulnerabilities! How to break the framework? We can enter the data, as it was done in the input, but believe me, they are really good at it. But we in our work very often need to embed the dynamic content that came from the server that the user entered. This dynamic content is indeed a threat. Different frameworks do this in different ways. There may be some directives, there may be some property ... Let's start with AngularJS.


So, here the ng-bind html directive actually lies in the sanitize.js library. We put in there a dumb piece of html, and this library cuts out all the dumb things on its sheet: attributes, tags — everything that she didn’t like.




Leaves pure html that we can safely insert. It seems that everything should work well. But what if we forget some attribute on our list? So it happened. Which of you used the usemap attribute? I did not know about him until I read the reports, I never used them. This is an attribute for dynamically loading content by clicking on a picture. The developers have also forgotten about it in Angular. And prior to version 1.5, this vulnerability existed. That is, this code will be gladly inserted and executed. Vulnerability.




And not only with this attribute. Here is a short list of vulnerabilities to version 1.5:




Many of them are, of course, fixed in later versions, but still this is a big list. I will not dwell on them in more detail, but they are. It would seem, AngularJS, already legacy-framework.


We need to look at something newer, more stylish, youth. Developers, after all, had to take into account past experience. Vue.js. I started reading the documentation how they work in the v-html directive. They write that inserting dynamic content is somehow dumb, so you are to blame. And what do they do? Never mind.


I downloaded the latest version of Vue.js:




And I tried to insert dynamic content in the specified area. Happened.




Vue.js does not help us in this. This should be done by the developer himself. And now, if you write on Vue.js and hear about it for the first time, you have a vulnerable application. Congratulations.


Well, what about React and Angular? Over the past 2 years, not a single security issue has been discovered. It would seem that here it is. We use React and Angular, and we live to ourselves happily. But here's another statistic. 77% of sites with these frameworks have at least one vulnerability. Where does all this rubbish come from? But from where. Vulnerabilities in node_modules. We downloaded them ourselves, chose the version ourselves, added our own project. Welcome.


For example, let's analyze the vulnerability in Redux. Redux and React gave us a great feature, server rendering. It was a killer feature of its time, it works in the following way: we need a state, which we want to use as initial, to insert it into the __PRELOADED_STATE__ variable in the global window in the global window. But before that, it is necessary to grind it.


And special attention to this line.




What if I managed to register somewhere with this name?




The data was saved somewhere on the server, it seems that nothing terrible happened, but here is the server pre-rendering ...




and everything, the script is closed again, and my script is executed. Vulnerability. Yes, this is not a vulnerability in Redux itself, but in the Redux approach, but we use this Redux from node modules. We use what was written in their documentation. The second problem of node modules — on average, node_modules is 1177 days behind the last release — more than three years! Think about it: everything that appeared new in three years, all these vulnerabilities - they all, most likely, are in your application. Let's think what happened in three years. jQuery has reduced its popularity by only 35%. This is despite the fact that Angular appeared, AngularJS, React, Vue. And if you look at the versions, 79% of the sites use the first version of jQuery. And in the first version - here you are, open vulnerabilities.




Therefore, in all sites that use the old version, most likely, there are vulnerabilities. And this is not only a jQuery problem, it is a problem of all old client libraries: Handlebars, Bootstep, D3, JsTree, almost any library of the old version has at least one vulnerability. If you haven't updated them, if you have a fairly legacy site, I advise you to look at it.


And let's pay attention to these packages: babelcli, jquery.js, mangose, gruntcli, D3.js. I think each of you at least once worked with these packages. This is actually what these packages are called: babel-cli, jquery, mangoose, grunt-cli, D3. And this is a huge problem, which appeared recently in npm, - infected packages. We, as attackers, work directly with npm. We are looking for some popular packages, we make some typo, fill it again at npm, and the person, relying on his memory, shakes the mangoose with one “o”, takes him to the project, and, believe me, you don’t even immediately notice. They work exactly the same, but in postinstall cookies, your environment variables will be stolen. NPM is very concerned about this issue. He searches for these packages, downgrades the version, calls him “0.0.1-security”, so you cannot remove the entire package now, and only the readme and package.json remains. If you upgrade your packages, you will see this problem, if not - your environment variables will still be stolen.


If you are thinking, well, who could dull it, then here is an example. I recently went to the npm repository, entered the wrong mangoose, and found out that 21 more people had blunted that day. 464 people per month, so it works.


It turns out that all our friends are our enemies. We store more data on the client, because in order to maintain offline mode we need more and more data. Often it can be some kind of security data, and I want to steal it, some kind of analytics. And the data is against us. NPM with its vulnerabilities in some packages is a threat to our applications. Server rendering, an example with Redux, is incorrectly used - here you have a vulnerability.


Progress also does not stand still, power is growing, and potentially it is interesting for our attackers.


Single page applications - an excellent approach to writing applications, and now we will think about how people use it. We came in the morning, downloaded this application, and do not reboot it until the evening - not for nothing. And if somewhere there was a vulnerability, it works all day, you gave the whole day to the script in the SPA. When you are developing a SPA, you should be even more attentive.


Cash plays against us too. We made a mistake, we reposted it, we fixed it, but we set up the wrong service worker, set up the cache incorrectly. And in the cache of our users, this script still works, this vulnerability still remains for a while - also a problem.


Who of you used Service Worker? Just a year and a half ago, I talked about this as something new. Now, if in your application there is no Service Worker, everything, it is not reactive, not progressive. Now it should be in every application.


I'll tell you an interesting story. I started to google and googled my friend, Kitty Programmer. He programs well, I really liked this gif, and I inserted it into my application by reference. It was pretty, and I forgot about it, went on working. After some time, I notice that in the application that I developed, in which there is no Service Worker, some Worker starts spinning on this domain, and it turns constantly, does not end. Where did he come from? If we analyze the header and response of this image, we can see two interesting lines: “Original-Trial” and “Link”.




Original-Trial is, in principle, understandable, the key from Google for using some kind of experimental technology. Moreover, you can use them without the knowledge of your users. This proposal is called Foreign Fetch for Service Worker, to optimize the loading of fonts and images. And this Service Worker can be installed from the link. It is installed and can do without your knowledge cross origin request. What? I have not invited anyone into my app!


How to use it: Service Worker is so arranged that if no one turns to him for 60 seconds, it fades. Not completely, it is hanging somewhere in the subprocess to listen to push notifications, but in principle it does not work, and if we send a message to our Service Worker every 50 seconds, we will work all the time. Or another approach: we can go to the network and pull out the exact same copy of the Service Worker from there, it will also work, and every minute we will upload something new. What can we use it for? All right, mining. Without our knowledge, in the background hangs a Service Worker, which is constantly working. This vulnerability has existed for as many as 3 versions of Chrome. What am I leading to? Technologies develop so quickly and so quickly get into production without proper checks that it’s scary to use them.


How to deal with it? How to fight. for example, with mining? We can put some extensions that will keep track of all these incomprehensible manipulations and block them. But if they really saved us and helped, the next chapter would not sound like "Extensions are also our enemies." Many of us use ad blockers. AdBlocker, uBlock, AdGuard, whatever. And let's think about how they actually work. You load your content, and these blockers crawl all over your HTML and hide the blocks that contain ads, that is, you can't hide from them in the DOM, they can climb everywhere. Then they block the download from some resources that they have in the blacklist, that is, they have access in response to the content security policy-object. Then they get access to the response itself. They can directly from reponse snatch a piece containing advertising. That is, in principle, everything is available to extensions. And what if these extensions fall into bad hands?


Here is the real story. Sergey, the author of one of the very popular XML Viewer extensions for Chrome (100,000 users):




He allowed to share this story and tell it to you. Once, people came to him and offered good money: the links had to be modified so that special meta information was added to them and it was possible to find out where the user came from. Quite good money, in principle, why not, a harmless modification ... And as soon as he gave the code to these people, complaints immediately began that there were some snippets in our requests that track all of our extension requests in general. This example illustrates well how much you trust these extensions. After all, they can steal anything, they can modify anything. Of course, Sergey very quickly fixed this problem, rolled back, but this is a very revealing story. Do you trust your extensions that you have in your application, in your browser?


How do we deal with these vulnerabilities? If extensions scared you a bit, let's help users. We can determine from our application which extensions are in the browser. And if we know for sure that these extensions are harmful for your application, we can identify them. Each extension has a unique id, which we can see directly on the site. Further, we can study the manifesto of this extension and see that there are some open resources that can be downloaded directly from your application.




For example, in the AdBlock example, this is some kind of custom CSS. We formed a url and in the usual way we try to load, and if this resource is loaded, then extension is worth it. Show pop-up. If you have something terrible there, remove it quickly, otherwise they will steal everything from you. Help your users, it costs you nothing, just three lines of code.


A little captain's advice: if there is no need, never insert scripts from users, do not insert even comments, do not insert any tags or attributes, styles, do not insert anything. Work with clean code. If you still have such a need, protect yourself in your forms, it is enough just to extract these five characters, and no script will be executed on your client, at least. Five characters is pretty simple.




Still need to sanitize. If you think that, in principle, I myself can write some code, here is an approximate list of dangerous tags, attributes that you need to enter.




They are much more, we have already forgotten about many, we do not know, but there are more of them. Use ready-made solutions, well tested. I would advise: js-xss, the most popular HTML sanitize, there is also DOMPurify, which is also quite a popular library. They are very lightweight, they have good tests, they are constantly updated, the community supports. And there is a serialize-javascript in order to walk through your object and find these inclusions here, so with the help of this library you can very easily solve the problem with Redux.


Use Content-Security-Policy - a special header in the response, it can be used as a meta tag describing the rules by which resources will be loaded on your page. We say we want to ship from this domain. We are loading the scripts, they are being loaded, and if the attacker tries to pull up someone else's domain from his domain, it will not work, an error message will appear, we have blocked it. I will not go into the details of the documentation, you can read everything yourself, I can only say that we can describe the rules for pictures, for styles, for working with iframe, with scripts - many different settings. I would like to dwell on the new features that appeared in the second version. This nonce is a string that is generated on the server side and added to all your scripts. That is, the attacker, inserting you a script, this nonce will not know, because it is new every time, so the script will not be executed either.
Or the second method - you can simply count the hash sum of all your inline scripts. Knowing this hash sum, if any script suddenly changes, at least one space is added or the order of scripts changes, everything, the scripts will not be executed, you will be safe.




We receive approximately such error messages, development mode. In production it is not very used, because I would like to collect statistics. Content-Security-Policy also allows you to collect reports. The special attribute report-uri allows you to tell us the endpoint where we will send our reports. If you are immediately afraid to implement Content-Security-Policy, then it is reasonable, because you can block some important scripts, in production it is scary. You can connect them in Report-Only mode, the rules will work in the same way, but reports will be sent approximately in the following form: what was blocked, why it was blocked, what rule.




Content-Security-Policy saves you from above, that is, do not rely on your code, protect yourself a little higher, at the browser level. In older browsers, Content-Security-Policy is not supported, so you need to know other headers, there are many, much more than in this list:




That is, you do not have to store cookies, so that they are not accessible from the document, be transmitted only in requests. To support various protections in old browsers, read later, be sure to remember about them. We are trying to protect ourselves from the development side, but what to do in production? We need some tula that automate this protection.


There is such a site and organization OWASP (Open Web Application Security Project). If you start to google something, you will definitely get there, this is where all the relevant information and statistics about all the vulnerabilities is collected. And it would seem, where, if not there, to seek advice on the use of the bodies. And so, if we go to this site, we will see a link to download in 2013, the release was 4 years ago. Am I using it? Probably, not. Here's another tip from 2006. This is probably when Sam Kamkar hacked, then this tool appeared. That is, there is nothing sensible. Most of the bodies, even just under Windows, work. But the most interesting thing is that we don’t need tula either. We want to embed them in CI. One of the most popular CI for an enterprise is Jenkins, I will give an example to him. No matter how paradoxical it may sound, one of the really worthwhile products is a product from OWASP itself, they support it, although for some reason they don’t advertise as much as others. ZAP Application Proxy works as follows. We in our Jenkins should refer to this Application Proxy through which our application will work. In test mode, this proxy can test our application. How will he do it? He just takes our application and starts to rape all of them, inserts everything in a row, then collects reports on what was inserted, what was rebooted, how it happened, and sends us reports in different formats. Additionally, we will need a ZAP Plugin and some kind of plugin for creating reports in order to collect analytics in the long run. Build some trends, etc. From the minuses, we can understand that it’s quite simple, especially for the front-end developer, to set up a proxy server in Jenkins CI is quite difficult, and even more so that the application runs through it. According to the performance can strike, the solution is not the easiest. But for the sake of interest, you can install it locally and test your site. I've played with holyjs-moscow.ru , a site on which, in principle, there is not a single input, there is nothing to break. But here are some recommendations that skipped some headers for older browsers. That is, if I somehow integrate between the domain and this site, I can use it for mining, why not.




The next tool is Arachni, it works according to a similar principle. From Jenkins we have to refer and give the URL of our secured test environment to this Arachni. Arachni has an excellent CLI, and he does the same thing, starts playing with our application and generates reports to us. It is more convenient to use, weighs less and is quite simple to implement. Additionally, we will need: Text Finder Plugin to analyze the result of the report, mark the build as failed or success, and another plugin for analysis in the long term.


But this is all a dynamic check. We wrote code, checked out, checked there, but we need to somehow understand that we are already writing something wrong, that is, we need to include some tool for static analysis. If we start to google, Checkmarx, Veracode, SonarQube will appear in the first rows in some mode - expensive tools, for the enterprise it is even expensive, in my opinion. 2018 , JavaScript , ECMAScript, TypeScript, JSX, - - . ? Not. , . ESLint – . Security , , . CI .


, ? , , node-? — Node Security Platform, npm ( npm install nsp ) npm check – . , , . , . , CI . — , package.json, , , , . , , , Snyk, . npm, , package.json, . , . Snyk , . Lighthouse, Canary, . , , dev tool, , , , , , , . Snyk GitHub, Dependency graph , , . .


, . . , . , . , - .


. , - , .


node_modules, , . Content-Security-Policy, (ESLint).




Minute advertising. As you probably know, we do conferences. JavaScript — HolyJS 2018 Piter , 17-18 2018 . , ( — ), -, . In short, come in, we are waiting for you. .

')

Source: https://habr.com/ru/post/349630/


All Articles