Uncovering and Exploiting a Client-Side Template Injection in Vue.js

Vue.js is a popular open-source JavaScript framework used for building user interfaces and single-page applications. It was created by Evan You and released in 2014. Vue.js is known for its simplicity, flexibility, and ease of integration with other libraries and projects.

Vue.js has gained significant popularity in the web development community due to its simplicity, performance, and extensive documentation. It’s often compared to other front-end frameworks like React.js and Angular.js, offering it’s own unique features and advantages.

As with any software framework or library Vue.js may have vulnerabilities that could potentially be exploited by attackers. Some common types of vulnerabilities associated with Vue.js applications include:

  • Cross-Site Scripting (XSS): XSS vulnerabilities can occur if developers do not properly sanitize user input or output. Attackers may inject malicious scripts into the application, which can then be executed in the context of other users’ browsers, potentially compromising sensitive data or performing unauthorized actions.
  • Component Security: Vue.js applications often rely on third-party components and libraries, which may introduce vulnerabilities if they are not regularly updated or if they contain security flaws. Developers should ensure that they use reputable and up-to-date components to minimize the risk of vulnerabilities.
  • Sensitive Data Exposure: Vue.js applications may expose sensitive data if developers do not properly secure data transmission or storage. Attackers may intercept network traffic or exploit vulnerabilities to gain access to sensitive information such as user credentials or personal data.

In this post we will analyze and understand common mistakes and misconfigurations that lead to applications being vulnerable to Cross-Site Scripting (XSS) in Vue.js.

Let’s start with a simple example of a Vue.js application that displays a form to search for data that is reflected in the URL and to the page.

 

Let’s take a look at the code and get an understanding of what is going on.

  • This HTML structure sets up a basic web page layout.
  • The Vue.js and Vue Router libraries are imported using script tags from CDN (Content Delivery Network) sources.
  • Bootstrap CSS is included to style the components again from a CDN.
  • The main content is wrapped in a div with the id app, which is the root Vue instance.

The important part about this HTML is on line 25. <p v-html="searchQuery"></p>. We will come back to this. Let’s keep moving.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Search App</title>
  <script src="https://unpkg.com/vue@2/dist/vue.js"></script>
  <script src="https://unpkg.com/vue-router@3/dist/vue-router.js"></script>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>

<body>
  <div id="app" class="container">
    <h2>Search Form</h2>
    <div class="form-group">
      <form action="#">
        <label for="search">Search: </label>
        <input id="search" name="search" type="text" v-model="searchQuery" @input="updateUrl" placeholder="Type something...">
      </form>
    </div>
    <strong>Results:</strong>
    <p v-html="searchQuery"></p>
  </div>

The next and final snippet of code we will analyze is the guts of the Vue.js code. Let’s also break this down.

  • A Vue component called SearchResults is defined. It receives a prop called searchQuery and renders a simple template displaying the search query.
  • Vue Router is configured with a single route /search, which renders the SearchResults component. The searchQuery prop is passed to the component based on the query parameter q from the URL. If the URL does not match any route, it redirects to /search.
  • A new Vue instance is created, bound to the #app element.
  • The instance is provided with the Vue Router instance router.
  • The data object initializes the searchQuery property to an empty string.
  • The updateUrl method updates the URL with the current search query whenever the input field changes.
  • In the created lifecycle hook, the code checks if there’s a q query parameter in the URL. If present, it initializes the searchQuery with its value.
<script>
    const SearchResults = {
      props: ['searchQuery'],
      template: `
        <div>
          <h2>Search Results</h2>
          <div>Results for:<p v-html="searchQuery"></p></div>
        </div>
      `
    };

    const router = new VueRouter({
      routes: [
        { path: '/search', component: SearchResults, props: (route) => ({ searchQuery: route.query.q }) },
        { path: '*', redirect: '/search' }
      ]
    });

    new Vue({
      el: '#app',
      router,
      data: {
        searchQuery: ''
      },
      methods: {
        updateUrl() {
          this.$router.replace({ query: { q: this.searchQuery }});
        }
      },
      created() {
        const queryParam = this.$route.query.q;
        if (queryParam !== undefined) {
          this.searchQuery = queryParam;
        }
      }
    });
  </script>
