Skip to content

Allow only allowed protocols in \href#1440

Merged
edemaine merged 7 commits intoKaTeX:masterfrom
ylemkimon:href-protocol
Jun 27, 2018
Merged

Allow only allowed protocols in \href#1440
edemaine merged 7 commits intoKaTeX:masterfrom
ylemkimon:href-protocol

Conversation

@ylemkimon
Copy link
Member

  • Added allowedProtocols settings

Added `allowedProtocols` settings
@ylemkimon ylemkimon requested review from edemaine and k4b7 June 19, 2018 02:07
@codecov
Copy link

codecov bot commented Jun 19, 2018

Codecov Report

Merging #1440 into master will increase coverage by 0.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1440      +/-   ##
==========================================
+ Coverage    83.2%   83.22%   +0.01%     
==========================================
  Files          77       77              
  Lines        4417     4422       +5     
  Branches      772      773       +1     
==========================================
+ Hits         3675     3680       +5     
  Misses        642      642              
  Partials      100      100
Impacted Files Coverage Δ
src/Settings.js 73.52% <100%> (+0.8%) ⬆️
src/Parser.js 94.45% <100%> (+0.05%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 8621f5b...6e2dd7b. Read the comment docs.

Copy link
Member

@edemaine edemaine left a comment

Choose a reason for hiding this comment

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

Nice idea. It seems good in particular to forbid blob: and file: and especially javascript: by default, and give people an option to customize. I just have a few small comments.

One bigger question: Should there be an option to allow all protocols, when the source is fully trusted? (There's already a way to forbid all protocols: [].) I see two extensions that would achieve this:

  1. Also allow a function for allowedProtocols that decides whether to allow a given protocol. Then (protocol) => true would allow all.
  2. Also allow a true argument to allow all protocols. This may be less self-explanatory.

Do you think this is worth adding? Or should we stick to an explicit whitelist like most sanitizers?

});

it("should not allow protocols not in allowedProtocols", function() {
expect("\\href{javscript:alert('x')}{foo}").toNotParse();
Copy link
Member

Choose a reason for hiding this comment

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

This should probably be javascript:.

} else if (protocol == null && this.settings.allowedProtocols.indexOf(
"_relative") === -1) {
throw new ParseError('Not allowed relative url in \\href', res);
}
Copy link
Member

Choose a reason for hiding this comment

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

You could use utils.contains which is designed for this purpose (and equivalent). I don't feel strongly about this, though... I've always found that helper a bit small to be important.

README.md Outdated
- `colorIsTextColor`: `boolean`. If `true`, `\color` will work like LaTeX's `\textcolor`, and take two arguments (e.g., `\color{blue}{hello}`), which restores the old behavior of KaTeX (pre-0.8.0). If `false` (the default), `\color` will work like LaTeX's `\color`, and take one argument (e.g., `\color{blue}hello`). In both cases, `\textcolor` works as in LaTeX (e.g., `\textcolor{blue}{hello}`).
- `maxSize`: `number`. All user-specified sizes, e.g. in `\rule{500em}{500em}`, will be capped to `maxSize` ems. If set to `Infinity` (the default), users can make elements and spaces arbitrarily large.
- `maxExpand`: `number`. Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to `Infinity`, the macro expander will try to fully expand as in LaTeX. (default: 1000)
- `allowedProtocols`: `string[]`. Allowed protocols in `\href`. Use `_relative` to allow relative urls. (default : `["http", "https", "mailto", "_relative"]`)
Copy link
Member

Choose a reason for hiding this comment

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

Please remove the space after default.

@ylemkimon
Copy link
Member Author

@edemaine Thank you for the review! I've added boolean argument to allow or disallow all protocols. I'm not sure about the function.

@k4b7
Copy link
Member

k4b7 commented Jun 24, 2018

One alternative solution might be to allow [ "*" ] to represent all protocols. This is going to get more interesting if we ever support embedding images.

@edemaine
Copy link
Member

@kevinbarabash That might be considered more standard. I could go either way. @ylemkimon Thoughts?

Revert 'Allow boolean argument'
@ylemkimon
Copy link
Member Author

I think ["*"] is more consistent. Changed to ["*"].

@edemaine
Copy link
Member

Looks great!

@edemaine edemaine merged commit a8015d0 into KaTeX:master Jun 27, 2018
@ylemkimon
Copy link
Member Author

I wonder this qualifies as a security vulnerability.

@ylemkimon ylemkimon deleted the href-protocol branch June 28, 2018 02:17
@edemaine
Copy link
Member

Maybe, given that javascript: was allowed before? How do we indicate this?

@k4b7
Copy link
Member

k4b7 commented Jun 29, 2018

We can add a security section in the release notes of the next release. This is technically a change in behaviour so we should probably go to 0.11.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants