1. React Application Hacking and XSS
How to hack a RealWorld live React application in seven minutes. Tips, best practices, and pitfalls when writing React code. XSS and cross-site scripting in React. React's secure by default, but not always. The first thing to discover: adding a link to a React application.
How would you like to hack a RealWorld live React application? So let's get started and see how we do that in seven minutes. I'll try to give you as much tips and best practices as I can and show you where the pitfalls are when you write React code.
So my name is Iruntal, I'm a developer advocate at Snyk where we help developers build secure software. I've got a bunch of stuff around OWASP and Node.js and security research that I'm doing on my own. If you have any questions or want to help me do some of that as well, just reach out afterwards and I'd be happy to chat with you and we'll do some stuff together.
So, how do you do React vulnerabilities live? So essentially, think about XSS. And I'll go through this really quickly. Like, why am I talking about XSS and cross-site scripting when we have React and modern front-end frameworks? So consider this code example, which has first name with some XSS image and first name is user input, right? It flows into your JSX like that, and React outputs something like this. So far, so good. Basic stuff. It works. Actually, React outputs this and not the other thing that you saw before. These are called HTML entities, and it allows the browser to understand that these are left side triangle, right triangle with the less than, greater than, and all of those things. And so the browser understands that you want to print it and show you this. So, like, basic stuff.
But React is secure by default. Or secure by default, this is essentially what it means. It's doing output and coding. Well, what if I told you it sometimes does that? Not all the time. And that is where things get very hairy. So let's discover the first thing. Take one. I want to add a link to a React application. So imagine this is my application and I'm building it on the right side. And there's a user story, right? Product managers put in a user story. You want to add Twitter links. It makes sense. I add a Twitter link. You can see the input. I essentially have my Twitter link coming in, maybe at, like, a JSON feedback from the back end or somewhere else.
2. React Code Vulnerability and Best Practices
React code vulnerability: cross-site scripting with Twitter link. React doesn't sanitize or output H ref attributes. Fix attempts: detect JavaScript, use dummy hashtag, transition to lowercase. Control corrector exploit. Best practices: avoid denialist approach, sanitize user inputs.
And I have my React code with a component. There's a button in it. H ref. I give it the Twitter link. So far, so good? Let's see.
Well, essentially, if this flows into the Twitter link as is, that is a cross-site scripting vulnerability. So if you did that, and really the input of the user for the Twitter link was the following, you'd get an alert popup. This is plain React code. I didn't do anything except show you the code of what actually happens. The thing is React doesn't sanitize or output in code those H ref attributes.
So let's try to fix it. Maybe we'll try to fix it and do something like, well, I'll detect all of those JavaScript and collon whatever is coming up there, index of, right? I'm detecting and starting with this rather than being somewhere else on the URL. I'll go ahead and fix it with some dummy hashtag. So I do that, but then... That doesn't work because hackers are smart, so they try different ways to fuzzy test the application.
So maybe I'm thinking, well, you know what? I'll try to fix it with a lowercase. So I'll transition everything to lowercase and then match them. Okay? So I did this. Very simple. Push it to production. I tested. It works. But then someone comes in and they do something like this. Okay? This is a control corrector. If someone pushes this in, it means essentially the end of the medium, the end of line. This is a way for someone to push it in. And so all of that thing just ends up not working. So links in React apps. Think about the fact that best practices here don't do denialist, okay? They're trying to figure out how to remove it. Also think about things like sanitizing user inputs where it should be.
3. React XSS Vulnerabilities and Secure Coding
React's lack of sanitization and output encoding for user inputs. Exploring XSS vulnerabilities and the need to pretty print JSON. The React JSON pretty package and its potential XSS risks. The importance of context encoding and secure coding practices.
Because React doesn't sanitize or correctly actually output encodes of everything that you push into it. There are specific context like HTML attributes, two elements and all of those things. So that said, let's see another way of doing it.
Discovering other people's XSS vulnerabilities. How do you pretty print a JSON to look something like this? Because I don't want to write the whole logic around printing it and indentation, et cetera. So I do an npm install for a package that does this for me. Makes sense. This one has 50K downloads a week. So I feel pretty well to install React JSON pretty. I do it. I import it. All of that makes sense. Then I use it like that. A very cool, easy, simple component. So far, so good. That's what you do all day. Is it XSS-free?
Think about what input can flow into the application. Maybe it flows in different ways. Maybe your package manifest or the JSON you want to show there is actually not a JSON It's maybe a string. So here's the code for it. This is the code from the React JSON pretty component. The npm library. You can see it has some dangerously set HTML, but it actually calls this pretty, which is a method inside that has something that actually tries to output encoding correctly. So it does essentially what React does. Well, if you look actually more into what's going on with stuff that it tries to catch and not do correctly. It actually has this area where it catches it, but doesn't do output encoding correctly. So that's what we have. And they have tried to do some XSS to try and remove it. Maybe you tried it. Maybe it doesn't work. Maybe you use it in specific context. And you fall into the same problem, because if you try to do that in XSS for an attribute, that's not going to work. You need to do context encoding.
So with that said, I'm going to tell you if you want to learn more about all of those There's a bunch of stuff on the blog. You can just Google things like react-security-best-practices-sneak or something like that. And do secure coding. So thank you so much.
Comments