</body>
</html>

After breaking this down, what is the vulnerability and how can we exploit it?

As I stated earlier we need to review <p v-html="searchQuery"></p> and understand what makes this dangerous. Reviewing the documentation on the directive v-html reveals it will output data in HTML. The search form is taking user input and outputting it as HTML. 

Let’s abuse this and supply HTML to the search and see how it displays.

As we can see we have successfully exploited the search function and have HTML rendered on the page. Now we can try JavaScript with the payload <img src=x onerror=alert('xss')>.

Again we are successful at exploiting this flaw in the code. 

You might be wondering, “how prevalent is this issue?” Unfortunately, I must admit that it occurs far too frequently, despite the explicit warning message provided in the documentation on vuejs.org regarding its potential dangers.

How can we remediate this vulnerability? The proper method is simply wrapping the data in double mustaches or {{ }} to interpret the data as plain text and not HTML.

Let’s modified the code to use {{searchQuery}}.

<div id="app" class="container">
  <h2>Search Form</h2>
  <div class="form-group">
    <form action="#">
      <label for="search">Search: </label>
      <input id="search" name="search" type="text" v-model="searchQuery" @input="updateUrl" placeholder="Type something...">
    </form>
  </div>
  <strong>Results:</strong>
  <p>{{searchQuery}}</p>
</div>

<script>
  const SearchResults = {
    props: ['searchQuery'],
    template: `
      <div>
        <h2>Search Results</h2>
        <div>Results for:<p>{{searchQuery}}</p></div>
      </div>
    `
  };

As we can see in the results no HTML is rendered. Only the plain text value. 

This method of exploiting a common Vue.js mistake is both simple and impactful. Frequently, it stems from developers copying and pasting code snippets from sources like Stack Overflow or ChatGPT without fully understanding the risks. It underscores the importance of taking heed of warnings presented in documentation, as negligence in this regard can lead to significant vulnerabilities.
 
Here is the entire vulnerable code snippet if you would like to tinker with it. It’s all client-side.

If you found this helpful, please send me a tweet and tell me what you thought! Feedback is always appreciated!

Jarrod

 
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Search App</title>
  <script src="https://unpkg.com/vue@2/dist/vue.js"></script>
  <script src="https://unpkg.com/vue-router@3/dist/vue-router.js"></script>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>

<body>
  <div id="app" class="container">
    <h2>Search Form</h2>
    <div class="form-group">
      <form action="#">
        <label for="search">Search: </label>
        <input id="search" name="search" type="text" v-model="searchQuery" @input="updateUrl" placeholder="Type something...">
      </form>
    </div>
    <strong>Results:</strong>
    <p v-html="searchQuery"></p>
  </div>

  <script>
    const SearchResults = {
      props: ['searchQuery'],
      template: `
        <div>
          <h2>Search Results</h2>
          <div>Results for:<p v-html="searchQuery"></p></div>
        </div>
      `
    };

    const router = new VueRouter({
      routes: [
        { path: '/search', component: SearchResults, props: (route) => ({ searchQuery: route.query.q }) },
        { path: '*', redirect: '/search' }
      ]
    });

    new Vue({
      el: '#app',
      router,
      data: {
        searchQuery: ''
      },
      methods: {
        updateUrl() {
          this.$router.replace({ query: { q: this.searchQuery }});
        }
      },
      created() {
        const queryParam = this.$route.query.q;
        if (queryParam !== undefined) {
          this.searchQuery = queryParam;
        }
      }
    });
  </script>
</body>
</html>

 

 

Finding Vulnerabilities with Burp Suite Intruder and Repeater (Community Edition)

Burp Suite is a set of tools used to perform Web Application Pentesting. In this guide I will show you how to leverage the free (community) edition to help find vulnerabilities in web applications. We will utilize Burp Suites Repeater and Intruder functionality along with word lists from SecLists.

I will use a TryHackMe Free room called Team Room and a room called Brute it to help set up the testing targets. I highly encourage looking into the Burp Suite Academy for labs on Burp Suite as well to get more hands on experience.

I will also be using FoxyProxy to proxy the traffic through. If you are not familiar, Burp Suite needs to have a proxy setup between the browser and target application. FoxyProxy helps make managing the proxy simple, as it can be enabled and disabled through the browser.

Here is a basic setup on how I have FoxyProxy setup and leveraging Burp Suites port 8080.

Using TryHackMe’s Team Room, we can have an environment set up to do testing. With Burp Suite running and Team Room setup via TryHackMe we can get testing.

I will be cheating a bit to get to the fuzzing section of Team. In the /etc/hosts file I will add an entry for dev.team.thm. This will set up the section to perform our first attack.

Navigating to http://dev.team.thm will display a web page. With Burp Suite we can access the Proxy Tab and then the HTTP History Tab and “Add to scope” to ensure only this applications traffic is captured with Burp Suite.

Clicking the Place Holder Link loads a new page with a page parameter in the URL.

Next we can forward this request to Repeater in order to do some analysis. We can then tinker with the page parameter, change the Request to a Post Request, mess with the User-Agent, etc, to see if the application will display any errors or useful information in the Response.

The next step is to use Intruder to fuzz the page parameter to see if it is vulnerable. SecLists offers a variety of fantastic word lists that we can use to Fuzz the parameter. I encourage you to review and look over these word lists and see which ones can help you in a particular moment.

SecLists offers lists for command-injection, SQL Injection, XSS, Local File Inclusion (LFI), passwords, word lists for directory/file brute forcing, extensions, and much more.

Sending the request to Intruder, we can highlight the parameter we want to fuzz. In this case we want to highlight the teamshare.php value. The attack type will be set to Sniper.

Next we will click the Payloads tab. Here we can insert our word list values from our SecLists. Because the parameter appears to be loading in a file, it would be a good guess to try for Local File Inclusion (LFI). We can copy and paste the values of file LFI-Jhaddix.txt into the Payloads Options section. In SecLists this is stored in Fuzzing/LFI.

Burp Suite Community Version will throttle the speed at which the fuzzing is happening, but we will quickly see some results come back from our attack. While Intruder is cycling through the word list we can view Responses that have a vastly different Length to see if anything is interesting pops up. It turns out that the parameter is indeed vulnerable to Local File Inclusion.

The combination of Burp Suite intruder and SecList word lists for LFI allows us to not only to have a POC for /etc/passwd, but other Linux files that were read.

This was a good example of what Intruder and a good word list can do. Let’s take a look at one more example using Intruder to perform brute force password attacks on an administrative login.

Using the TryHackMe room Brute It we can get practice using Burp Suite Intruder to perform a brute force attack. If you are interested in working along, fire up Brute It on TryHackMe and navigate to the /admin page. Here we see a basic login page.

With Burp Suite running and FoxyProxy enabled we can capture a post request by attempting default credentials with admin/admin.

With the parameters setup for the user to be admin and the password to be the target using a Sniper Attack Type we can now load in another word lists with SecLists.

This time we will try the 500-worst-passwords.txt to see if we can find the admin password. This password list if found under /Passwords. Either load in the word list or copy and paste the passwords into the Payloads section. Submit the attack by clicking the attack button and let’s see if we get a hit.

Viewing the results we see one that sticks out with an HTTP Status of 302 and a much different Response size. This is a pretty good sign we got a hit during our brute force attack.

