Skip to content

Commit 8ba2b1c

Browse files
committed
use named export for future-proofing
1 parent ec0d8b1 commit 8ba2b1c

File tree

2 files changed

+30
-30
lines changed

2 files changed

+30
-30
lines changed

README.md

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,30 @@
22

33
Like `JSON.stringify`, but handles
44

5-
* cyclical references (`obj.self = obj`)
6-
* repeated references (`[value, value]`)
7-
* `undefined`, `Infinity`, `NaN`, `-0`
8-
* regular expressions
9-
* dates
10-
* `Map` and `Set`
5+
- cyclical references (`obj.self = obj`)
6+
- repeated references (`[value, value]`)
7+
- `undefined`, `Infinity`, `NaN`, `-0`
8+
- regular expressions
9+
- dates
10+
- `Map` and `Set`
1111

1212
Try it out on [runkit.com](https://npm.runkit.com/devalue).
1313

1414
## Goals:
1515

16-
* Performance
17-
* Security (see [XSS mitigation](#xss-mitigation))
18-
* Compact output
19-
16+
- Performance
17+
- Security (see [XSS mitigation](#xss-mitigation))
18+
- Compact output
2019

2120
## Non-goals:
2221

23-
* Human-readable output
24-
* Stringifying functions or non-POJOs
25-
22+
- Human-readable output
23+
- Stringifying functions or non-POJOs
2624

2725
## Usage
2826

2927
```js
30-
import devalue from 'devalue';
28+
import { devalue } from 'devalue';
3129

3230
let obj = { a: 1, b: 2 };
3331
obj.c = 3;
@@ -40,7 +38,6 @@ devalue(obj); // '(function(a){a.a=1;a.b=2;a.c=3;a.self=a;return a}({}))'
4038

4139
If `devalue` encounters a function or a non-POJO, it will throw an error.
4240

43-
4441
## XSS mitigation
4542

4643
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:
@@ -62,7 +59,10 @@ Which would result in this:
6259
```html
6360
<script>
6461
// NEVER DO THIS
65-
var preloaded = {"userinput":"</script><script src='https://evil.com/mwahaha.js'>"};
62+
var preloaded = {"userinput":"
63+
</script>
64+
<script src="https://evil.com/mwahaha.js">
65+
"};
6666
</script>
6767
```
6868
@@ -77,43 +77,43 @@ const template = `
7777
7878
```html
7979
<script>
80-
var preloaded = {userinput:"\\u003C\\u002Fscript\\u003E\\u003Cscript src=\'https:\\u002F\\u002Fevil.com\\u002Fmwahaha.js\'\\u003E"};
80+
var preloaded = {
81+
userinput:
82+
"\\u003C\\u002Fscript\\u003E\\u003Cscript src='https:\\u002F\\u002Fevil.com\\u002Fmwahaha.js'\\u003E"
83+
};
8184
</script>
8285
```
8386
8487
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`:
8588
8689
```js
87-
const value = (0,eval)('(' + str + ')');
90+
const value = (0, eval)('(' + str + ')');
8891
```
8992
90-
9193
## Other security considerations
9294
9395
While `devalue` prevents the XSS vulnerability shown above, meaning you can use it to send data from server to client, **you should not send user data from client to server** using the same method. Since it has to be evaluated, an attacker that successfully submitted data that bypassed `devalue` would have access to your system.
9496
95-
When using `eval`, ensure that you call it *indirectly* so that the evaluated code doesn't have access to the surrounding scope:
97+
When using `eval`, ensure that you call it _indirectly_ so that the evaluated code doesn't have access to the surrounding scope:
9698
9799
```js
98100
{
99101
const sensitiveData = 'Setec Astronomy';
100102
eval('sendToEvilServer(sensitiveData)'); // pwned :(
101-
(0,eval)('sendToEvilServer(sensitiveData)'); // nice try, evildoer!
103+
(0, eval)('sendToEvilServer(sensitiveData)'); // nice try, evildoer!
102104
}
103105
```
104106
105107
Using `new Function(code)` is akin to using indirect eval.
106108
107-
108109
## See also
109110
110-
* [lave](https://github.com/jed/lave) by Jed Schmidt
111-
* [arson](https://github.com/benjamn/arson) by Ben Newman
112-
* [tosource](https://github.com/marcello3d/node-tosource) by Marcello Bastéa-Forte
113-
* [serialize-javascript](https://github.com/yahoo/serialize-javascript) by Eric Ferraiuolo
114-
* [jsesc](https://github.com/mathiasbynens/jsesc) by Mathias Bynens
115-
* [superjson](https://github.com/blitz-js/superjson) by Blitz
116-
111+
- [lave](https://github.com/jed/lave) by Jed Schmidt
112+
- [arson](https://github.com/benjamn/arson) by Ben Newman
113+
- [tosource](https://github.com/marcello3d/node-tosource) by Marcello Bastéa-Forte
114+
- [serialize-javascript](https://github.com/yahoo/serialize-javascript) by Eric Ferraiuolo
115+
- [jsesc](https://github.com/mathiasbynens/jsesc) by Mathias Bynens
116+
- [superjson](https://github.com/blitz-js/superjson) by Blitz
117117
118118
## License
119119

devalue.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const objectProtoOwnPropertyNames = Object.getOwnPropertyNames(Object.prototype)
2626
* Turn a value into the JavaScript that creates an equivalent value
2727
* @param {any} value
2828
*/
29-
export default function devalue(value) {
29+
export function devalue(value) {
3030
const counts = new Map();
3131

3232
/** @param {any} thing */

0 commit comments

Comments
 (0)