davedawkins / Sutil

Lightweight front-end framework for F# / Fable. No dependencies.
https://sutil.dev
MIT License
285 stars 17 forks source link

Avoid eval #44

Closed AngelMunoz closed 2 years ago

AngelMunoz commented 2 years ago

https://github.com/davedawkins/Sutil/blob/804ea324ee6bfc24b8bd1d5b54cbe6099c09a070/src/Sutil/webcomponent.js#L70

I think this won't pass security considerations due to CSP I'd suggest avoid eval and try something different, the class used for the web component doesn't need to match the name with the name in the registry classes can be anonymous in Javascript

    let className = name.replace(/-/g, '');
    let ctorJs = `
        let ${className} = function() {
            let _ = Reflect.construct(HTMLElement,[], ${className});
            return init(_, attributes);
        };
        ${className}.observedAttributes = attributes;
        ${className};
    `;

could be translated to

let ctorJs = class {
  static get observedAttributes() { return attributes; } 
  attributeChangedCallback( name, oldVal, newVal ) {
        this[name] = newVal;
    }
  connectedCallback() {
        for (const key of attributes) {
            if (this.hasAttribute(key)) {
                this[key] = this.getAttribute(key);
            }
        }
    }
  disconnectedCallback () {
        this.sutilCallbacks.Dispose();
    }
} 

customElements.define(name, ctorJs);

If we're on a javascript file there's no need to avoid JS classes, if we're doing this inside F# then the func version would be preferred but even then eval should be avoided for security concerns

AngelMunoz commented 2 years ago

you can also grab some inspiration from this https://github.com/davedawkins/Sutil/pull/43/files#diff-469049174da5c0501dc98ae73a9c8a7b17aa9c7abead51ee31221916da6142cbR4-R75

which doesn't use eval at all and does the function approach which chould be translated to F# if we want to ditch the JS files

davedawkins commented 2 years ago

Eval removed - thanks for the help