-
Notifications
You must be signed in to change notification settings - Fork 2k
Enhance local Python executor security by blocking dunder calls #1551
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
Conversation
updating the local_python_executor to prevent execution while Python code attempt to access dunder methods. A developer can authorize a dunder method the same way as he authorizes tools, for example: custom_executor = LocalPythonExecutor([]) custom_executor.send_tools({"__getattribute__":"__getattribute__","__subclasses__":"__subclasses__"})
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.
Thank you for the security fix!
I think there are some cases where this fix is not working: see failing tests.
- For example, what about a subclass calling
super().__init__()
? This PR does not allow it.
@albertvillanova thanks for the response. |
Thanks for the clarification, @nnfrog! Just to clarify, I wasn't referring to
That said, you're absolutely right that More broadly, though, I wonder if we should consider allowing some basic built-in methods by default (such as In any case, I agree this could be discussed and handled separately in a dedicated PR. Would be great to hear your thoughts on that direction. |
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.
One thing I forgot to ask: do you have a mechanism in mind for explicitly allowing methods like __init__
, for example? In the current design, tools/functions are passed via static_tools
as a dictionary mapping function names to their corresponding callables; but in the case of __init__
, there's no standalone callable we can provide in the same way.
I think this is something we should address directly in this PR, as it ties into the broader question of how we handle access to special methods. As I mentioned earlier, it's always a delicate balance between maintaining security and enabling useful functionality.
Hi @albertvillanova and sorry for the delay in my response About how to implement it - I think a list with method names as strings, and then checking it against a func.name result could be a valid option WDYT? |
Thanks for the suggestion: yes, I think that could work well. A list of explicitly allowed method names (e.g., I'm happy to proceed with that direction if you are. |
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.
Thanks a lot for the security enhancement!
I just added some comprehensive vulnerability tests covering various attack vectors through dunder methods:
- Direct dunder method calls (
'string'.__dir__()
) - Complex attack chains using
__getattribute__
and__subclasses__
- Subprocess execution attempts via class hierarchy traversal
Sure! You are welcome! |
Hi, all. It looks to me that this issue and fix was inspired by a security report first filed on 6/16 (see https://huntr.com/bounties/8d993108-f56c-445e-8886-282288170b29). While I appreciate this critical vulnerability gets the attention that it deserves and finally fixed, I hope that Huggingface is not setting the precedence to decline bug bounty report but later fixing the issue. |
@quitbug, thanks for raising your concern. I'd like to clarify the timeline here to avoid any misunderstanding. This vulnerability was first reported to us on May 27 by the JFrog team. We assessed it as informative at the time, since the local Python executor is not intended to be a secure, sandboxed environment. Shortly afterwards, the JFrog team themselves proposed to open a pull request to address the issue, which led to the eventual fix you see here. We take all security reports seriously and have no practice of declining a valid bug bounty report only to later fix it without acknowledgment. In this case, the report you linked was not the first disclosure of the issue, and the fix originated from the earlier JFrog report and PR. CC: @Michellehbn |
As a matter of fact, the report was not marked as a duplicate of the JFrog issue, but another similar issue (from jackfromeast) which required a different fix. That has created the unnecessary misunderstanding. Now, things are clear. Thank you and everyone for the fix. :) |
Thanks for your understanding, @quitbug. Note that the JFrog report didn't come through huntr.com, but it was submitted via security@huggingface.co to our internal Zendesk system. So linking it as an exact duplicate wasn't possible. I believe it was instead linked to the most similar public report. In any case, I'm glad everything is clear now, and I appreciate the constructive discussion. |
Updating the local_python_executor to prevent execution while Python code attempt to access dunder methods (and not just dunder attributes).
A developer can authorize a dunder method the same way as he authorizes tools, for example: