This looks great, if anything I think it's a shame it's not implemented using Web-Components, as they would be a perfect fit here for several reasons: intuitive, ease of use and maybe would even solve some security concerns.
If you’ve got a way to add node packages to your frontend then it is pretty straightforward. If not, using unpkg (https://unpkg.com/) in a script tag should work.
Happy to help you figure it out! Post in the discussion board on GitHub or email me (address on the website).
As long as a user can only run the code they (or the page author) has entered by themself, I don't see an issue. It gets more problematic if you allow users to store modified cells and link to them. Then a malicious user could write a cell amd trick another user into executing it.
What's the worst that could happen with an `<iframe sandbox="allow-scripts">` on your page (where the iframe will be treated as if it's from a different origin to the current page)? https://codepen.io/ runs custom user JavaScript, HTML and CSS for example via iframes.
Like CSP, iframes' sandbox attribute was conceived for an environment where it only works as part of a defense-in-depth strategy. It had to be; iframe is not a completely new element—consider what things looked like the day after the first browser to support the sandbox attribute was released: you had some X% of users who would be protected by it, and some Y% who would not, where Y >> X, and the set of people belonging to Y weren't "wrong" for belonging to that set—an author expecting sandbox to be the first, last, and only line of defense against malicious code is the one in the wrong. (Same with CSP.)
That doesn't change the fundamental character of sandbox being one part of a defense-in-depth strategy instead of being the first-last-and-only line of defense. When you begin using and relying on a security-related feature in a way it was never designed to be used, then you are playing with fire and arguably already compromised. Browser vendors can change their implementation at any time on the basis that newer releases still satisfy the intent.
Example: what approach are you using in your hypothetical to actually get the cell contents into the iframe?
Most of the evolution of web dev can be described as people pushing the boundaries of what browsers were meant to do until standards caught up. I think iframes for running untrusted content is very standard now (https://caniuse.com/iframe-sandbox) with a lot of well supported safe guards built-in like treating the iframe as its own origin.
Obviously defense-in-depth is a good idea and you should be careful when setting up iframes, but if there's a good chance `iframe sandbox` is going to break in later browser releases, there's a lot of stuff you couldn't do anymore. Even with CSP, it would only reduce but not eliminate what an attacker could do.
Really cool project! The API call functionality could be a good feature for docs, feels cleaner showing the sample response there instead of a dropdown.
I could not see any cell because I have JS disabled by default. blog-cells's readme addresses this:
> Using pre tags instead of script tags
> Script tags are great for defining notebook cells since they can hold pretty much any code without escaping. However, they are invisible by default, meaning that readers won't see anything until blog-cells loads. You can get around this by using <pre class="notebook-cell"> tags instead, however reserved HTML characters should be escaped using HTML entities.
I was pleasantly surprised to see this. I know it's a bit less convenient to type because of the entities, but I believe this is the way to go and this should be the main, advertised, method. Progressive enhancement. Keep your content as accessible as possible :-)
Now, I do think the result blocks would be better statically rendered if it's going to yield the same result each time they are run. The code runs once, at generation time, and the page is totally readable without JS. It indeed requires a generation step, but I think it's worth it, and blogs usually already have one.
I think Emacs has something like this with Org mode.
Which stops you from having to type out all those entities.
Once fully supported, you could even put this behind a media query (`@media (scripting: none)`) so you don't have to change the display with JavaScript after load.