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

Use temporary rewriting of curly brackets when rendering Markdown content blocks #994

Closed
wants to merge 2 commits into from

Conversation

bennothommo
Copy link
Member

@bennothommo bennothommo commented Oct 16, 2023

Fixes #992

The new Markdown parser (CommonMark) applies some escaping logic for links and some HTML attributes. This prevents the curly bracket variables working in these, as they are escaped upon parsing. Since the Commonmark library is very much locked down with final classes and the like, we can't directly override this behaviour, so this is the next best thing (although feels kinda dirty).

This replaces the curly brackets with another placeholder while the Markdown parsing takes place and then switches it back to curly brackets afterwards. The characters chosen should be safe from being parsed, I believe. It should also ensure that the curly brackets are still cached as it was with the previous behaviour.

@LukeTowers
Copy link
Member

LukeTowers commented Oct 18, 2023

Can we have some unit tests added for this? If they could include attempts at abusing this new logic to somehow perform some sort of malicious action (if you can think of any) that would be great. The proposed fix could open the door for that type of potential attack vector.

@bennothommo
Copy link
Member Author

bennothommo commented Oct 19, 2023

@LukeTowers the only specific opening this would provide would be if one were to be accepting any form of user input into a content block - they could put in the replacement signature (ie. .=VAR=[some variable]=.) into their input, and as long as the variable is actually passed into the rendering pipeline, it would be replaced.

I figured the likelihood that people would be accepting input into content blocks was extremely low, and at best, they would simply get access to a variable that's already made available to the page anyway (and can only be provided by the backend, so it would need to be a privileged user).

I will set up a test case or two for it though.

@LukeTowers
Copy link
Member

@bennothommo this is a horrible idea, but we could prevent it from happening by pre-replacing the replace target with something else and then changing it back afterwards.

So:

  • replace .=VAR=. with .=NOTVAR=.
  • replace {} with .=VAR=.
  • markdown parse
  • replace .=VAR=. with {}
  • replace .=NOTVAR=. with .=VAR=.

I could see some potential attack vectors around the use of template fields and safe mode, so we should at least cover this case to avoid introducing any vectors unnecessarily.

@bennothommo
Copy link
Member Author

@LukeTowers slightly less horrible, but the other idea is we could add that sequence to the escaping functionality within Twig, so if it's fed through a Twig variable, it's escaped, but should be fine if it's directly in the template.

@mjauvin
Copy link
Member

mjauvin commented Oct 22, 2023

Maybe a stupid question, but why can't we expand the content variables to their values BEFORE parsing the markup with Markdown::parse ?

@bennothommo
Copy link
Member Author

@mjauvin because the content blocks are cached on render. Putting in the variables before rendering would lock that set of variables in, and you'd lose the ability to re-use the content block with different values without clearing and re-rendering each time.

@mjauvin
Copy link
Member

mjauvin commented Oct 22, 2023

Right, that couldn't be so simple... It was worth a shot!

@LukeTowers
Copy link
Member

@bennothommo what would that look like? Cause it sounds pretty horrible 😂

@LukeTowers
Copy link
Member

Also is there any flexibility to just changing the markdown parser to not cause us this issue in the first place?

@bennothommo
Copy link
Member Author

@LukeTowers it basically requires us to completely replace one of the core Commonmark extensions with our own copy of the same extension (plus any overrides to make the links work with the variables).

While I'm not adverse to that, it does mean that we then have to ensure that we're monitoring the Commonmark library for changes and implementing any fixes into our own.

@LukeTowers
Copy link
Member

Argh, how annoying. Let's give the twig escaping a try then I guess? Would that actually stop the theoretical attacks I was proposing?

@bennothommo
Copy link
Member Author

It should. I'll have to circle around to this in a couple of weeks though unfortunately. Currently knee-deep in a very time-critical project.

@bennothommo
Copy link
Member Author

@LukeTowers just circling back to this - I'm wondering if we even need Twig escaping? The particular issue here is with content blocks that are Markdown-formatted. Content blocks aren't put through the Twig parser at all, as far as I'm aware.

@LukeTowers
Copy link
Member

@LukeTowers just circling back to this - I'm wondering if we even need Twig escaping? The particular issue here is with content blocks that are Markdown-formatted. Content blocks aren't put through the Twig parser at all, as far as I'm aware.

@bennothommo didn't you say that they are?

@mjauvin because the content blocks are cached on render. Putting in the variables before rendering would lock that set of variables in, and you'd lose the ability to re-use the content block with different values without clearing and re-rendering each time.

@LukeTowers LukeTowers modified the milestones: v1.2.4, 1.2.5 Dec 27, 2023
@mjauvin mjauvin modified the milestones: 1.2.5, 1.2.6 Feb 18, 2024
@LukeTowers
Copy link
Member

@bennothommo what's the status on this?

@LukeTowers LukeTowers modified the milestones: 1.2.6, 1.2.7 Apr 25, 2024
@bennothommo
Copy link
Member Author

I really don't like this fix, TBH. I'm more inclined to can it and think of something else.

@LukeTowers LukeTowers closed this Apr 26, 2024
@LukeTowers LukeTowers deleted the fix/992 branch April 26, 2024 03:37
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.

Markdown parser fails in content file when using a content variable as the url
3 participants