4 ms·
Risky. How can you distinguish between an intentionally set script and an attack? Why can't HTML be composed client-side using proper, contextual APIs instead
by alanfranz 5y ago
Risky. How can you distinguish between an intentionally set script and an attack?
Why can't HTML be composed client-side using proper, contextual APIs instead of "sanitizing" it afterwards? It won't work. It reminds me of PHP magic quotes - they didn't work.
We'd still need a sanitizer for URLs, of course, those are one of the pesky parts of the web specs.
- wccrawford 5y agoBecause far, far too many web apps need to display user-entered data, and it needs to be sanitized. When markdown is converted to HTML, as it is on this form, it still should be sanitized afterwards to deal with any vulnerabilities that were discovered after the user entered the data, even years later.
- alanfranz 5y ago"and it needs to be sanitized..." clarify your point. If I need to display user-controlled data, I can use a proper API - e.g. var x = document.createElement(); x.textContent = "<script></script>". You can put anything inside textContent. It works because it is contextual; you're creating an element and telling the browser what to do with it (display as text). If you needed better formatting, you would compose the various html elements, you would NOT use innerHTML. DOMPurify performs a string->string conversion, so it's got no context information. I don't understand how this can work. It didn't work for PHP magic quotes. It doesn't work for SQL queries. Why can and should it work for HTML? Remember that "work" implies not just "safe". It implies "it must show what the user wanted to see". Otherwise var sanitize = function(input){ return "<p>";} Would "just work" perfectly.
- wccrawford 5y agoThe output from a markdown to HTML converter is not text content. It's HTML. And it needs to be sanitized before it is added to the DOM. That's just a quick example. There are plenty of other conversions of user data that can't simply be displayed as plain text and need to be converted to HTML. That conversion doesn't always happen in the browser. Sometimes it's actually just straight HTML that needs to be displayed, but because it came from a user, it needs to be sanitized.
- alanfranz 5y agoI'm taking a better look at the sanitizer API before going on with this discussion. But, pardon me, the proper way to render markdown in the browser would be to let the markdown converter output a node or element. The markdown converter, when doing the conversion, knows what to do, which part of markdown must be converted to what HTML element, and what should be inserted as textContent. So I would imagine that when the markdown parser encounters *** This is a section writes something like: var el = document.createElement("h3") el.textContent = ... so an element is returned by the parser at the end, not a string. "Sanitizing" a string afterwards will either yield a safe (but possibly wrong) result, or a correct (but possible unsafe) result. You cannot decide what is safe if you don't have context. Unless "safe" means something like "nothing that looks like a script". What then if the markdown converter decides that it needs js for some feature?
- nightpool 5y agoWell, it's a good thing we're not talking about DOMPurify, because the spec we're talking about (the Sanitizer API), has lots of context information and does not provide a string -> string API: https://wicg.github.io/sanitizer-api/#strings https://wicg.github.io/sanitizer-api/#strings This API is simply a DOM-based whitelist for preventing script execution coupled with a contextual parser. No more, no less. It doesn't solve every problem with accepting untrusted HTML, sure, but it's good enough for a wide variety of use-cases (One example that comes up frequently is embedded markdown, another good example is a mail client—both situations where formatted, user-controlled data is important). The benefit of doing this client-side instead of server-side is that you can stay up to date with any changes that the client may make to how it's processing HTML that may have security implications. (The downsides, of course, are those associated with any thick-client/thin-server API design—more logic on the front-end means more logic to reimplement for different consumers)
- alanfranz 5y agoThanks for the link. I'm taking a better look at the sanitizer API; I was probably misled by the dompurify references and examples.