Skip to content

Enhancing the local Python sandbox #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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

Conversation

nnfrog
Copy link

@nnfrog nnfrog commented Jul 13, 2025

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:

custom_executor = LocalPythonExecutor([])
custom_executor.send_tools({"__getattribute__":"__getattribute__","__subclasses__":"__subclasses__"})

nnfrog and others added 5 commits July 13, 2025 10:17
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__"})
Copy link
Member

@albertvillanova albertvillanova left a 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.

@nnfrog
Copy link
Author

nnfrog commented Jul 20, 2025

@albertvillanova thanks for the response.
This fix is functioning under the presumption that dunder methods are no different than tools, if a developer want to have some dunder method available he can explicitly allow it at his own risk - otherwise all the rest will be blocked.
About the "super" method's test I must say I am a little confused as the super method is blocked regardless of my fix - as it is not authorized by default method.
I am using "smolagents" version 1.19.0 and I got this error while attempting to run code with "super", regardless of my fix:
InterpreterError: Forbidden function evaluation: 'super' is not among the explicitly allowed tools or defined/imported in the preceding code

@albertvillanova
Copy link
Member

albertvillanova commented Jul 21, 2025

Thanks for the clarification, @nnfrog!

Just to clarify, I wasn't referring to super itself, but rather to the __init__ call: InterpreterError: Forbidden access to dunder function: __init__

FAILED tests/test_local_python_executor.py::TestEvaluatePythonCode::test_classes - smolagents.local_python_executor.InterpreterError: Code execution failed at line 'dog1 = Dog("Fido", 3, "Labrador")' due to: InterpreterError: Forbidden access to dunder function: __init__

That said, you're absolutely right that super is already blocked by default, so extending that behavior to also block __init__ makes the logic consistent.

More broadly, though, I wonder if we should consider allowing some basic built-in methods by default (such as super and __init__) to support simple class definitions/instantiations and typical Python constructs out of the box. That might help make the Python executor more useful for common use cases. It's always a challenge to strike the right balance between security and usability, especially in a execution environment.

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.

Copy link
Member

@albertvillanova albertvillanova left a 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.

@nnfrog
Copy link
Author

nnfrog commented Jul 28, 2025

Hi @albertvillanova and sorry for the delay in my response
while init by itself is harmless, init+super can be an issue depending on context - this is why I'm more of a "let the devs decide" guy in my approach.

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants