3 ms·
Off the top of my head the way I would this: * On the back end request the third party code and then associate that code with a hash sequence. + On the backen
by austin-cheney 2y ago
Off the top of my head the way I would this:
* On the back end request the third party code and then associate that code with a hash sequence.
+ On the backend dynamically modify the html such that there is a div tag with an id whose value is the hash sequence. Also modify the html such that there is a script tag that requests the third party code from your domain. For tracking purposes you add the hash value to a data attribute on that script tag.
* On the back end modify that third party code such that all instances of document. and window. are replaced by document.getElementById(hash_value). and all query selectors begin with #hash_value.
* You would to replace .parentNode in the Element prototype with a custom property that checks for and drops escape from the providdd container.
Then send the html document to the browser. If the third party code breaks that is ok. The constraints should be communicated to the third party and it’s up to them to test their own code before sending it to your server. All you care about is that their code does not escape the dynamically provided container. Test this regularly on your side to look for security violations.
Also, this may not work, but it would be fun to experiment with.
- dawnerd 2y agoThat seems like it’s pretty fragile though. I’d be really worried about all the weird edge cases
- jitl 2y agoYou can easily escape this by traversing a DOM node’s parent pointer.
- austin-cheney 2y agoNot at all. So, yes, depending upon the implementation there is a parent pointer tree which binds node hierarchy. This is not really how the DOM works though and not what's exposed via API. Typically the nodes are objects in memory and point to each other via static relational reference. These references are exposed to the API, like: parentNode, nextSibling, childNodes. Under the hood deep in the binary might the parentNode make use of a parent pointer tree to map between the node instance in memory? Again, that depends upon the implementation and is entirely irrelevant to the executing JavaScript which is isolated from that layer.
- jitl 2y agoI mean "parent pointer" in a generic sense. There’s more parent direction pointers available in addition to parentNode: parentElement, ownerDocument, offsetParent. There’s just loads and loads of ways to navigate around the DOM. You can fire a custom event and watch as it bubbles out of the “sandbox” with `myEvent.currentTarget`. You could build a new script to eval bit-by-bit and then attach it with a <script> tag (can disable that with CSP though). I wouldn't trust security based on a deny-list approach, especially when it comes to an API surface area as complex as the DOM, where the platform can roll out new APIs before you can update your deny-list.
- chmod775 2y agoIn the context of this conversation, which is about running untrusted code, this has about a million holes. The only way DOM access can become secure is if either browsers add support for sandboxing in such a way, or you have your own sandbox, like OPs, and provide DOM modification APIs within it that go through rigorous validation before you pass anything on to the browser. Trying to sandbox with find/replace will never work (unless you replace the entire script with an empty string).
- austin-cheney 2y ago> this has about a million holes. Kind of. First of all, the DOM is a global artifact. Browsers do not provide any convention to isolate a section of the DOM tree except for iframes and document fragments and there are limitations to both. iframes are slow and not entirely isolated either. Document fragments are better for security as they are isolated from the document object, but they are designed to be worthless until appended to the document. Document fragments were only created to build multiple DOM trees in parallel without waiting to access the document object, because there is only one document object. These performance concerns are largely irrelevant now because the DOM, even with the extreme slowness of query selector strings, is insanely fast. Secondly, this is about running untrusted code. In applications outside the browser this is super scary. However, in the browser this happens just about everywhere all the time. Any JavaScript code that comes into a page not from a domain you own is untrusted. Go to any page and look at the network tab and its common just about everywhere. The only security safeguard to this, besides the browser's single origin policy, is that all security risks are directly transferred to the user in the browser because its not requested or touching the web server. With this context in mind talk of security holes is kind of ridiculous to the point of ignorance about how the browser works. As hacky as my suggest is, its still far more secure than how every commercial webpage normally operates.
- chmod775 2y ago> Kind of. This is JS code that will write "Hello!" to the body tag, bypassing protections that rely on find/replace: https://gist.githubusercontent.com/laino/8d2676f8fd6fe0de19d15b2e2bbc1134/raw/7eedbda1100ea0b5caaf3410602fa44bb0b3c5b3/hello.js https://gist.githubusercontent.com/laino/8d2676f8fd6fe0de19d... Another one that uses eval, which may be disabled by CSP on some pages: https://gist.githubusercontent.com/laino/316843234f5da5073bd39500b2ea493a/raw/1afcaccafaf37d2ee3f58c25a40ead7b881c6641/hello.js https://gist.githubusercontent.com/laino/316843234f5da5073bd... The point is that find/replace will never work with a dynamic language like JS. > First of all, the DOM is a global artifact. Browsers do not provide any convention to isolate a section of the DOM tree except for iframes and document fragments and there are limitations to both. There's also shadow DOM which allows you to encapsulate things on a page. > However, in the browser this happens just about everywhere all the time. And this whole exercise is about making that secure, which is what OPs sandbox can do for you. Code in such sandboxes can only interact with whatever you explicitly give them access to, which is called whitelisting, whereas your approach is trivially circumventable blacklisting (the code can do anything you don't explicitly prevent). If all you expose to code in a sandbox is your own DOM modification utilities that perform rigorous validation, then absent of any security holes, that's what the code running in the sandbox will be able to do. If you decide all it gets to do is create up to 10 div tags with a custom text and color, then that's it.