4 ms·
You need escaping only when you're sending strings to a compiler (which is what you do when you do server-side rendering), and its a never ending source of bugs
by spion 9y ago
You need escaping only when you're sending strings to a compiler (which is what you do when you do server-side rendering), and its a never ending source of bugs. You basically need to re-implement the entire logic of a full blown parser for the target language to guarantee successful escaping.
E.g. see `mysql_real_for_real_this_time_escape_string` versus just supporting parameterized queries. Parameters don't need to be escaped; they will never be interpreted as SQL code.
This list is also fun: https://gist.github.com/JohannesHoppe/5612274 https://gist.github.com/JohannesHoppe/5612274 - will your framework escape implementation cover all of them? Are you sure?
If you serve a static html (no templates) + css + JS (pre-compiled JSX templates) client with all dynamic content being served as e.g. JSON, you're getting rid of a large number of attack vectors from the start.
You are down to a handful of attributes, of which only dangerouslySetInnerHTML is a React-originating attack vector because similarly to all other template languages it sends a string to a compiler. It should probably be a symbol, too, especially now that we have spread syntax for props. https://github.com/facebook/react/issues/10506 https://github.com/facebook/react/issues/10506 - until then, you can simply forbid spread syntax for props and/or dangerouslySetInnerHTML.
Any other HTML attributes that have a string-to-compiler behaviour remain a problem, regardless of whether you are using jquery or react or whatever. (e.g. href). Its sad but for some of them the only recourse we have is escaping. Still, thats a huge improvement over escaping everything.
- EGreg 9y agoExactly. You make a very good point. Passing PARAMETERS to a string based query or command should be done by reference whenever possible. The CALLER shouldn't be responsible for the escaping and interpolation. That is for the DRIVER or API or whatever. That just further proves my point. When you call SQL commands from PHP you should use PDO and parametrized queries always. Values should always be passed by reference. Same goes when you are outputting some HTML. You should have a hash of { attributeName: value } and it should be up to the HTML RENDERER - and not you - to escape the values every time. You've made another great point, which layers on top of my point, which is: 1) Use each language Y as it was intended 2) Escape everything automatically by passing values by reference to an API layer in language X So to sum up: Use HTML for structure, CSS for appearance, and JS for all dynamic behaviors. Keep your files separate! Do not allow embedding arbitrary CSS and JS in your HTML and so on. For MySQL use a MySQL driver API and pass values to it For HTML use an HTML renderer API and pass values to it For Javascript-accessible data embedded in HTML use a JSON function (easy) and pass values to it. For JSONP (old school) use JSON wrapped with some callback. Better: load actual JSON using XHR and CORS. Best: use iframes and postMessage to execute arbitrary methods in the other domain via an authorized session. And so on.