Using the credentials from Intruder we are able to verify the password for the admin was correct and we have successfully authenticated.

This concludes the basic guide for Repeater and Intruder. If you want to get more hands on with Burp I recommend TryHackMe’s Burp Suite Module. Here is the starting basics section. Burp Suite is an incredible suite of tools that can help find vulnerabilities and misconfigurations in a web application.

More hands-on labs can be found on Burp Suite Academy’s site if you want more targeted vulnerabilities to work on, such as SQL Injection or XSS.

If you found this helpful, please send me a tweet and tell me what you thought! Feedback is always appreciated!

Free Resources To Learn Pentesting

TryHackMe
TryHackMe is a online service that offers paid and free rooms. The highlight for TryHackMe is that it offers beginner friendly and advanced rooms for pentesting, malware analysis, digital forensics, and much more related to cyber security. If you are just getting into Cyber Security, this is a great starting point. If you enjoy the free content, consider the monthly service to have access to the paid rooms. I used this as my first Cyber Security Training to help me become a Pentester.

PortSwigger Web Security Academy
PortSwigger Academy is a free online resource for learning beginner and advanced Web Application Exploits. This site offers labs on XSS, SQL Injection, Server Side Request Forgery and so much more. The course is designed around PortSwiggers Burp Suite Program, but labs can be completed without it. PortSwigger is always adding new content to the site. This is a great resource for learning Web Application Pentesting.

API Security University
APISEC University is a website that offers Courses on learning how to hack and pentest against APIs. Corey Ball goes into great detail in discussing how to hack APIs and talking about the OWASP Top 10 for API Security. This course is free and offers great video material that help set up labs and perform the test, then at the end of each section you will be given a quiz and a lab to perform to ensure you are learning the material.

The Cyber Mentor YouTube Channel
The Cyber Mentor has a fantastic YouTube Channel dedicated to Cyber Security. I could make a blog post dedicated to just Cyber Mentor Content. The content on the YouTube playlist I recommend checking out is the twelve hour series on Ethical Hacking. It includes information on networking, basic hacking techniques, python programming, web application hacking, buffer overflows, OISNT, and much more. If you enjoy the free content, you can check out the paid video series on TCM Security Academy and extend your knowledge.

HackTricks
HackTricks is a fantastic website that has great learning material and methodology on pentesting. It is a typical go-to while I am performing a pentest to get a refresher on a tool. This site has a great number of links to resources and other learning material as well. I highly recommend checking out this resource and giving the material a read.

Active Directory Security
Active Directory Security is a website used to post information about Active Directory Security and pentesting. Learn about Mimikatz, Kerberoasting, AD Recon, and more. If you are interested in Active Directory Security and pentesting, this site is a great resource to learn from.

VulnHub
VulnHub is a resource with vulnerable boxes that are meant to provide hands-on practice. The website offers several vulnerable boxes that use Virtualization Software such as Virtualbox or VMWare. I recommend the route of setting up your own virtual environments and testing against it. You can also look into hardening and patches the boxes.

If you found this helpful, please send me a tweet and tell me what you thought! Feedback is always appreciated!

My Top Ten TryHackMe Rooms

I have been a TryHackMe fanboy for a while and just finished up doing a 500 day streak and have completed 275+ rooms. I wanted to write a blog post describing my personal ten favorite rooms.

No flags or hints on how to complete these rooms on this page. I will discuss at a high level what the room is about and what skills or techniques would be needed to solve it. If you like to go into rooms 100% blind than feel free to skip this blog post.

10. Vulnversity

Vulnversity is a free and beginner friendly TryHackMe Room that is geared towards teaching the basics of Pentesting.

The room includes a video guide by Darkstar and does a fantastic job of explaining the tools used, thought processes, and holds your hand throughout the room. This is great for someone that is looking for their first penetration testing room that wants their hand held from start to finish.

