Watch Out: JavaScript's Dangerous Game

Why you should never use eval() in JavaScript. Reflected DOM XSS Attack.

Estimated read time: 1:20

    Learn to use AI like a Pro

    Get the latest AI workflows to boost your productivity and business performance, delivered weekly by expert consultants. Enjoy step-by-step guides, weekly Q&A sessions, and full access to our AI workflow archive.

    Canva Logo
    Claude AI Logo
    Google Gemini Logo
    HeyGen Logo
    Hugging Face Logo
    Microsoft Logo
    OpenAI Logo
    Zapier Logo
    Canva Logo
    Claude AI Logo
    Google Gemini Logo
    HeyGen Logo
    Hugging Face Logo
    Microsoft Logo
    OpenAI Logo
    Zapier Logo

    Summary

    This deep dive explores the inherent dangers of using the JavaScript eval() function, particularly in the context of a DOM-based Cross-Site Scripting (XSS) attack. The video dissects a lab scenario where a blog's search functionality leaks vulnerabilities due to this risky function usage. Through the examination of JavaScript code, especially external script files, the video highlights how eval() executes strings as code, making it a primary vector for attacks. This breakdown also explains the importance of using safer alternatives like JSON.parse() to handle JSON data, ensuring security and robustness against potential threats.

      Highlights

      • Injected strings can cause major issues when evaluated with the eval() function. 🚨
      • External JavaScript files can hide vulnerabilities if not scrutinized. 🔍
      • DOM-based XSS occurs before content is even rendered—hidden but dangerous! ⚠️
      • Bypassing JSON.parse() leaves applications open to JSON injection attacks. 💥
      • Broken JSON leads to syntax errors that secure parsers like JSON.parse() can catch. 🔒

      Key Takeaways

      • Never use eval() in JavaScript—it’s a security hazard waiting to happen! 😱
      • Eval() allows attackers to execute arbitrary code, putting your application at risk. 🚨
      • Using JSON.parse() instead of eval() prevents vulnerabilities by ensuring only valid JSON is processed. 💡
      • Understand the difference between JSON and JavaScript objects to avoid common mistakes. 📚
      • Ajax calls, though outdated, still pose risks if not handled correctly. Be cautious! ⚠️

      Overview

      In this thrilling video breakdown, we're uncovered the nastier side of the JavaScript eval() function. The creator, z3nsh3ll, opens the treasure chest of security flaws by demonstrating a DOM-based XSS attack made possible by careless eval() usage. Walking through a simulated blog lab, it's easy to see how injecting a simple string into a search bar can lead to more than just search results—try, exposed vulnerabilities!

        The video teaches us about the hidden dangers lurking in JavaScript's DOM manipulation, especially when external scripts run wild without oversight. As the creator dives into code inspection, viewers learn how eval() holds the door open for exploits by treating strings as executable code. The lab scenario becomes a lesson in why using JSON.parse() instead can make a crucial difference in security.

          Finally, it's a call to action for developers everywhere: steer clear of eval(), keep your eyes peeled for potential exploits, and ensure JSON integrity. This presentation stands as a brilliant reminder that while JavaScript empowers us to do more, it also asks us to code responsibly. Keep your applications safe, smart, and robust!

            Chapters

            • 00:00 - 00:30: Introduction to eval() and DOM XSS In this chapter, we explore the dangers associated with using the JavaScript eval function, particularly focusing on how it can lead to DOM-based Cross-Site Scripting (XSS) attacks. The discussion takes place within the context of a lab setup that simulates a blog with a search functionality. The chapter begins by demonstrating how injecting an arbitrary search string can lead to it being reflected on the page, highlighting the potential for exploitation using eval and DOM manipulations.
            • 00:30 - 02:00: Investigating JavaScript Code and DOM The chapter focuses on investigating JavaScript code and DOM to understand how a specific string is injected into the DOM. It begins with searching for the injected search string within the DOM, finding it inside the H1 tags. The investigation centers around figuring out how this string ended up there. It suggests a connection to DOM-based XSS, potentially injected by a specific JavaScript synchronization process.
            • 02:00 - 03:30: Understanding XMLHTTPRequest and Ajax The chapter "Understanding XMLHTTPRequest and Ajax" dives into the intricacies of placing a string in the DOM using JavaScript. Unlike previous labs at Burp Academy, which utilized a single HTML page with embedded JavaScript, this lesson introduces a more complex scenario with multiple pages. The main focus is on understanding that the JavaScript responsible for DOM manipulation is located in an external JavaScript file, as evidenced by the script source visible on the page. This highlights the evolution from simpler in-page scripts to more advanced, modular JavaScript setups in web development.
            • 03:30 - 05:30: The Danger of eval() and JSON Parsing The chapter discusses the potential dangers of using the JavaScript eval() function and JSON parsing in web development. It explores how JavaScript code is often external to the main HTML document, specifically analyzing the network tab to observe files that make up a web page. The discussion uses search results.js as a case study to understand the logic of page rendering and identify security concerns associated with eval() and improper JSON parsing.
            • 05:30 - 10:00: Exploiting XSS with eval() In the chapter titled 'Exploiting XSS with eval()', the focus is on analyzing JavaScript that hasn't been obfuscated and is easy to read. The discussion revolves around understanding the behavior of a function named 'search', which accepts a parameter called 'path'. By examining the DOM inspector, it's revealed that this JavaScript function is being invoked with 'search results' as the argument.
            • 10:00 - 15:00: Recreating the Vulnerability In this chapter titled 'Recreating the Vulnerability,' the focus is on understanding how a specific search function in a page triggers JavaScript, which is crucial for identifying vulnerabilities. The process starts by examining the creation of a new variable, xhr, assigned to the XML HTTP request object. This object is not commonly used in contemporary practices but serves as an entry point for exploring the vulnerability.
            • 15:00 - 24:00: The Security Risks of eval() The chapter titled 'The Security Risks of eval()' delves into the potential security threats posed by the eval() function in JavaScript. Although the transcript doesn't explicitly mention eval(), the discussion touches on asynchronous JavaScript and XML (Ajax) and its evolution over time. Ajax, initially involving XML, often uses JSON today. The chapter likely relates eval() to security issues in handling JSON and asynchronous requests, despite the transcript's focus on the shift from XML to JSON.

            Why you should never use eval() in JavaScript. Reflected DOM XSS Attack. Transcription

            • 00:00 - 00:30 we're going to be considering the dangers of using the JavaScript eval function and how in this particular lab it causes a possible Dom based cross-site scripting attack now this particular lab has a few moving parts so let's just get a fill for the intended functionality of this lab first of all so we have a Blog we have the ability to search the blog so let's start by injecting an arbitrary search string and straight away we can see our search string reflected to the page so let's
            • 00:30 - 01:00 fire up the Dom let's search for our injected search string in the Dom we'll see where it appears in this case we get one match on our string and it's appearing inside H1 tags but it's not appearing anywhere else in the Dom so the first obvious question is how did it get there there's a little bit of a clue in the lab title since this is a Dom based xss it usually means that this particular string was injected into the Dom by a specific JavaScript sync so the
            • 01:00 - 01:30 obvious question is where is the JavaScript that's placing that particular string in the Dom now this is a slight upgrade in complexity of previous Labs at burp Academy where we might just have a single HTML page and then a snippet of JavaScript at the bottom of the page but this particular lab makes use of a few different pages for example in this case the JavaScript is actually in an external Javascript file in fact we can see it on the page here script Source equals we have this
            • 01:30 - 02:00 search results.js also if we check out the network tab we can see the various files that are being pulled in to make this page possible now we're going to jump straight to the search results.js because we want to get a field for the logic of this page let's have a look at the response now in some ways this is slightly more realistic in the sense that JavaScript is usually not in the same document as the main page itself having said that it's still fairly straightforward in the sense that this
            • 02:00 - 02:30 JavaScript has not been obfuscated it's in a really straightforward readable format so let's get a feel for what's happening here now we can see a function being declared here and the name of the function is search and it takes in a param path and if we just head back to the Dom inspector just like to point out that we can see that the JavaScript is actually calling this particular function and it's passing in search results remember that we've just seen that this function accepts a path parameter so we
            • 02:30 - 03:00 can see here the path provided as a string the key takeaway here is that the page is calling this search function so that's going to trigger our JavaScript let's head back to our Javascript file so firstly we see a new variable being created it's called xhr and it's being assigned to a built-in JavaScript object known as the XML HTTP request now we don't see these as much in modern
            • 03:00 - 03:30 JavaScript because they've been replaced in a lot of cases by promises but the functionality is still the same it allows us to make an asynchronous request to an external resource and this is sometimes referred to as adjax which stands for asynchronous JavaScript and XML part of the irony is even when Ajax is used it often doesn't involve XML it often involves Json rather than XML is the case in this lab but for whatever
            • 03:30 - 04:00 reason it's still referred to as XML before Jason became very widespread XML was often used for communicating between processes on a web app whereas most cases we make use of Json but there's still some XML being used on production websites so this xhr object is created we then bind a function to an event listener so we have this event listener on ready State change and the idea is that the
            • 04:00 - 04:30 xhr object has this ready-state property which indicates the state of the request and the key piece of information we need right now is that ready State four means the request is completed so every time that ready State changes this function is triggered it checks to see if the ready state is four and also if the HTTP response status is 200. if both of those are true it means the HTTP request has
            • 04:30 - 05:00 succeeded and we can access the response data by making use of this dot response text in order to initiate this HTTP request we then need to make use of the dot open method provide some parameters so this is going to be the path that was provided through the path parameter from the original HTML Document Plus window.location.search which is going to be anything after the query string then finally we call it xhr dot send
            • 05:00 - 05:30 method which is going to dispatch the HTTP request so now let's return to this event handler Let's Pretend we've dispatched our HTTP request with the search information we've now received a response what is this JavaScript doing with the response it's calling a vowel it's passing VAR search results obj equals as part of a string then it's concatenating to that string
            • 05:30 - 06:00 this dot response text finally it's taking the newly created search results object and it's passing it to a second function which is defined below called display search results now let's just focus on this line of code eval and then we can see that a string is passed to the eval function what is the JavaScript eval function here we can see a description of a Val in JavaScript the eval function evaluates JavaScript code
            • 06:00 - 06:30 represented as a string and returns its completion value then notice we have a warning in red warning executing JavaScript from a string is an enormous security risk it's far too easy for a bad actor to run arbitrary code when you use a vowel so this is something that works in JavaScript but it's saying don't use a vowel it's very dangerous it poses huge security risks now we'll come back to this shortly and see what the problem is
            • 06:30 - 07:00 with that eval code first of all let's just refresh this page so we're going to be submitting the same search term because it's contained within the query string and let's just follow the lab through so we know that that search function is called as a result that xhr object is created then we expect an Ajax HTTP request to be sent to search results and we can see it here so if we check out the headers tab here we can see a get request made to our Academy
            • 07:00 - 07:30 forward slash search results then part of the query string we see our search term search equals Zen Shell let's have a look at the response so the response here is a Json object so we have our first key which is called results and then empty array that's because we don't have any matches then we have a second key which actually mirrors back our search term to us so we have a search term key as part of this Json object and it tells us your search
            • 07:30 - 08:00 term was Zen shell and obviously that Zen shell term is then taken and reflected to the page and if we dig around in that JavaScript we should be able to see that so keep in mind that we have a Json response which is stored in this dotresponse.txt that Json has been bound to our variable search results object that's passed to display search results and what this display search results does is it basically goes through the Dom and renders all of our
            • 08:00 - 08:30 search results to the page but we're not too interested in that for now because the vulnerability actually occurs before all of that information is rendered to the Dom let's take a look at that Ajax HTTP request that's sent to the search results endpoint which Returns the Json object so we can see that HTTP request here and we can see the Json response so we have an empty array for results because our search term didn't return
            • 08:30 - 09:00 any results we then have the search term key with Zen shell now we're going to jump ahead and see that it's possible to break out of this string so we can actually break out of this Zen shell string and we can add an alert function or we can subtract in this case so let's experiment with that input we can right click and choose send to repeater in burp so this is the request that we're going to send in fact let's just submit that and we see our Json response now the obvious way of attempting to break
            • 09:00 - 09:30 out of the string is simply to include a double quote then we could do something like minus alert and the reason why we like to use minus instead of plus is simply because plus is typically URL encoded whereas minus or hyphen is not so rather than Zen shell plus alert it's typical to try something like Zen shell minus a lot it's a little bit cleaner this way let's send that and see what we get now what we can see is we failed to break out of the string and that's because the Json response is
            • 09:30 - 10:00 automatically escaping that double quote so this is a standard feature of JavaScript strings imagine we wanted to create a string with double quotes but we wanted a double quote character inside that string but we don't want that double quote character to terminate the string as it would ordinarily we can make use of what's known as escaping in JavaScript it means placing a backslash before that particular character so that character no longer carries a special meaning so you can see what's happening
            • 10:00 - 10:30 here is that because there's a backslash before that double quote it's not terminating the string the interesting thing though is that backslash is also a special character that can be escaped so if we instead put backslash double quote and submit that payload see what we get well now we've actually broken out of that JavaScript string you see the backslash returned from the Json response is no longer escaping that double quote because we're escaping it manually with the backslash we're submitting as part of the payload so
            • 10:30 - 11:00 what we actually have here is search term Zen shell minus alert now part of the problem is that we don't have a valid JavaScript object at this stage that's because we have this trailing quote and we have this end of the object we can actually comment that out and the way we use comments in JavaScript double forward slash but we're going to end our JavaScript object first and we're going to submit that so what we have now is completely valid JavaScript object so
            • 11:00 - 11:30 you have search term we have a string minus the alert function our object ends correctly we then have the JavaScript common characters and then that isolated double quote is commented out so let's take this now as our payload so we're going to copy this we'll head back to our lab let's paste this into our search box and you can see we get the alert function popped up to the screen so this is the lab solved but the
            • 11:30 - 12:00 question is why is it working because surely we can't ordinarily just comment things out on a JavaScript object but the thing is this is not a pure JavaScript object it's actually constructed from a string and this is where we loop back to that a vowel function causing us problems I think the best way is to just recreate the lab so we're going to create a fresh HTML document we're going to put everything inside HTML tags we'll have a body to our HTML document
            • 12:00 - 12:30 we'll just give it a heading we're going to call it a vowel because really this is a lab on where you should never use eval I'll place an empty paragraph after the H1 and this is actually not part of the exploit as you'll see this is what happens after the exploit because the lab actually renders the search results to the page in fact it creates the element first then places the text in that element then attaches it to the Dom we're not going to do all of that we're just going to place the elements automatically in the HTML but we will
            • 12:30 - 13:00 have to render the search results to the page so let's open up some script tags so we can make use of this xhr JavaScript functionality we were referring to so we can say VAR XML HTTP equals new XML HTTP request we'll then specify the URL for this HTTP request and you can see I've created a data dot Json and it has inside information Zen shell and we'll start a
            • 13:00 - 13:30 web server at Port 8000 so in order to get this Json object returned as a response we'll say VAR URL equals HTTP forward slash localhost at Port 8000 then of course we can reference the name of the file directly which is data.json in this case so now we need to set up the event listener so we can say XML HTTP on ready State change equals we'll code our listener now and we can say if
            • 13:30 - 14:00 this dot ready State equals exactly four and this dot status equals exactly 200 that means that the HTTP request has exceeded so this is going to be our code now for handling the response and for now let's just console log out this dot response so we can check that everything works at the moment this is just creating the object so we need to call XML HTTP open method we need to specify that it's going to be a get request we
            • 14:00 - 14:30 need to pass in the URL variable that we've created and we need to pass true as well and finally XML http.send is going to dispatch the HTTP request finally we are inside the relevant folder in our terminal as you can see and it's very easy to start a basic web server using PHP so I'm running PHP hyphen s and we're running that on localhost Port 8000. so if we head to localhost Port 8000 let's just reload
            • 14:30 - 15:00 the page so you can see the initial HTTP request which is going to pick up index.html automatically then we can see an xhr or XML HTTP request to data.json and we can see that that's going to return a Json response the next thing our lab does is it binds the response to a variable so we can say my object in fact let's say let my object equals this
            • 15:00 - 15:30 dot response and it actually does this with the eval function as we're going to see let's just take a look at this code outside of the eval function first let my object equals this dot response now what is this dot response it's a Json object right no it's not it's a string sometimes we forget this because especially in the world of JavaScript Frameworks and Promises we sometimes find that the framework actually passes a Json response into an object for us
            • 15:30 - 16:00 whereas that's not the case with these xhr requests this is actually a string and we can prove this because we can actually console log type of this response say type of this dot response let's see what the output gives us we'll head to the console so you can first of all see it echoed out type string so this is not an object at least not yet the correct way of handling this is to make use of javascript's json.pass method so if I do
            • 16:00 - 16:30 let my object equals Json dot pass and then put this response as the parameter now if we console log out type of my object after it's been passed as Json let's check this out we can see we get object um we can actually now use that object to reflect data to the page so just as a quick recap on our Json object it's returning information as the key and
            • 16:30 - 17:00 then Zen shell as a value so we could do something like document dot get element by ID we created a paragraph and we gave it the ID of page let's just pass in page that's going to select that specific element from the Dom then we can set inner text equals myobs.information so that should now render the data to the Dom in response to that HTTP request where we get the Json object returned so
            • 17:00 - 17:30 let's head to our page let's refresh that we can see we get the information rendered to the Dom as mentioned the exploit actually happens before this now let's head to our Json object now we don't need to worry about escaping or anything like that because we actually have direct control over the Json object that's the difference in the lab is we submitted that Ajax HTTP request and there was some escaping going on with the response whereas we can control directly that
            • 17:30 - 18:00 Json response we have it here in this file so we're one step ahead compared to where we were in the lab we can think about this exploit without needing to worry about any of the extra complexity that comes from escaping so what we actually had is we had a string and we had minus alert function now notice straight away that that is linted in red it's indicating to us that this is not actually a valid Json object I'll see what happens when we try and run that what do you think are we going to get
            • 18:00 - 18:30 the alert Echo to the page see what we get we refresh that we get an error in the console unquote syntax error json.pass expected a comma or the end of the object in other words it's saying we can't run Json pass method on this Json because it's not valid Json why is it not valid Json sometimes we think about JavaScript objects and Json as being the same and
            • 18:30 - 19:00 they're actually not the same they're similar but they're different they have different rules in fact take a look at this section Json evaluates to JavaScript objects the Json format is almost identical to JavaScript objects in Json Keys Must Be Strings written with double quotes so there's one difference right off the bat you can see Json you have to have the key inside double quotes whereas JavaScript you can just do this we don't care about the double quotes but then if we take a look at the values as well in Json values
            • 19:00 - 19:30 must be one of the following data types A String a number an object an array a Boolean I don't see anything to do with like a function or a method or anything like that that's not value Json syntax you can't have an expression or a function in Json it has to be a string a number an object an array or a Boolean that's it in JavaScript however values can be all of the above plus any other valid JavaScript expression including a function including a date including undefined including Zen shell minus
            • 19:30 - 20:00 alert method that's a valid JavaScript object as well it's just not valid Json so this is why when we're calling json.pass javascript's refusing to pass it it's saying this is not a valid Json object and here is where we get back to the problems with Val let's now rewrite this single line of code using a vowel instead of json.pass so we're going to use eval remember the idea behind a
            • 20:00 - 20:30 vowel is it takes a string as a parameter and then it reads that string like its JavaScript the key problem here is that it's very easy to inject into Strings and also we're not making use of json.pass we're not checking if this is a valid Json object before initiating it into a JavaScript object so it's essentially the same line of code but it's inside a string so we're going to say let my obj equals and we're simply going to concatenate to
            • 20:30 - 21:00 that the response that we get back from the server which is that data.json file but remember it's not a Json object yet it's just a string yes it's Json but it's in string format so that's why we can concatenate it here so we'll say plus then we'll say this dot response and we're going to comment out the correct line of code so this is very similar but remember this is actually jumping straight into a JavaScript object taking a string and it's using it to create a JavaScript object it's completely bypassing that json.par
            • 21:00 - 21:30 section where we check to see if that is valid Json and remember if it's value Json then we can't just tag a function on the end of it we're going to get that error the cross-site scripting attack never happens but in terms of passing this as a string as part of the eval function well this is a valid JavaScript object it's not valid Json but it is a valid JavaScript object let's see what happens now when we run this code refresh the page now we get the alert popped up to the page now one of the subtleties of this lab is we might
            • 21:30 - 22:00 imagine when first solving the lab that the cross-site scripting attack occurs when information is rendered to the Dom whereas in fact it's this line that triggers the cross-site scripting attack in fact the rendering to the Dom doesn't even work unless we actually use VAR myobs instead of let my odds so if we actually run this attack now you'll see that the attack succeeds we get the alert then when we click OK we see n-a-n rendered to the Dom and the reason why
            • 22:00 - 22:30 we have n a n it's just to do with the dynamic typing in JavaScript it's trying to assume that this is a type integer when it's not so it's just saying actually this is not returning a number so we're getting n a n we actually remove this and refresh the page of course we don't get the cross-site scripting anymore but we see the rendering to the Dom occur correctly as we'd expect but there's obviously not a vulnerability with this lab which is we just manipulate the Json response so
            • 22:30 - 23:00 we're doing it directly on the Json object in the lab we do this via the search input we obviously need to consider escaping when we do that and you see very clearly we get the alert and then we get the rendering to the Dom in fact if we just completely remove the rendering to the Dom but let's just do absolutely nothing after that a valve function is called let's refresh the page we get the alert popped up to the page still no rendering to the Dom so unlike other types of attack where maybe the cross-site scripting vulnerability
            • 23:00 - 23:30 occurs after the rendering to the Dom in this case we can see it actually takes place beforehand and it's to do with the use of that valve function so the key takeaways anytime you see a vowel being used as part of the JavaScript that's a big red flag and the reason why is because eval takes in a string and it's very easy to inject into a string and the chances of being able to run arbitrary code when a Val is used on the JavaScript is much higher we also saw
            • 23:30 - 24:00 how removing a valve completely fixed the cross-site scripting vulnerability because we weren't even able to pass that Json object because Jason pass could see it was corrupted it wasn't valid syntax it wouldn't even begin working with that object in the first place if Val doesn't care it just takes in the string and doesn't care how that String's been injected into it will try and use it as value JavaScript