I have problem. Server generate html code and returns to me, with script tags, i needed render this into my React component. I must render the html code (like dangerouslySetInnerHTML), and run script tags. You do not know the solution? Sorry for my english.
You can render the script tags from componentWillMount or componentDidMount, but not dangerouslySetInnerHTML for security purposes. You could easily strip out <script> tags with regular expressions and run that from one of the said methods.
Related
My project has admin panel and main page. On admin panel I can create posts using HTML editor (VueEditor in this example) post that in data base looks like this:
<p>Here is some test text from VueEditor</p>
Then, I want to parse it one the main page, but, of course, without <p> tag, so I use this:
<p v-html='item.plot'></p>
And here is a problem, IDE tells:
ESLint: 'v-html' directive can lead to XSS attack.(vue/no-v-html)
Is this really that dangerous? Should I parse it some other way?
Yes it is really that dangerous.
Consider what happens when I create the post.
Hi I'm Dave this is my <script>alert('pwned,' + document.cookie)</script> post!
I can now run arbitrary JS code on your website and steal login info for every user you serve this code too.
I'm not super familiar with vue in particular but most frameworks have an easy way to output sanitized html. I think this is {{ itme.plot }} in vue. This will not render an actual (or any other tag) but an escaped version <script> which the browser will not interpret as actual code.
There are a million other way to do XSS if you let me inject my own HTML in your website.
Long story short I have strings that contain HTML which are downloaded before a production build from a secure server. The framework we're using is React with Gatsby and typically you would just do the following:
<div dangerouslySetInnerHTML={{__html: '<p>My Stuff</p>'}}></div>
Which works fine, the main problem is for SEO purposes we want the html to be compiled into html rather than being rendered with Javascript.
Seeing as it's already HTML is there a way I can disable the protection inside react so these strings aren't escaped by default and become regular HTML in the production build?
Not practically, no. It's important to distinguish a <div> in a .jsx file from a <div> in html. If you look at the compiled output of the jsx, it will reveal what's really going on. If you transpile a react component containing <div>Hello world</div>, you'll get a function call along the lines of _react.createElement("div", null, "Hello world"). Anything that is put into the body of the div will also be inserted into it as JSX elements. The dangerouslySetInnerHtml prop is there to tell React that the value is actual html that you trust. However, even if there were an option other than dangerouslySetInnerHtml, I don't believe it would solve your problem as anything inside your react is going to have to wait for client side rendering.
Now, I'm no SEO expert, but if it's crucial to have content on the page before you render it, you may be able to send in the original html in a hidden element. If your original markup has <div id="app">Some seo stuff</div>, React will replace the content of the div when it renders it.
I think what you need is SSR; React allows this feature
You could install a server adapter (maybe expressjs) and use it to render a first screen (which is most likely SEO related) and once the client side is ready to render, it would hydrate the pages. Since you have the HTML gotten from a server, I think this is best route to go
var stringToHTML = function(htmlContent) {
var dom = document.getElementById('integrationMessage');
dom.innerHTML = htmlContent;
return dom;
};
stringToHTML(res.data.message);
<div id = "integrationMessage"></div>
I have a piece of code that server sends to react component and this piece of code is set as a component property. This code includes a div tag and a script tag inside it. I need to execute and run this code in React component. Dangerously Set innerHTML doesn't work for me - js code isn't running in this case. Are there any variants to make this work?
Thanks in advance.
You can still use eval() for this.
But you need to be aware of the security implications it has. Especially you need to make sure you are using secure connections to your server and don't publish malicious code to your users.
React does not recommends use innerHTML. But if you very need to, you can use
function createMarkup() { return {__html: 'First ยท Second'}; };
<div dangerouslySetInnerHTML={createMarkup()} />
More info https://facebook.github.io/react/tips/dangerously-set-inner-html.html
I have to create a text module in React, i'm using JSX too; I will receive the data from a JSON file. For example:
{ "text-data":
"text": "<small> Hello world </small>"
}
I tried to do something like this in my module:
<p> {this.props.textData.text}</p>
When I try to render this in my JSX file, it show as plain text with the tags included. I've been researching and I found that I could use this function "Dangerously Set innerHTML" but it's not recommended because it can cause an XSS attack. I read here other answers about this, that say that using HTML entities work; but I can't make that work for now.
The dangerouslySetInnerHTML prop is there for cases like this. In effect, you're saying that you completely trust the html that you're outputting and that it's valid html. You would not want to use it for user input (unless absolutely necessary and thoroughly validated).
See the React documentation for more information. There is also a previous similar StackOverflow question.
I have observed that, while writing JS in script tags into the template will run the script, inserting them into the template using a Handlebars expression will prevent it from running.
I have tried writing this into my component:
test: Ember.String.htmlSafe("<script>console.log('Hello World')</script>")
And in my template:
{{test}}
This will insert it into the DOM, but will not run the code. I thought it was because HTMLBars did not allow script tags in the template, but just writing
<script>console.log('Hello World')</script>
into the template itself will run the JS within.
Can somebody tell me if there is a way to achieve this, or provide an explanation as to why this happens? Thanks in advance.
If you work with javascript string you can use extra {{{ }}} to display them properly. Safe template output with:
{{{test}}}
That will do the job. Have a look at this blog post
http://www.kaspertidemann.com/html-safe-strings-in-handlebars/
There is no need to do that. You can either run JavaScript code from your Component or have <script> tag in your template (like you've described in your question).