This was one of the first rooms I did when I started TryHackMe and it cemented a number of techniques and tools I still use today. Port scanning, file and directory fuzzing, using reverse shells, and privilege escalation. Often I get asked what a good starting room is for penetration testing. This is the one I recommend.

Tools/Techniques that you could use are

  • Nmap
  • GoBuster
  • Burp
  • Netcat
  • Using Linux to abuse SUID to become root

9. Jason

Who doesn’t love a good horror movie? Jason is a room that is fairly easy, but the technique used to complete the room can be a bit complicated for those new to penetration testing.

It is an easy room if you know what deserialization vulnerabilities are and how to exploit them. If this is something you are not familiar with then here is an OWASP article for you to read if you are interested.

If you want to practice deserialization then this room is for you. It is one of the few rooms that if you are struggling with deserialization I recommend using a guide or walk through to help get you through and learn about the concept.

Great room with fun challenges, great design, and helps in learning a rather daunting technique. Highly recommend checking this out if you are on the hunt to learn more about exploiting deserialization vulnerabilities.

8. Thompson

Thompson has a special place in my heart. I used to manage Apache Tomcat and this room is all about exploiting Tomcat in a fun and real world scenario.

I love when a box has a real world feel to it and Thompson is a scenario that penetration testers will see in the wild and have an opportunity to exploit. Tomcat is deployed with multiple default configurations and files that attackers will use against the target.

From the starting point of the room you get to have a lot of fun fuzzing for files and directories, password spraying, and using Metasploit to exploit Tomcat Manager to get into the system with a reverse shell.

I have seen this similar room used in competitions and it is definitely a room you want to check out.

Tools/Techniques that you could use are

  • Nmap
  • GoBuster
  • Hydra
  • Metasploit
  • Abusing crontab for privilege escalation

7. Linux Agency

This box is 100% a video game box. It is a fun and exciting way to learn more about Linux commands.

The premise is: you start off on mission one. You ssh into the box as mission1 and are given a task to solve that allows you to become mission2 user and you essentially climb a ladder solving a challenge and then becoming a new user to solve another challenge.

The challenges change from different Linux techniques such as outputting data from a file, grepping a flag out of a file that has thousands of lines of data in it, changing file permissions, compiling files to get output and using various programming languages to read files.

Linux Agency is fun. However it is long so be prepared to spend some time on this room, but when it is done you will level up your Linux knowledge.

6. Wreath

Wreath is a large room aimed at teaching pivoting and Command and Control Frameworks. It is a very large room that can eat up a day.

It is highly recommend to take good notes and take it slow. I swear I didn’t plan this but again Dark has created a video guide to help teach and walk users through this if needed. The video guide is forty one videos and as stated earlier this can easily eat a whole day.

That being said it is a “free” room. The catch is it is free if the free user has a seven day streak.

This room goes into great detail on pivoting and what it is and with socat, chisel, and SSH Tunneling / Port Forwarding. The next major section will be Command and Control. If you are not familiar, Command and Control (C2 Frameworks) are applications used to manage remote sessions on a compromised host. Cobalt Strike, Covenant, Metasploit, and Empire are examples of C2 Frameworks. The last major section is AV Evasion.

I suggest this beast of a room because it teaches excellent fundamentals for internal pentesting and how to pivot and use C2 Frameworks. I cannot even remotely begin to explain how cool and amazing this room is. You will gain so much hands on experience and it is free for users with a seven day streak. I would easily pay money to TryHackMe to have access to this room.

5. Buffer Overflow Prep

Before I started TryHackMe, I had some basic Ethical Hacking Knowledge. I knew how to do a lot of the easy rooms and felt comfortable with using tools such as Nmap, Metasploit, GoBuster, Burp, etc. What I didn’t feel comfortable with was Buffer Overflows.

Buffer Overflow Prep by Tib3rius was a God send for me. It taught me how to do buffer overflows and gave me so many attempts at doing them that I got the basics down and felt like I conquered a huge undertaking. Buffer Overflows can be a lot to take in and work on and with Buffer Overflow Prep I was able to overcome the fear and learn to have fun with them.

That is why I recommend Buffer Overflow Prep and why it is one of my favorite TryHackMe rooms. It gave me the tools and knowledge needed to learn how to perform a Buffer Overflow and how to transfer the knowledge to other rooms and exams.

I know someone else out there is afraid to dive into Buffer Overflows and if that someone is you, try this room and watch the video Tib3rius made for this room. Stack Based Buffer Overflow Prep.

4. Linux/Windows Priv Esc

I’m cheating here, but I’m going to combine Linux and Windows Privilege Escalation rooms together for the number four spot.

Created by Tib3rius, these rooms are geared towards teaching some of the most important techniques that are required to go anywhere in this field. A short list of what you will learn are

Linux:

  • Weak File Permissions
  • Cron
  • SUID
  • NFS
  • Kernel Exploits

Windows:

  • Registry
  • Scheduled Tasks
  • Token Impersionation
  • Service Exploits

This is a short and sweet description, but nothing can really be said other than if you want to be a penetration tester / red teamer than these two rooms are essential.

A small bonus I found helpful was to take the Udemy courses by Tib3rius as I did these rooms. The Udemy videos and TryHackMe rooms do an excellent job complimenting each other.

Links to the Udemy courses can be found here.

3. Biohazard

For those that do not know this about me, I love the Resident Evil games and Biohazard does a phenomenal job capturing the feel of playing a RE game while hacking.

It is one of the more “video game” like rooms in both name and execution. You are tasked to collect flags and discovered hidden files, folders, pages, keys, images, and anything else scatted on the box to complete this room. It is simply a blast to play.

It can be difficult and at times I would get stuck and get a bit frustrated, but that emulated the feel of the RE games so much that I had to smile. Come prepared to think outside the box and don’t forget about that ever important source code to get by.

Not beginner friendly and it is one of the paid sub rooms, but if you haven’t played this room and love the Resident Evil franchise then I highly recommend this room.

Even if you do not play the Resident Evil games I still recommend this room. It is nothing but a crazy, fun puzzle.

2. Mr. Robot

This room is simply charming and fun to play with. Similar to Vulnversity it comes with a video guide by Darkstar to help hold your hand and provide though process and techniques used to help get through the room.

This room is marked as medium difficulty, but I would say it is one of the best rooms to transition someone that has been doing easy rooms and wants to step their game up and try the medium difficulty rooms.

If you are looking for a fun room to step up your game and have fun. I cannot recommend Mr. Robot enough. I was smiling and having such a blast hacking this box. It is easily one of the best TryHackMe has to offer.

1. Internal

My absolute favorite TryHackMe room is Internal, created by Joe Helle aka TheMayor. I love rooms that are more geared towards real world challenges and are exactly like what a penetration tester would see in the wild. This room was also designed to help prepare you for the eLearnsecurity eCPPT.

Just like in a real penetration test you are given a scope of work and are encouraged to create a report. Once you have completed reading the briefing and start the machine you need to obtain a user.txt flag and root.txt flag.

This room is rather difficult and not for beginners. It is a fantastic room to see where your skills are at and what needs improvement. Do not use a guide for this room. Internal is a room that if you can complete without help can really demonstrate to yourself that you have a good skill set when it comes to penetration testing.

TheMayor truly knocked it out of the park creating this room and even though I have completed it I will often come back to again and again just like one of my favorite video games. The amount of detail put into this room is excellent and I cannot recommend it enough to put your skills to the test.

In Conclusion: I hope this blog has provided some insight for those looking for suggestions for rooms on TryHackMe. TryHackMe has been a huge part in my growth as a Penetration Tester. The overwall number of rooms is huge and it can be a bit much to find the next room to do and I hope this helps someone!

If it does, feel free to send me a message on Twitter and let me know!