voxpupuli / webhook-go

Puppet Webhook port in Golang
Apache License 2.0
16 stars 12 forks source link

Add a option to force override module name #139

Closed raincz closed 8 months ago

raincz commented 9 months ago

The module name is implied from the git repository name. However, both r10k and puppet are very particular about module naming, and the implicit rewrites rules can get in the way. Puppet will understand any amount of dashes in the project name as <vendor>-<module>, rewriting - to /. For git repositories, there are often arbitrary naming rules with copious amounts of these control characters in repository names, making it nearly impossible to serve both worlds at the same time.

This URL parameter (module_name) allows to override the module name directly in the URL, completely ignoring the git repository name.

raincz commented 9 months ago

@dhollinger Sorry, another rather similar one. :D Description in the commit message. I did not find any documentation which needed to be updated.

raincz commented 9 months ago

Sure thing. Should I do it as a separate PR?

raincz commented 9 months ago

I added something to the README in a second commit. There really wasn't anything to start with so I just added a new section.

raincz commented 9 months ago

Hmm, I see you approved it @dhollinger but maybe it's the automated checks that are stopping the merge? The thing is, the failing check seems to be new and it's failing outside of the code I touched.

smortex commented 8 months ago

The thing is, the failing check seems to be new and it's failing outside of the code I touched.

I feel like this is caused by the module_name not being sanitized, e.g. one can pass module_name=%24%28rm%20-rf%20%2A%29foo, and this would have unexpected consequences? Maye can be tested a safe way with module_name=%24%28touch%20%2Ftmp%2Fflag%29foo (module_name=$(touch /tmp/flag)foo)?

Not sure how to fix that properly in go. Generally it is safer to run a command by passing an array of arguments rather that a string fed to a shell.

raincz commented 8 months ago

That is a fair point, I did not consider this. Silly that the check puts the blame on a completely detached line.

raincz commented 8 months ago

Mmm, so I looked at the docs. For one it does not seem like any shell quoting is necessary to begin with, as https://pkg.go.dev/os/exec#Command does not really use sh -c to run commands. But it's true that handling of bad invocation of r10k isn't great in the webhook in general, so it makes sense to explicitly validate this based on the documented Puppet rules. I added that. The CodeQL check is overly dogmatic though and still fails. I'll try to think of a way to shut it up.

raincz commented 8 months ago

Well. I'm at a loss. This monstrosity of a security check is simply forbidding variables touched by user input to be used for insertion into commands. With gosec there's a way to disable the linter checks with a comment, but I don't see a way how to do it with this CodeQL. I understand the overall rationale, and I fully support having to sanitize anything that goes into a system command. But this alert offers no way to really fix this, and it seems like it will not accept anything less than a full concession and not implementing any functionality like this. The "suggestion" to use a set of predefined consts and choose from them based on the user input is really entirely senseless here.

dhollinger commented 8 months ago

@raincz The issue here is that by allowing a user to pass in the value from the url directly, it allows anyone with credentials, or some other mechanism, to execute code maliciously on the system. We probably need to look at a value that can be passed in as a Header or some other mechanism supported by the Git provider as a way to override the module name.

Ideally, I'd prefer to have an API I can call to run r10k-like functionality, but that currently doesn't exist and I haven't had time to look at/work on g10k to make it useable with this in place of r10k

raincz commented 8 months ago

Yeah. This is true in general, but sanitizing the input should be sufficient. The Puppet module name has a pretty strict regex that I put in (lowercase leters, digits, underscore), which pretty much precludes any injection. This should be sufficient for this particular use case, but regardless of that, there is simply no way to tell this to CodeQL.

dhollinger commented 8 months ago

@raincz I will override and merge this PR. Though I will continue to look for a better way to do this