Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to implement XSS through deceptive React elements

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)05/31 Report--

This article introduces how to achieve XSS through deceptive React elements, the content is very detailed, interested friends can refer to, hope to be helpful to you.

Introduction to related roles

HackerOne is a platform for security response and vulnerability reward, with the slogan "start from scratch (build) and make security a top priority." The team that created HackerOne included several security engineers and penetration testers, so I was very excited to be able to find vulnerabilities on their website.

React is a popular JavaScript library for building user interfaces.

I am a developer for Trello (a team collaboration application) and am responsible for running Trello's vulnerability reward project on HackerOne. Occasionally, I try to find security problems in the applications I use.

Background

This problem was caused by another XSS vulnerability I previously targeted at HackerOne, a tentatively undisclosed report, and a CSP bypass vulnerability.

Send illegal JSON data

When I'm looking for security issues, I spend a lot of time trying to create "unexpected" situations. A website asked me to fill in my name, and I sent it some HTML. They asked me to fill in the URL, and I gave them a URL with a bunch of quotation marks, line feeds, empty characters, and so on. If you see what I mean.

While browsing the HackerOne website, I looked at some AJAX requests sent and noticed that some of them sent complex JSON objects as the body of the request, for example:

{state: "open", substate: "triaged", report_ids: [49652, 46916], reply_action: "change-state", reference: "http://danlec.com"}"

I try to send a similar request and set some fields to types that I don't think are valid. For example, send a value of string type danlec where the expected parameter type is a number. Or send an array where you should normally send a string type. For example:

{state: {"foo": "danlec", "bar": 42}, substate: 3.2 reportchildren: ["xyzzy", 46916], reply_action: [2, "change-state"], reference: {"a": 1, b: ["2"]}}

Unsurprisingly, these values are almost universally rejected or converted to values of the appropriate type (for example, {'foo':' bar'} may be converted to string type'{"foo" = > "bar"}').

However, in some places, the value of the error type is not rejected directly, but is returned from the server. That is, it seems that the value of the error type is stored and returned in the response of subsequent API calls.

I found two examples. One is a field called reference, which is used to classify reports. The other is a field called data, which is associated with the trigger condition.

Unfortunately, although this is absolutely strange, the values of these error types are actually safely rendered on the page. I can't immediately think of a way to take advantage of this behavior. I added it to the bug list with the potential for deep mining.

Almost give up

Over the next week, I kept retrying the bug. I tried several different values, and although I couldn't do anything bad, I did notice that some values were strangely rendered.

Typically, string values such as "foo" will be rendered as similar to

Foo

I noticed that when the value is changed to an array, such as ["foo", "bar"], it is rendered as

Foobar

Even more exciting is that when using objects such as {foo: "bar"}, foo is included in the react-id attribute of the span element at render time, such as

Bar

I'm sure I can have some impact on the final rendered DOM elements, but the code responsible for rendering does a good job of content purification (escaping illegal characters). I still can't use it to do anything bad.

I'm ready to submit this bug and define it as "it's a strange thing, probably a bug, but without any security concerns." But I decided to try one last time to see if I could find anything by stepping into the client code responsible for rendering the element.

Single-step debugging minified JS

After setting a breakpoint where the value of the error type is rendered, I start debugging all the code step by step to see if there is anything interesting that can be used for me. Most characters are compressed (in minified JS files, variable names are usually replaced with random individual characters), so it's not always clear what's going on, but when I see a value of the wrong type being passed to this function:

L.isValidElement = function (e) {var t =! (! e | |! e._isReactElement); return t}

I started to get excited. (this is the really interesting part of security research, you know you've found something bad, and now you just need to figure out how bad it can be.)

I have proved to myself that I can make e any JSON value I want to enter. So, without any skill, you can create an object and set its _ isReactElement value to true, which seems to tell the client that the object I created is a "valid element."

Once I add _ isReactElement, and a few other keys (_ store,type,props), the object I create will be rendered in a completely different way, which will eventually check the dangerouslySetInnerHTML property. Now there is a property that looks interesting to be manipulated.

Obviously, the attribute name is trying to warn me that it is dangerous to include the original HTML. But, of course, I have no qualms about adding the dangerouslySetInnerHTML attribute to the fake React element. Once this property is set, the render method renders the HTML fragment I passed in, allowing arbitrary HTML injection, XSS, and so on.

Vulnerability exploitation has been realized!

So. What actually happened here?

When I get XSS to work properly, I take a step back to find out what's actually going on. HackerOne uses React, and it turns out that React's createElement method has a parameter, and the expected value is a React node, which can be a string (for simple text content) or an array, or a React element.

Remember how I noticed that sometimes my input would be rendered as multiple span?

I tried to run some React methods from the console, and it was clear what actually happened:

> React.renderToString (React.createElement ("span", null, "abc")) "abc" > React.renderToString (React.createElement ("span", null, ["abc"])) "abc" > React.renderToString (React.createElement ("span", null, {foo: "bar"})) "bar"

In the client code of HackerOne, it is assumed that the value it passes is always a string, but I can make it pass the JSON object I deliberately constructed and make React think it is rendering an element by setting the correct properties.

DangerouslySetHTML is a special non-DOM attribute that provides the ability to insert the original HTML into an element, which is exactly what XSSer like me is looking for.

I used the full JSON object instead of the string expected by HackerOne, similar to

{_ isReactElement: true,_store: {}, type: "body", props: {dangerouslySetInnerHTML: {_ _ html: "Arbitrary HTMLalert ('No CSP Support: (') link"}

Render the JSON object on the console:

> React.renderToString (React.createElement ("span", null, {_ isReactElement: true,... })) "Arbitrary HTMLalert ('No CSP Support: (') link" on how to implement XSS through deceptive React elements is shared here. I hope the above content can be of some help and learn more knowledge. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Network Security

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report