Skip to content
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

exec Function Allowed in Restricted Python Environment #284

Open
Abdullahsecuriti opened this issue Aug 2, 2024 · 3 comments
Open

exec Function Allowed in Restricted Python Environment #284

Abdullahsecuriti opened this issue Aug 2, 2024 · 3 comments

Comments

@Abdullahsecuriti
Copy link

Abdullahsecuriti commented Aug 2, 2024

BUG/PROBLEM REPORT / FEATURE REQUEST

Description:

In a restricted Python package environment, the following code snippet:

python 3.10.0

try:
  exec("import os; os.system('ls'); print('**')")
except:
  pass

successfully executes without throwing an error, despite exec being expected to be undefined in such a restricted environment.

However, when the code is run without the try-except block:

exec("import os; os.system('ls'); print('**')")
an error is thrown as expected.

Expected Behavior:

The restricted environment should prevent the execution of exec and throw an error when it is invoked, regardless of the surrounding try-except block.

@d-maurer
Copy link
Contributor

d-maurer commented Aug 3, 2024 via email

@Abdullahsecuriti
Copy link
Author

Abdullahsecuriti commented Aug 3, 2024

@d-maurer
Thank you for your quick response; it's highly appreciated.

I have successfully executed the following code:

async def __main():
    # Import necessary modules from RestrictedPython
    import textwrap
    from RestrictedPython import compile_restricted, safe_builtins
    from RestrictedPython.Utilities import utility_builtins
    from RestrictedPython.Eval import default_guarded_getattr

    def execute_restricted_code(user_code):
        try:
            # Format the user-provided code
            formatted_code = textwrap.dedent(user_code)
            # Define safe globals for restricted code execution
            safe_globals = {
                '__builtins__': safe_builtins,  # built-in policy allowing basic Python functions
            }

            # Compile the normalized and formatted user-provided code into a restricted code object
            restricted_code = compile(formatted_code, '<usercode>', 'exec')

            # Create a list to capture printed output
            captured_output = []

            # Define a custom print function to capture output
            def safe_print(*args, **kwargs):
                output = ' '.join(str(arg) for arg in args)
                captured_output.append(output)

            # Execute the restricted code within the restricted context
            exec(restricted_code, safe_globals, {'print': safe_print})

            # Print the captured output directly within the function
            for line in captured_output:
                print(line)

            return '\n'.join(captured_output), None

        except Exception as e:
            error_message = f"Error executing restricted code: {e}"
            print(error_message)
            return None, error_message

    # This is User Input from Node
    user_code = '''
    def restrictedPythonMain():
        try:
            # Attempt to use a restricted operation (e.g., system command or file access)
            restricted_operation = lambda: exec("print('hello world')")
            restricted_operation()
        except:
            # Catch any exceptions that indicate unauthorized access is prevented
            pass
    restrictedPythonMain()
    '''

    result, error_message = execute_restricted_code(user_code)

    if result is None:
        errorHandler = [{'error': str(error_message)}]
        return errorHandler

await __main()

While this code executes successfully, it allows the use of the exec function, which is not intended. I observed the output "hello world" on the console, indicating that restricted functions were not blocked as expected.

However, when the user_code is as follows, an error is thrown due to the use of the exec function, which is the desired behavior:

user_code = '''
def restrictedPythonMain():
    exec("print('hello world')")
restrictedPythonMain()
'''

Could you please advise on what might be incorrect in my implementation? I aim to prevent users from calling functions like exec in any context within the restricted environment.

Thank you for your assistance.

@d-maurer
Copy link
Contributor

d-maurer commented Aug 3, 2024 via email

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

No branches or pull requests

2 participants