Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
Add template support #285
base: master
Are you sure you want to change the base?
Add template support #285
Changes from 4 commits
f9f6d10
602af77
fe491bf
29adb8e
b6419db
a3a1c8a
887d70d
cc9a267
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps the template population should be timeboxed (context.WithTimeout) (and in a separate goroutine) so a malicious template (infinite loop) doesn't halt the bot
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i've spent some time looking into this and thinking about how it would be done and i'm struggling to think of how we would cancel the
t.Execute
call if it did end up in a situation where there was some kind of infinite loop in a template. we could call it in a goroutine, and we could usecontext.WithTimeout
to know that we're okay to move on after so many seconds of waiting, but i'm not sure how we would actually stop thet.Execute
call from continuing to hang?i also did some tests to see if it's possible to create some kind of malicious template with an infinite loop, and it turns out that if you create a template that ranges over nothing, like
{{ range }}{{ end }}
it just fails to execute and returns an error, rather than creating an infinite loop the wayfor{}
would. i think overall these templates should be pretty safe, considering the fact that they provide a separate templating package specifically to prevent code injection when dealing with html, which makes me think these templates should be okay to use even if they come from an untrusted source.if you still think we should timebox this, i'd be interested in your thoughts about how to kill that
t.Execute
call.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would a recursive template like this be possible? https://play.golang.org/p/uMN1IsGB4xl
It might be useful to look at this issue golang/go#31107
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realized that my playground example might not be super realistic since playground has some pretty strict timing & memory restrictions. It seems like Execute gives up at some depth (100000 from the source).
However, I came up with something that gets killed by the linux OOM killer when writing to a
bytes.Buffer
if the timeout is too loose. Might be useful to allocate a limited size buffer. I imagine it's still possible to abuse the memory when executing the template though.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i tried this on an instance of the bot that i'm currently running, and it did not work. i tried it exactly as you have it here, which takes no input from any fields on the webhook, and i also modified it a bit to take a
name
field. both ways resulted in the following log line when attempting to hit the webhook:but this was a really cool approach. i'm kind of curious why this works in the playground but not the bot. out of curiosity i also put your example in a file and compiled it and it runs in under a second before exiting, and it prints out a bunch of the
Don't you just love recursion?
lines.thank you for this! i skimmed it a but just now but will have to read through it a bit when i have more time. it looks like there may be some good ideas in there that i can use.
perhaps this explains the behavior i mentioned abovened above
i'll look into this, thanks for the suggestion. i'd be interested to see what you came up with.
also, feel free to ping me on keybase and i can point you to the instance i'm running if you want to poke at it.