Skip to content

Add \class and \cssId on non-strict mode#1437

Closed
ylemkimon wants to merge 8 commits intoKaTeX:masterfrom
ylemkimon:html-extension
Closed

Add \class and \cssId on non-strict mode#1437
ylemkimon wants to merge 8 commits intoKaTeX:masterfrom
ylemkimon:html-extension

Conversation

@ylemkimon
Copy link
Member

  • Added string group type, which passes raw string argument

* Added `string` group type, which passes raw string argument
@codecov
Copy link

codecov bot commented Jun 17, 2018

Codecov Report

Merging #1437 into master will decrease coverage by 0.37%.
The diff coverage is 44.11%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master   #1437      +/-   ##
=========================================
- Coverage   82.57%   82.2%   -0.38%     
=========================================
  Files          77      78       +1     
  Lines        4408    4406       -2     
  Branches      772     771       -1     
=========================================
- Hits         3640    3622      -18     
- Misses        665     676      +11     
- Partials      103     108       +5
Impacted Files Coverage Δ
src/buildHTML.js 97.79% <ø> (ø) ⬆️
src/functions.js 100% <ø> (ø) ⬆️
src/ParseNode.js 88.88% <ø> (ø) ⬆️
src/functions/href.js 100% <100%> (ø) ⬆️
src/Parser.js 94.9% <100%> (+0.5%) ⬆️
src/functions/html.js 5% <5%> (ø)

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 6195f2f...6ce0fde. Read the comment docs.

if (lastToken.text === "{") {
nest += 1;
} else if (lastToken.text === "}") {
if (nest <= 0) {
Copy link
Member Author

@ylemkimon ylemkimon Jun 17, 2018

Choose a reason for hiding this comment

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

This was unreachable, as while is terminated if nest === 0 && this.nextToken.text === groupEnd.

@ronkok
Copy link
Collaborator

ronkok commented Jun 17, 2018

As @kevinbarabash once reminded me, some people may want to protect their web site from users adding classes. Maybe this (terrific) code should go behind its own rendering option omitClass, default = true.


defineFunction({
type: "html",
names: ["\\class", "\\cssId"],
Copy link
Member

@ry-randall ry-randall Jun 18, 2018

Choose a reason for hiding this comment

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

While I know mathjax calls this "cssId", I think it would be nice to give it a more generic name (i.e. "id"). My only reasoning is, if multiple renderers end up being supported, css may have no meaning (i.e. in a canvas).

For a similar reason, I would give this file a more generic name as well (i.e. identifiers.js)

Copy link
Member

Choose a reason for hiding this comment

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

@rrandallcainc were you thinking that id might be useful for hit testing in canvas based renderer.

Copy link
Member

Choose a reason for hiding this comment

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

@kevinbarabash Hit testing could be one use case. I was more thinking along the lines of being able to manipulate specific parts of the LaTeX separately. For example, let's say I had \frac{\id{numerator}{a}}{\id{denominator}{b}} and I wanted to switch the two. I see as id/class as general ways of targeting specific areas of the latex.

names: ["\\class", "\\cssId"],
props: {
numArgs: 2,
argTypes: ["string", "original"],
Copy link
Member

Choose a reason for hiding this comment

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

I'm assuming we want this allowed in text?

Copy link
Member Author

Choose a reason for hiding this comment

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

@rrandallcainc Set allowedInText true.

Copy link
Member

Choose a reason for hiding this comment

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

Assuming you'll want to apply allowInText: true also to html, no?

@ylemkimon
Copy link
Member Author

ylemkimon commented Jun 19, 2018

@ronkok I'm not sure how classes or ids can be abused, as styles are predefined.

@ronkok
Copy link
Collaborator

ronkok commented Jun 19, 2018

as styles are predefined.

Styles are predefined, that's true. But a malicious user, writing in an input box like the one I am writing in now, could mis-apply existing CSS style rules to places where they should not be. An administrator of a site like this one might want to restrict that.

@ylemkimon I think this PR is terrific, and I want to see it succeed. I only write to suggest a way that everybody can be happy with it.

@ry-randall
Copy link
Member

Curious how "reserved" classes/id's are handled. For example, if someone tried \class{strut}{blah} would it apply the strut class unintentionally?

Also, do you plan on adding tests for this?

@k4b7
Copy link
Member

k4b7 commented Jun 24, 2018

My guess is that class and cssId (or id) are commands that would be used by site/app developers and not something that really make sense for user submitted content so providing a way to disable these commands should be sufficient.

/**
* Parses a url string.
*/
parseUrlGroup(optional: boolean): ?ParsedArg {
Copy link
Member

Choose a reason for hiding this comment

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

This change conflicts with #1440.

"html": {|
type: "html",
class?: string,
cssId?: string,
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we could change this be:

type: "html"
attribute: "class" | "id",
value: string,
body: AnyParseNode[],

Copy link
Member Author

Choose a reason for hiding this comment

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

@kevinbarabash I thought there may be use cases of setting both class and id.

Copy link
Member

Choose a reason for hiding this comment

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

But wouldn't there be separate commands, e.g. \class{foo}{\id{bar}{content}}?

"string": {|
type: "string",
value: string,
|},
Copy link
Member

Choose a reason for hiding this comment

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

Is this only used to replace url?

Copy link
Member Author

Choose a reason for hiding this comment

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

Also for the first argument of \cssId and \class.

math.setAttribute('class', group.value.class);
}
if (group.value.cssId) {
math.setAttribute('id', group.value.cssId);
Copy link
Member

Choose a reason for hiding this comment

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

I've found that browsers tend to get confused about things when there are multiple elements with the same id.

Copy link
Member Author

Choose a reason for hiding this comment

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

Does it apply to the MathML elements, too?

Copy link
Member

Choose a reason for hiding this comment

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

If you query for an element by id you can get an HTML element, SVG element, MathML element, etc.

@ylemkimon
Copy link
Member Author

@ronkok @ry-randall Another way of limiting their usage is allowing only those with specific prefix, like MathJax safe extension. What do you think?

@ronkok
Copy link
Collaborator

ronkok commented Jun 26, 2018

@ylemkimon I don't really have a strong personal opinion on this issue. I spoke up earlier to make you aware of a comment that @kevinbarabash had once made to me. Anything he likes on this issue will be okay with me, too.

@ry-randall
Copy link
Member

ry-randall commented Jun 27, 2018

@ylemkimon I'm not too familiar with the mathjax safe extension. Do you mean something like \class{katex-className}{blah} where "katex-" would be the safe extension?

Edit: I just took a look @ http://docs.mathjax.org/en/latest/options/other/Safe.html#configure-safe and found what you're referring to.

I think that's the right approach, for sure. Others thoughts?

@edemaine
Copy link
Member

Hmm, related to #1436 then I guess. Is there a nice uniform solution? It'd be cool to be able to specify custom-* or something as allowed classes, or explicitly list allowed classes, though the "safe" specifier might also be sufficient in most cases.

@edemaine
Copy link
Member

P.S. I do worry about defining an id that matches another id on the page, thereby hijacking some things tied to the page. It's not like the KaTeX object is going to do anything with that replacement (until we support \javascriptToRunWhenClicked{...}), but it could easy break existing code that uses document.getElementById. So some kind of limitation is needed.

@k4b7
Copy link
Member

k4b7 commented Jun 29, 2018

So some kind of limitation is needed.

I think the limitation should be at the command level. We should disable \class and \id by default and allow users to opt-in by enabling "unsafe" mode. This should be relatively simple to do and allows users to move to the new version of KaTeX without opening a major attack vector. Users whose sites don't accept user input and who need \class and/or \id can turn of "unsafe" mode.

@ronkok
Copy link
Collaborator

ronkok commented Jun 29, 2018

I think the limitation should be at the command level.

What if a web site administrator wants protection from a malicious user? Would the limitation be better if set as a KaTeX rendering option?

@edemaine
Copy link
Member

Perhaps we should add a new option safe or unsafe that is similar to strict, but is explicitly about security, and allows configuration (e.g. allow certain classes but not others, allow class but not id). The allowedProtocols configuration could be rolled in...?

@k4b7
Copy link
Member

k4b7 commented Jun 29, 2018

I think the limitation should be at the command level.

What I meant by this is that I don't think we should try to filter things in/out by some id/class prefix. I think we should have a unsafe setting which is false by default which can be passed to the render function. Setting unsafe to true will allow the use of the \id and \class commands.

@ylemkimon
Copy link
Member Author

I think we can go with RegExp | boolean, with default false. I'm afraid this will clutter settings, with a feature only few people will use. I think we should categorize settings and/or have a naming system.

@k4b7
Copy link
Member

k4b7 commented Jul 4, 2018

@ylemkimon the boolean is whether or not class and id are allowed and the RegExp is what values they all?

@k4b7
Copy link
Member

k4b7 commented Jul 4, 2018

Agree that a naming strategy for options/settings is a good idea.

@ylemkimon ylemkimon mentioned this pull request Jul 16, 2018
@k4b7
Copy link
Member

k4b7 commented Jul 22, 2018

For this to move forward it sounds like we need:

  • test cases involving \class{part-1}{\frac{1}{2} + \frac{3}{2}} = 2
  • changes to the code that address the spacing issues and make those test cases pass

@ylemkimon
Copy link
Member Author

ylemkimon commented Sep 8, 2018

Blocked on #1706 and #1711.

@dvergeylen
Copy link

dvergeylen commented Feb 5, 2019

Hi @ylemkimon ,

As #1706 and #1711 are both merged by now, do you see anything blocking this?

Is #1771 blocking this or could a (disabled by default) option (e.g: {allowClass: false, allowId: false} ) be reasonable security setting?

I am currently needing this feature for a WYSIWYG editor, would be glad to give a hand!

@edemaine
Copy link
Member

edemaine commented Feb 5, 2019

@dvergeylen Yes, this is blocked on #1771, or more precisely, #1794. We don't want to add a bunch of options and then switch to a different mechanic. Your feedback on #1794 would be appreciated!

@steveluc
Copy link

While we are waiting for #1794, is there a workaround to add styling to an element that corresponds to a substring of tex input? Id is overkill for this and so is class. For example, there could be something like \localId{id1}{x^2} which associates id1 with an element implementing the x^2 substring. We could have an option passed into render that supplies a map or object to be populated with these ids. Then whatever permission the page has to style elements, it can apply to these elements. Thanks.

@k4b7
Copy link
Member

k4b7 commented Apr 17, 2019

I think this is still blocked, but by #1794 now.

@k4b7 k4b7 added the blocked label Apr 17, 2019
@k4b7 k4b7 removed the blocked label Jul 9, 2019
@k4b7
Copy link
Member

k4b7 commented Jul 9, 2019

This is no longer blocked.

@edemaine edemaine mentioned this pull request Jul 10, 2019
@ylemkimon ylemkimon mentioned this pull request Aug 20, 2019
@k4b7
Copy link
Member

k4b7 commented Sep 22, 2019

Closing in preference of #2082.

@k4b7 k4b7 closed this Sep 22, 2019
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.

7 participants