Invoke: Possible alternative, safer run() interpolation

Created on 17 May 2012  Â·  5Comments  Â·  Source: pyinvoke/invoke

Ken's Envoy project has a similar run() to what Invoke will have, and somebody raised the point about making it easy for users to be secure against injection/quoting attacks, by adding a DB-API like parameterization format.

The link: https://github.com/kennethreitz/envoy/issues/16

I agree with Ken's points therein that the point of these tools is ease of use, not correctness, but also with the "let's offer users the option of correctness if they want it" corollary.

So, check out that pypi'd package linked at the end of the discussion and see if it makes sense to integrate.

EDIT: cut to chase, link is http://shell-command.readthedocs.org/en/latest/ . Untouched since initial release, so now ~3 years old.


Strongly related here is the idea of exposing Popen's alternate list-of-parameters format for its initial argument, i.e. not this:

run("foo --the-bars plz")

but instead, this:

run(['foo', '--the-bars', 'plz'])

Some users find this easier than trying to handle/escape complex all-in-one command strings.

Feature run()

Most helpful comment

I'd absolutely love to use plumbum inside invoke. It's become my de-facto scripting "language" since I knew it.

Anyways, I think that being able to pass an argv list instead of a string is really needed, no matter the implementation.

All 5 comments

Another angle on this is the use of tools like sh.py or plumbum, which attempt to bridge arbitrary shell string execution with Python-level function invocations. The latter can easily protect against injection style attacks because all the parameters/flags/values/etc are being handled independently and can be filtered/transformed before/while constructing the final string (or list/vector).

I'm not at all sure I want to pull in one of those or use it as the primary invocation style, but it should definitely be considered as an option.

And re: the SQL-style parameter substitution in this ticket's description, I'm on the fence as to whether that should be default or not. Being secure by default is a great idea, but it's unclear whether untrusted input is a big concern here - most users of eg Fabric and Makefiles are running their own commands or commands from an implicitly-trusted shared codebase.

@pfmoore notes that this style of invocation (list-based instead of string-based) is also beneficial on some Windows platforms, see link to #312 above.

Seems there's a(n old) PR for this, #341 - linking for possible use when I get to this.

I'd absolutely love to use plumbum inside invoke. It's become my de-facto scripting "language" since I knew it.

Anyways, I think that being able to pass an argv list instead of a string is really needed, no matter the implementation.

I see there are two PRs open to address this, #341 and the more recent #698. I’m not able to judge whether they are in any position to be approved and merged – in the meantime I think it would be nice to update run’s documentation to reflect that escaping isn’t provided and mention the risks so users can make an educated decision.

This could just be a single sentence in http://docs.pyinvoke.org/en/stable/api/runners.html#invoke.runners.Runner.run, or mentioning the lack of escaping of the command parameter. Perhaps with a link back to this issue for further info.


I’d be very happy to make that documentation PR, or do what I can to help get #341 / #698 merged, if someone more experienced with the project can provide guidance.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

deckar01 picture deckar01  Â·  6Comments

anarcat picture anarcat  Â·  4Comments

DominikSerafin picture DominikSerafin  Â·  6Comments

bitprophet picture bitprophet  Â·  4Comments

lsh-0 picture lsh-0  Â·  5Comments