Skip to content

Commit

Permalink
Merge pull request #3663 from spicyj/san-md
Browse files Browse the repository at this point in the history
[docs] Use marked instead of Showdown and escape HTML
  • Loading branch information
sophiebits committed Apr 13, 2015
2 parents d8117d0 + 36aefcb commit be03fa7
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 1,322 deletions.
4 changes: 1 addition & 3 deletions docs/_js/examples/markdown.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
var MARKDOWN_COMPONENT = `
var converter = new Showdown.converter();
var MarkdownEditor = React.createClass({
getInitialState: function() {
return {value: 'Type some *markdown* here!'};
Expand All @@ -20,7 +18,7 @@ var MarkdownEditor = React.createClass({
<div
className="content"
dangerouslySetInnerHTML={{
__html: converter.makeHtml(this.state.value)
__html: marked(this.state.value, {sanitize: true})
}}
/>
</div>
Expand Down
1 change: 0 additions & 1 deletion docs/_layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
<script type="text/javascript" src="/react/js/react.js"></script>
<script type="text/javascript" src="/react/js/JSXTransformer.js"></script>
<script type="text/javascript" src="/react/js/live_editor.js"></script>
<script type="text/javascript" src="/react/js/showdown.js"></script>
</head>
<body>

Expand Down
20 changes: 9 additions & 11 deletions docs/docs/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ Note that we have passed some data from the parent `CommentList` component to th

Markdown is a simple way to format your text inline. For example, surrounding text with asterisks will make it emphasized.

First, add the third-party **Showdown** library to your application. This is a JavaScript library which takes Markdown text and converts it to raw HTML. This requires a script tag in your head (which we have already included in the React playground):
First, add the third-party library **marked** to your application. This is a JavaScript library which takes Markdown text and converts it to raw HTML. This requires a script tag in your head (which we have already included in the React playground):

```html{7}
<!-- index.html -->
Expand All @@ -221,41 +221,39 @@ First, add the third-party **Showdown** library to your application. This is a J
<script src="https://fb.me/react-{{site.react_version}}.js"></script>
<script src="https://fb.me/JSXTransformer-{{site.react_version}}.js"></script>
<script src="https://code.jquery.com/jquery-1.10.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/0.3.1/showdown.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.2/marked.min.js"></script>
</head>
```

Next, let's convert the comment text to Markdown and output it:

```javascript{2,10}
```javascript{9}
// tutorial6.js
var converter = new Showdown.converter();
var Comment = React.createClass({
render: function() {
return (
<div className="comment">
<h2 className="commentAuthor">
{this.props.author}
</h2>
{converter.makeHtml(this.props.children.toString())}
{marked(this.props.children.toString())}
</div>
);
}
});
```

All we're doing here is calling the Showdown library. We need to convert `this.props.children` from React's wrapped text to a raw string that Showdown will understand so we explicitly call `toString()`.
All we're doing here is calling the marked library. We need to convert `this.props.children` from React's wrapped text to a raw string that marked will understand so we explicitly call `toString()`.

But there's a problem! Our rendered comments look like this in the browser: "`<p>`This is `<em>`another`</em>` comment`</p>`". We want those tags to actually render as HTML.

That's React protecting you from an XSS attack. There's a way to get around it but the framework warns you not to use it:

```javascript{5,11}
```javascript{4,10}
// tutorial7.js
var converter = new Showdown.converter();
var Comment = React.createClass({
render: function() {
var rawMarkup = converter.makeHtml(this.props.children.toString());
var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
return (
<div className="comment">
<h2 className="commentAuthor">
Expand All @@ -268,9 +266,9 @@ var Comment = React.createClass({
});
```

This is a special API that intentionally makes it difficult to insert raw HTML, but for Showdown we'll take advantage of this backdoor.
This is a special API that intentionally makes it difficult to insert raw HTML, but for marked we'll take advantage of this backdoor.

**Remember:** by using this feature you're relying on Showdown to be secure.
**Remember:** by using this feature you're relying on marked to be secure. In this case, we pass `sanitize: true` which tells marked to escape any HTML markup in the source instead of passing it through unchanged.

### Hook up the data model

Expand Down
11 changes: 6 additions & 5 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,17 @@ id: home
<h3>A Component Using External Plugins</h3>
<p>
React is flexible and provides hooks that allow you to interface with
other libraries and frameworks. This example uses Showdown, an external
other libraries and frameworks. This example uses **marked**, an external
Markdown library, to convert the textarea's value in real-time.
</p>
<div id="markdownExample"></div>
</div>
</div>
<script type="text/javascript" src="js/examples/hello.js"></script>
<script type="text/javascript" src="js/examples/timer.js"></script>
<script type="text/javascript" src="js/examples/todo.js"></script>
<script type="text/javascript" src="js/examples/markdown.js"></script>
<script type="text/javascript" src="/react/js/marked.min.js"></script>
<script type="text/javascript" src="/react/js/examples/hello.js"></script>
<script type="text/javascript" src="/react/js/examples/timer.js"></script>
<script type="text/javascript" src="/react/js/examples/todo.js"></script>
<script type="text/javascript" src="/react/js/examples/markdown.js"></script>
</section>
<hr class="home-divider" />
<section class="home-bottom-section">
Expand Down
Loading

0 comments on commit be03fa7

Please sign in to comment.