Closed ross-bradley closed 3 years ago
@ross-bradley Thanks! Yes, you are completely correct and this should be addressed.
I think the best approach here is to simply (and always) disallow access to "dunder" attributes entirely but to also keep the other UNSAFE_ATTRS that are not "dunder" methods. A quick check shows that doing that still passes all existing tests. Doing that "no dunder methods" is still sort of a black-list instead of a white-list, but it will adapt better with newly added features.
Does that seem reasonable to you?
That seems to strike an appropriate balance. Whilst yes, it's an extension of the deny-listing approach, it seems to cover the most dangerous attributes and methods in a sufficiently sweeping manner, and does so without requiring an overly onerous effort.
@ross-bradley Thanks - I'll commit that. It turns out that 0.9.22 got released yesterday, but I'll try to push this out as 0.9.23 soon, updating the docs on what is not allowed.
FWIW, I think a whitelist of allowed attributes would be hard to maintain. I guess it does have the advantage of starting with "secure" and moving toward "useful".
@ross-bradley the fix for this is now merged into the master branch.
Hey @newville is it possible to publish a new release with this change? thanks
@snoopysecurity thanks for the reminder - I just tagged 0.9.23 and pushed to PyPI.
The engineers at work were considering using asteval, so I've taken a quick look at it to see what kind of risk it might represent. One sandbox escape in particular jumps out - reduce is permitted, giving access to getattr, at which point none of the security assumptions hold.
Potential "fixes", in rough order of less effort/useful -> more effort/useful include:
I'd also suggest adding base, builtin and builtins to the naughty list in the short-term. Given asteval's use case, it still exposes a lot of Python internals, increasing attack surface considerably. Of course this is basically whack-a-mole, as deny-lists inevitably are.
Simple proof of concept (open a netcat listener or some such on port 1234/tcp for full effect):