Open ngregoire opened 3 years ago
Thanks, you found a weird combination of intended and unintended effects:
enabled
boolean flag so that users can enable/disable plugins.enabled
as a local setting of the user, not something inherently tied to the setting itself.enabled
, it has to be supplied from somewhere. It's left false
(the default of boolean values) upon import to minimize surprising behavior, such as breaking an ongoing scan by inserting a HTTP listener that mangles requests and/or responses in an unexpected/unintended way.loadDefaultConfig
), where it obviously makes sense to load everything enabled since we know it probably won't break anything as it's a known state hardcoded into the JAR file.The end result is what you experienced, and I agree that it's not the best outcome. As I mentioned above, I intended YAML as the (more) user-readable, stand-alone, shareable version, while ProtoBuf is somewhere between a temptation (it's about 10 lines of code since the rest is already there for settings persistence, so why not) and the notion of it being easier to parse reliably in a standardized way as opposed to YAML which has lots of issues between different implementations.
Knowing all this, what would you consider a better solution?
I prefer to use YAML (easier to read / edit / compare) and I would like to see the Prototobuf and YAML versions working in a same way. That implies adding "enabled" to the YAML format.
Regarding YAML parsing differences: you made me curious given that, usually, parsing mismatches lead to interesting bugs
I prefer to use YAML (easier to read / edit / compare) and I would like to see the Prototobuf and YAML versions working in a same way. That implies adding "enabled" to the YAML format.
I agree, YAML is the way for Piper to interact with humans, that's also why I use it for the default config format. What are your thoughts about ignoring enabled
in the Protobuf import/export? That would also result in both formats working the same way.
Regarding YAML parsing differences: you made me curious given that, usually, parsing mismatches lead to interesting bugs
Exactly, this is why YAML is a bad format, as everyone can confirm who tried listing countries using 2-character ISO codes and someone picked Norway. ;) So right now, YAML works for Piper in a way that the same library is used to read and write. But I cannot guarantee that any other YAML parser could
It's a shitty format, but I couldn't find anything better with the same level of human readability and descriptive force such as arbitrary nesting (needed for filters), binary content (also needed for filters), etc.
Ignoring enabled
in the Protobuf implementation: why not, so that both parsers work in a same way. But we would loose the possibility to load enabled-by-default configs (that's not a problem for me)
YAML: thanks for opening my eyes on how bad this format is ;-) Despite the possible incompatibilities, I'd keep it around, as text-based config is much easier to deal with
Ignoring
enabled
in the Protobuf implementation: why not, so that both parsers work in a same way. But we would loose the possibility to load enabled-by-default configs (that's not a problem for me)
Thanks for the confirmation, I'll do it that way then.
YAML: thanks for opening my eyes on how bad this format is ;-)
Happy to help you become one of today's lucky 10,000 \o/
Despite the possible incompatibilities, I'd keep it around, as text-based config is much easier to deal with
I agree, that was my original intention. So YAML has always been the main format and ProtoBuf is just there because it would've been a sin not to expose the already existing option to users.
All good, many thanks!
Reopening, as this issue came up while developing #29.
1) This statement turned out to be too optimistic:
A special exception is made for the default config (see loadDefaultConfig), where it obviously makes sense to load everything enabled since we know it probably won't break anything as it's a known state hardcoded into the JAR file.
During testing, my code fell back to loadDefaultConfig()
, that has some MessageViewers defined. Some binaries required by MessageViewers are not present on the system. I also have some Stepper sequences defined, that for some reason try to execute all MessageViewers on the defined steps, which results in tons of exceptions because of invoking non-existent binaries on the system.
While this can be a bug of Stepper, I think, that assuming every dependency of every Piper script in the default config will be present on every system is unrealistic. We also don't know the edge cases where different Piper scripts with missing dependencies may be triggered. On the other hand when a user explicitly loads some scripts (or enables some defaults) I think it's fair to assume that she wants to use them, and is ready to deal with system dependencies.
2) Not being able to load scripts in an enabled state also hinders automation (think Burp Enterprise) significantly.
Maybe I didn't make myself clear enough: by won't break anything I meant not doing anything unexpected for the user, this covers
The first two are typical examples for HTTP listeners which the default config lacks while the last one covers the commands themselves which are considered trusted by definition, since if your threat model includes Piper JAR being mailicous, it's much easier to plant a backdoor in the Kotlin code itself instead of the much shorter and more readable YAML default config.
I guess your interpretation of braking thinks (results in tons of exceptions) is fair, yet it's not a big deal in my view: exceptions are part of life, and shouldn't break anything. Yet there's already code in place to handle this, just unused:
So if the code below would change from true
to null
(and Piper.Config.updateEnabled
would add a ?
to its Boolean
argument type to allow null
values), this would affect loading the default config by enabling only the things that have their dependencies installed.
Would that solve your issue?
Not being able to load scripts in an enabled state also hinders automation (think Burp Enterprise) significantly.
That would be solved by #29 I guess.
exceptions are part of life, and shouldn't break anything
I got one of my homeworks rejected you know where because of this, so maybe it's just my PTSD triggered :D
Would that solve your issue?
Yes, I think this is a good solution to the dependency problem.
That would be solved by https://github.com/silentsignal/burp-piper/pull/29 I guess.
True, but with this we enable scripts on one load path but not on another, which I think is inconsistent and goes against your stated concerns. Frankly, I don't see how support for automation and protecting the "Piper script supply chain" can be solved together.
we enable scripts on one load path but not on another, which I think is inconsistent and goes against your stated concerns
Inconsistent? Maybe. Against my concerns? I don't think so. Think Mark-of-the-Web:
So I think it's quite the opposite of what you stated: the current behavior supports automation yet prevents users from shooting themselves in the foot by loading either malicious or well-intended but flawed configurations.
Where do you see our opinions diverge?
I simply don't see that much of a difference between the GUI and the env var paths in terms of the trustworthiness of the input, or user consent. In both cases the user has to perform explicit actions to make the scripts load, and have the chance to review the scripts, but we can't ensure that she did.
If you argue that clicking buttons is a "weaker" consent than setting environment variables, I can accept that, but I think it is important to clarify (and maybe document) this, esp. since there are security concerns.
clicking buttons is a "weaker" consent than setting environment variables
Thanks, that's exactly my point. Although the use-cases of GUI and environment variables overlap somewhat, I feel that
And you're right, this should be documented as soon as it's ready for a release.
Piper behaves differently when importing YAML and Protobuf files. YAML won't persist the "enabled" state
How to reproduce:
Workaround: