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

fix autoescape for non-string values; fixes #835 #836

Merged
merged 6 commits into from
Sep 7, 2016

Conversation

devoidfury
Copy link
Contributor

@devoidfury devoidfury commented Sep 7, 2016

@devoidfury
Copy link
Contributor Author

Imo, a bugfix for the issue is release asap material (even if it's not this one). Maybe submit a CVE?

@SamyPesse @jlongster @vecmezoni @carljm @jbmoelker

if(autoescape && typeof val === 'string') {
val = lib.escape(val);
if(autoescape && !(val instanceof SafeString)) {
val = lib.escape(''+val);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

val.toString() will be clearer

@jbmoelker
Copy link
Collaborator

@devoidfury thanks for this! Looks solid. Could you update the CHANGELOG.md with the fix? For me that's all that's left before merging this PR.

I don't know if we need to submit a CVE. I understand the risk of this bug. But I don't know the protocol or procedure.

@carljm what's the procedure to release this? I've read MAINTENANCE.md, but I don't quite understand how the 2.x and 3.x branches are managed. Seeing the unreleased 2.x items I imagine we should release 2.5.0. Also I think @vecmezoni and I as 1 day old maintainers are able to create releases on GitHub, but are unable to publish a new version to npm.

@vecmezoni
Copy link
Collaborator

Probably would be better to publish 2.4.3 and 2.5.0 to fix vulnerability, so users with all the cases of package.json versioning ~ ^ will receive fix. Just need to check is there anything to bump a minor version or we might bump just patch (2.4.3)

@jbmoelker
Copy link
Collaborator

jbmoelker commented Sep 7, 2016

@vecmezoni well there are multiple unreleased features on 2.x, so that's why the minor bump. I agree that normally we'd merge this PR and release patch. But I'm not sure where to merge onto for that patch release. It's not master. But is it 2.x?

@vecmezoni
Copy link
Collaborator

vecmezoni commented Sep 7, 2016

We can make separate branch from 2.4.2 version, apply this patch and release 2.4.3. Then we can apply this patch to 2.x and decide to release or not to release 2.5. I've asked @carljm to give me access to npm, waiting.

@vecmezoni
Copy link
Collaborator

In this case people with "nunjucks": "^2.4" will get this update. Also we can add deprecation warning for everything less than 2.4.2 https://docs.npmjs.com/cli/deprecate

@vecmezoni
Copy link
Collaborator

@devoidfury add note to CHANGELOG.md and i'm going to merge this and prepare for release and deprecation note.

@matt-
Copy link

matt- commented Sep 7, 2016

Should the escape filter also do the same?

@devoidfury
Copy link
Contributor Author

Yes, thanks @matt- -- added another commit to fix this.

@@ -26,6 +26,9 @@ Changelog
* Fix handling of macro arg with default value which shares a name with another
macro. Merge of [#791](https://github.com/mozilla/nunjucks/pull/791).

* Fix potential cast-related XSS vulnerability in autoescape mode, and with `escape` filter.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be merged without, but credits where due: "Thanks Matt Austin and Thomas Hunkapiller.".

@vecmezoni
Copy link
Collaborator

👍 Merging this to master, then i'll create branch 2.4.3 from 2.4.2 release, backport this patch and rebase 2.x branch on 2.4.3.

@vecmezoni vecmezoni merged commit a6ea825 into mozilla:master Sep 7, 2016
@carljm
Copy link
Contributor

carljm commented Sep 7, 2016

@vecmezoni sounds good, but I'd avoid rebasing the 2.x branch. It's public, that could really mess up anyone else tracking it. just merge from your new 2.4.3 branch into 2.x instead.

@vecmezoni
Copy link
Collaborator

  • Released 2.4.3
  • Added deprecation note (i'm not sure that vulnerability is critical, but anyways)
> npm i nunjucks@2.4.2

npm WARN deprecated nunjucks@2.4.2: potential XSS vulnerability in autoescape mode, 
and with escape filter was fixed in v2.4.3
  • Backported patch to 2.x, tomorrow i will review and test branch and issue 2.5.0 release.

@dlmr
Copy link

dlmr commented Sep 8, 2016

Seems like this change broke the use of the safe filter.

{{ value | safe }}

With 2.4.3 this will be escaped where I thought it should not be that. Could be that I have used it incorrectly in my application and that this was never supposed to work but wanted to give a heads up if this was not the case.

@devoidfury
Copy link
Contributor Author

@dlmr Could you provide a simple test case here?

@dlmr
Copy link

dlmr commented Sep 8, 2016

@devoidfury I think I found the problem when trying to create a minimal example.

I was using React Helmet but did not use the toString() function on what I got back from it which means that the safe filter did nothing in that case and then when rendering the escape did not work, since it was not a string, and I got the unescaped output as I wanted.

So I was actually using this "bug" in my code. The more correct thing is of course to use toString and in the process be more correct.

Thanks for the quick reply and the fix in the first place! Sorry to blame the PR for this! 😄

@nelsonpecora
Copy link

nelsonpecora commented Sep 8, 2016

Haha thanks @dimr for catching this. I just hit this with an old filter we were using for embedding optional svgs. It definitely woke me up this morning!

screen shot 2016-09-08 at 11 58 41 am

If I'm parsing the tests in this PR correctly, I should be doing something like this in my filter, correct?

'use strict';
var fs = require('fs');

module.exports = function (path) {
  try {
    return fs.readFileSync(path); // which has a .toString() method
  } catch () {
    return '';
  }
};

EDIT: Looks like I should just return the string itself. ☝️ noted for anyone that runs into this thread later.

@devoidfury
Copy link
Contributor Author

@vecmezoni @carljm should we modify the SafeString constructor to automatically do a string conversion? Right now, it's no-op (identity) on non-strings, but after that point it's going to be cast to string anyway, and with autoescape, if it's not a SafeString, it will escape.

@fengmk2
Copy link

fengmk2 commented Sep 11, 2016

Should we fix this in 1.x?

}
return str;
return r.markSafe(lib.escape(str.toString()));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will throw TypeError: Cannot read property 'toString' of null when str is null or undefined

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fengmk2 added a commit to node-modules/nunjucks that referenced this pull request Sep 12, 2016
vecmezoni added a commit that referenced this pull request Sep 13, 2016
vecmezoni pushed a commit that referenced this pull request Sep 13, 2016
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

Successfully merging this pull request may close these issues.

None yet

9 participants