{"action":"created","issue":{"url":"https://api.github.com/repos/balderdashy/sails/issues/3522","repository_url":"https://api.github.com/repos/balderdashy/sails","labels_url":"https://api.github.com/repos/balderdashy/sails/issues/3522/labels{/name}","comments_url":"https://api.github.com/repos/balderdashy/sails/issues/3522/comments","events_url":"https://api.github.com/repos/balderdashy/sails/issues/3522/events","html_url":"https://github.com/balderdashy/sails/pull/3522","id":128278890,"number":3522,"title":"[Proposal] Handle untrusted bootstrap data in EJS","user":{"login":"irlnathan","id":1598650,"avatar_url":"https://avatars.githubusercontent.com/u/1598650?v=3","gravatar_id":"","url":"https://api.github.com/users/irlnathan","html_url":"https://github.com/irlnathan","followers_url":"https://api.github.com/users/irlnathan/followers","following_url":"https://api.github.com/users/irlnathan/following{/other_user}","gists_url":"https://api.github.com/users/irlnathan/gists{/gist_id}","starred_url":"https://api.github.com/users/irlnathan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/irlnathan/subscriptions","organizations_url":"https://api.github.com/users/irlnathan/orgs","repos_url":"https://api.github.com/users/irlnathan/repos","events_url":"https://api.github.com/users/irlnathan/events{/privacy}","received_events_url":"https://api.github.com/users/irlnathan/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/balderdashy/sails/labels/proposal","name":"proposal","color":"207de5"}],"state":"closed","locked":false,"assignee":{"login":"mikermcneil","id":618009,"avatar_url":"https://avatars.githubusercontent.com/u/618009?v=3","gravatar_id":"","url":"https://api.github.com/users/mikermcneil","html_url":"https://github.com/mikermcneil","followers_url":"https://api.github.com/users/mikermcneil/followers","following_url":"https://api.github.com/users/mikermcneil/following{/other_user}","gists_url":"https://api.github.com/users/mikermcneil/gists{/gist_id}","starred_url":"https://api.github.com/users/mikermcneil/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mikermcneil/subscriptions","organizations_url":"https://api.github.com/users/mikermcneil/orgs","repos_url":"https://api.github.com/users/mikermcneil/repos","events_url":"https://api.github.com/users/mikermcneil/events{/privacy}","received_events_url":"https://api.github.com/users/mikermcneil/received_events","type":"User","site_admin":false},"assignees":[{"login":"mikermcneil","id":618009,"avatar_url":"https://avatars.githubusercontent.com/u/618009?v=3","gravatar_id":"","url":"https://api.github.com/users/mikermcneil","html_url":"https://github.com/mikermcneil","followers_url":"https://api.github.com/users/mikermcneil/followers","following_url":"https://api.github.com/users/mikermcneil/following{/other_user}","gists_url":"https://api.github.com/users/mikermcneil/gists{/gist_id}","starred_url":"https://api.github.com/users/mikermcneil/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mikermcneil/subscriptions","organizations_url":"https://api.github.com/users/mikermcneil/orgs","repos_url":"https://api.github.com/users/mikermcneil/repos","events_url":"https://api.github.com/users/mikermcneil/events{/privacy}","received_events_url":"https://api.github.com/users/mikermcneil/received_events","type":"User","site_admin":false}],"milestone":null,"comments":11,"created_at":"2016-01-23T00:48:53Z","updated_at":"2016-09-23T00:24:01Z","closed_at":"2016-03-30T23:06:29Z","pull_request":{"url":"https://api.github.com/repos/balderdashy/sails/pulls/3522","html_url":"https://github.com/balderdashy/sails/pull/3522","diff_url":"https://github.com/balderdashy/sails/pull/3522.diff","patch_url":"https://github.com/balderdashy/sails/pull/3522.patch"},"body":"# A Sails helper function to handle untrusted bootstrap data in EJS.\r\n\r\n```\r\n<script type=\"text/javascript\">\r\n  window.SAILS_LOCALS = {\r\n    _csrf: <%- sails.htmlInject('_csrf') %>,\r\n\r\n    me: <%- sails.htmlInject('me') %>\r\n  };\r\n</script>\r\n```\r\n\r\nSo I need to access `me` from inside of an inline `<script>` tag on an HTML page (e.g. for bootstrapping data). This would replace any custom _recursive_ HTML escaping I currently have to do on the injected value (e.g. `<%- stringifyAndHtmlEscape(me) %>`), as well as a `typeof val==='undefined' check`.\r\n\r\n> I have the option of using the `<%= %> EJS tags`, which evaluates, escapes and injects anything between the tags or the `<%- %> EJS tags` which evaluates and injects anything between the tags as-is. I want to use `<%- %>` but then I’m responsible for protecting against potentially malicious data passed in `me`. \r\n\r\n## Proposed Solution\r\n\r\nThis...\r\n\r\n```\r\n<script type=\"text/javascript\">\r\n  window.SAILS_LOCALS = {\r\n    _csrf: <%- sails.htmlInject('_csrf') %>,\r\n\r\n    me: <%- sails.htmlInject('me') %>\r\n  };\r\n</script>\r\n```\r\n\r\n...generates this:\r\n\r\n```\r\n<script type=\"text/javascript\">\r\n  window.SAILS_LOCALS = {\r\n    _csrf: (function (escapedValue){\r\n      var unescaped = escapedValue;\r\n      // Unescape all strings in `escapedValue`.\r\n      // (recursively parse escapedValue if it is an array or dictionary)\r\n      // (also need to prevent endless circular recursion for circular objects)\r\n      return unescaped;\r\n    })('d8a831-d8a8381h1-adgadga3'),\r\n\r\n    me: (function (escapedValue){\r\n      var unescaped = escapedValue;\r\n      // Unescape all strings in `escapedValue`.\r\n      // (recursively parse escapedValue if it is an array or dictionary)\r\n      // (also need to prevent endless circular recursion for circular objects)\r\n      return unescaped;\r\n    })({\r\n      gravatarUrl: '&lt;/script&gt;',\r\n      admin: false\r\n    })\r\n  };\r\n</script>\r\n```\r\n\r\n...and if `me` is not defined:\r\n\r\n```\r\n<script type=\"text/javascript\">\r\n  window.SAILS_LOCALS = {\r\n    _csrf: (function (escapedValue){\r\n      var unescaped = escapedValue;\r\n      // Unescape all strings in `escapedValue`.\r\n      // (recursively parse escapedValue if it is an array or dictionary)\r\n      // (also need to prevent endless circular recursion for circular objects)\r\n      return unescaped;\r\n    })('d8a831-d8a8381h1-adgadga3'),\r\n\r\n    me: undefined\r\n  };\r\n</script>\r\n```"},"comment":{"url":"https://api.github.com/repos/balderdashy/sails/issues/comments/249066593","html_url":"https://github.com/balderdashy/sails/pull/3522#issuecomment-249066593","issue_url":"https://api.github.com/repos/balderdashy/sails/issues/3522","id":249066593,"user":{"login":"mikermcneil","id":618009,"avatar_url":"https://avatars.githubusercontent.com/u/618009?v=3","gravatar_id":"","url":"https://api.github.com/users/mikermcneil","html_url":"https://github.com/mikermcneil","followers_url":"https://api.github.com/users/mikermcneil/followers","following_url":"https://api.github.com/users/mikermcneil/following{/other_user}","gists_url":"https://api.github.com/users/mikermcneil/gists{/gist_id}","starred_url":"https://api.github.com/users/mikermcneil/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mikermcneil/subscriptions","organizations_url":"https://api.github.com/users/mikermcneil/orgs","repos_url":"https://api.github.com/users/mikermcneil/repos","events_url":"https://api.github.com/users/mikermcneil/events{/privacy}","received_events_url":"https://api.github.com/users/mikermcneil/received_events","type":"User","site_admin":false},"created_at":"2016-09-23T00:24:01Z","updated_at":"2016-09-23T00:24:01Z","body":"This is fully implemented as of https://github.com/balderdashy/sails/commit/ae5e042c1640b4b39d5148fb38a0664028931920"}}
{"actor":{"display_login":"mikermcneil"}}