1 | /**
|
2 | * @license MIT
|
3 | * Copyright (c) 2016 Craig Monro (cmroanirgo)
|
4 | **/
|
5 |
|
6 |
|
7 | /*
|
8 | Lacking knowledge of a good, but forgiving JSON parser, this hacklet was created.
|
9 | In short, I want to use JS Objects, but without it being strict JSON.
|
10 |
|
11 | What is no good about the std JSON:
|
12 | - trailing commas definitely break it
|
13 | - How annoying is that????
|
14 | - comments can break it
|
15 | - How daft is that????
|
16 | - the *key* MUST be in quotes. eg "key":"value"
|
17 | - How daft is that????
|
18 |
|
19 | In short, anything that acceptable to *real* JS object should be acceptable here. I declare that this *should* be allowed:
|
20 | key: "A string" + "another string"
|
21 | key: (new Date()) + " Some Date"
|
22 | key: (function() { return "green eggs and ham";})() <-- Although I think it OK, the parser disallows this use
|
23 |
|
24 | This parser does 1 thing: look for a few keywords that can be unsafe: notably 'eval' & function ()
|
25 | it's assumed that in context of a CMS, then everything else is acceptable. That is, the following are ok:
|
26 | - <script>
|
27 | - JSON.parse ....which is inherently safe anyway ;)
|
28 |
|
29 | However, things may change to cause this to be 'locked' down more.
|
30 | */
|
31 |
|
32 | var re_baddies = /(?:\beval\s*\(|\bjavascript\:|\bfunction\s+\w+\s*\(|\bfunction\s*\()/
|
33 | // \beval\s*\( == search for 'eval(', 'eval ('
|
34 | // \bjavascript:\( == search for 'javascript:'
|
35 | // \bfunction\s*\w*\( == search for 'function(', 'function word_1 (', etc'
|
36 |
|
37 | function _parse(str) {
|
38 | if (re_baddies.test(str))
|
39 | throw new SyntaxError('Bad syntax. Probable attempt at injecting javascript');
|
40 | return eval("(function(){return " + str + ";})()");
|
41 | }
|
42 |
|
43 |
|
44 | module.exports = {
|
45 | parse: _parse,
|
46 | };
|
47 |
|
48 |
|
49 | /* Here are some tests: (also look in tests). Note: this is ALL malformed & won't eval, for other reasons
|
50 |
|
51 | { evil1:eval (harry),
|
52 | evel2: eval(harry
|
53 | notevil2_eval(asd
|
54 | notevil3:eval_(monkey
|
55 | notevil4:eval$(asd
|
56 | js_evil1:javascript:alert(
|
57 | fn_notevil1:func()
|
58 | function:fn_notevil2
|
59 | fn_evil1:function() { }
|
60 | fn_evil2: function named123 (
|
61 | fn_evil3: function _nam123(
|
62 | fn_notevil3: function _nam123.dotted (
|
63 | fn_notevil4: function_nam123 (
|
64 |
|
65 |
|
66 |
|
67 | */
|
68 |
|