Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make infer.js work when eval is forbidden #385

Closed
gfwilliams opened this issue Sep 8, 2014 · 7 comments
Closed

make infer.js work when eval is forbidden #385

gfwilliams opened this issue Sep 8, 2014 · 7 comments

Comments

@gfwilliams
Copy link

Sadly this is a problem because Google Chrome Web Apps don't allow eval or Function.

There's a thread on this for acorn, and a script has just been contributed which fixes it for that.

Once that is applied, you're left with another failure which is from this code in infer.js which uses Function.apply:

  var constraint = exports.constraint = function(props, methods) {
    var body = "this.init();";
    props = props ? props.split(", ") : [];
    for (var i = 0; i < props.length; ++i)
      body += "this." + props[i] + " = " + props[i] + ";";
    var ctor = Function.apply(null, props.concat([body]));
    ctor.prototype = Object.create(Constraint.prototype);
    for (var m in methods) if (methods.hasOwnProperty(m)) ctor.prototype[m] = methods[m];
    return ctor;
  };

I've come up with this, which seems to work - however looking more closely at what's being done above I think it's probably wrong, so I'd really appreciate any input.

If it's ok I'd be happy to issue a pull request (however I assume that the original implementation was created for a good reason :) ).

  var constraint = exports.constraint = function(props, methods) {
    props = props ? props.split(", ") : [];
    var ctor = function() {
      this.init();
      for (var i = 0; i < props.length; ++i)
        this[props[i]] = arguments[i];
    };
    ctor.prototype = Object.create(Constraint.prototype);
    for (var m in methods) if (methods.hasOwnProperty(m)) ctor.prototype[m] = methods[m];
    return ctor;
  };
@marijnh
Copy link
Member

marijnh commented Sep 26, 2014

There's about a 5% performance penalty for using the dynamic implementation, since Tern creates a lot of constraints during analysis.

For some insane reason, it does not appear to be possible anymore to feature-detect content security policies (there was a document.securityPolicy object once in Chrome and in the spec, but it's been removed and I haven't been able to find any discussion explaining why).

Would triggering a security exception once, at the start of the program, catching it, and falling back to the slower method in that case be an okay solution to you? CSP exceptions can be 'reported', though I'm not entirely sure what that means and how much of a problem that is in Chrome Apps. They always get logged to the console, in any case, which is already awkward.

@marijnh
Copy link
Member

marijnh commented Sep 26, 2014

(I've also sent an email to public-webappsec@w3.org asking why there's no sane way to detect this anymore.)

@gfwilliams
Copy link
Author

Thanks - Yes, that's pretty frustrating... All I can think to do is to search for whether you're in a Chrome Web App or not, but that's probably worse than the 'try it and see' approach.

I'd be amazingly happy with any solution that works - thanks for having a look at this!

@mamacdon
Copy link

Hey, so I'm having to patch this to make Tern work in our Chrome app. I could submit a PR while I'm at it.

Is a simple try..catch fallback good enough, or are you expecting a shell script that generates a CSP-safe variant of infer.js, like Acorn does?

marijnh added a commit that referenced this issue Jun 12, 2015
Make definitions themselves a bunch more verbose.

Issue #385
@marijnh
Copy link
Member

marijnh commented Jun 12, 2015

Attached patch removes the use of new Function entirely. I'm still pissed that Chrome is breaking this feature of the language, but so it goes.

@marijnh marijnh closed this as completed Jun 12, 2015
@mamacdon
Copy link

Thanks for the fix.

@gfwilliams
Copy link
Author

Thanks! It is frustrating about Chrome - I'm not convinced it makes anything more secure either (which I assume was their rationale), as you could just write a JS interpreter in JS and still execute arbitrary code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants