npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

be-hashing-out

v0.0.2

Published

Elevate the trust level of HTML Fragments.

Downloads

9

Readme

be-hashing-out

Elevate the trust level of HTML Fragments.

The catch-22 of web development

Enabling unfettered JavaScript unintentionally in the browser can be dangerous, as it allows XSS attacks. Therefore, (in addition to performance and accessibility reasons), use less JavaScript, more HTML. However, if the HTML contains any explicit JavaScript in the event handlers, you're back to square one since the browser won't support you with nonce/hash, and script tags can't identify where in the DOM it is. So.... just give up and write the whole thing in JavaScript.

be-hashing-out can't help but long for the the brevity and sorcery on display here:

<form oninput="result.value=parseInt(a.value)+parseInt(b.value)">
     <input type=range id=a name=a value=50>
    +<input type=number id=b name=b value=25>
    =<output name=result for="a b"></output>
</form>

This example was also formerly shared with MDN, but MDN abandoned simplicity for seemingly nonce-sensical security reasons (perhaps I'm wrong, thinking this out, which is what this repo is currently).

Due to a lack of -- I'm not sure what -- the platform engineers have apparently failed to find a way to support brevity like this, even for trusted content coming from the host -- i.e. most "minimal" security measures throw the baby out with the bathwater, blocking our ability to do this (sigh). How could they have supported it? I think by allowing the nonce / hash attribute to apply to the parent element that contains inline scripts. Maybe that was looked at and found problematic, who knows? All I know is it is deeply unfortunate, and it appears to be resulting in solutions adopting makeshift handler syntax that is probably just as vulnerable to similar attacks as the native inline handlers are, only reduced by lack of widespread adoption. And not solving this problem appears to me to driving a stake through the idea of progressive enhancement.

Security concerns - Nonce in userland?

Step 1

<fetch-for be-hashing-out
href=https://cors-anywhere.herokuapp.com/https://www.theonion.com/ 
as=html shadow=open ></fetch-for>

What the be-hashing-out enhancement does: Since the value of the be-hashing-out attribute is empty, it emits a console.error with the expected SubtleCrypto.digest value, based on the attribute values (excluding the be-hashing-out attribute itself).

The console looks like:

Suggested markup:

<script type=module>
    import {register} from 'be-hashing-out/register.js';
    register('d61df4e4896765173a31dd0685866f0106c9b2b803f00096140d46e2e0dadc4f');
</script>

Suggested Attr: be-hashing-out="d61df4e4896765173a31dd0685866f0106c9b2b803f00096140d46e2e0dadc4f"

Step 2

Based on what is seen in the console, update the markup:

<script type=module>
    import {register} from 'be-hashing-out/register.js';
    register('d61df4e4896765173a31dd0685866f0106c9b2b803f00096140d46e2e0dadc4f');
</script>

<fetch-for be-hashing-out=d61df4e4896765173a31dd0685866f0106c9b2b803f00096140d46e2e0dadc4f
href=https://cors-anywhere.herokuapp.com/https://www.theonion.com/ 
as=html shadow=open ></fetch-for>

What be-hashing-out does with the above markup, now that it contains a non trivial be-hashing-out value:

  1. Forms a string from the attributes other than be-hashing-out of the element it adorns just like before.
  2. Calculates the digest just like before.
  3. Verifies that the value was registered, and the value matches the value of the be-hashing-out attribute.
  4. If everything is in order, sets properties:
    1. oFetchFor.beEnhanced.beHashingOut.resolved to true.
    2. oFetchFor.beEnhanced.beHashingOut.rejected to false.
  5. If the values don't match, or the value isn't registered, sets properties:
    1. oFetchFor.beEnhanced.beHashingOut.rejected to true.
    2. oFetchFor.beEnhanced.beHashingOut.resolved to false.
  6. If either case, two events with types "resolved" and "rejected" are dispatched.

Who cares?

This enhancement doesn't do much by itself. It is quietly providing information that it thinks will be useful to others. And "who" are those others that would find this information useful?

At least two third parties would find it useful for now.

  1. Custom Elements that support attributes that could allow for XSS attacks from untrusted third-party (or user supplied) HTML
  2. Custom Enhancements that similarly support such attributes.

So what these custom elements / enhancements can do is:

  1. Attach this be-hashing-out enhancement (if not already attached -- which the be-enhanced functionality already accounts for):
const {emc} = await import('be-hashing-out/emc.js');
const beHashingOut = oFetchFor.beEnhanced.whenResolved(emc);
let everyIsOkay = false;
if(beHashingOut.resolved){
    //for  custom elements do this
    if(beHashingOut.confirm(FetchFor.observedAttributes)){
        everyIsOkay = true;
    }
    //for custom enhancements to this
    if(beHashingOut.confirm(/** tbd **/)){
        everyIsOkay = true;
    }
}

Viewing Locally

Any web server that serves static files will do but...

  1. Install git.
  2. Fork/clone this repo.
  3. Install node.
  4. Open command window to folder where you cloned this repo.
  5. npm install

  6. npm run serve

  7. Open http://localhost:3030/demo in a modern browser.

Importing in ES Modules:

import 'be-hashing-out/be-hashing-out.js';

Using from CDN:

<script type=module crossorigin=anonymous>
    import 'https://esm.run/be-hashing-out';
</script>