• caglararli@hotmail.com
  • 05386281520

Filter arbitrary code for blacklisted keywords except on commented lines

Çağlar Arlı      -    13 Views

Filter arbitrary code for blacklisted keywords except on commented lines

I have a Rust-app executing Python-scripts using PyO3. The Python-scripts are uploaded by users, so I need to check for unsafe code before executing it. The scripts should only be able to do mathematical operations and in no case should access files, operating system resources, or use network functionalities.

To make sure of this I have blacklisted specific keywords like import, open, os, read, write,... If the user is not able to import his own libraries it'd be pretty hard already to execute e.g network functions.

But these blacklisted words should only be checked on lines not commented. E.g:

import something

def func(data):
    return 0

Is disallowed, but

#import something

def func(data):
    return 0

Should be allowed. My current approach is a Regex deleting all the lines who start with a comment before checking the string for blacklisted keywords.

    // We execute arbitrary Python scripts. Even if this is supposed to be a internal
    // application we need to secure this somehow. We blacklist specific Python keywords like
    // "import", "exec", "os",... so no dangerous code can be executed.
    // We import popular mathematical libraries so those can be used.
    fn arbitrary_code_is_secure(&self, code: &String) -> bool {
        let blacklist = vec![
            "import",
            "open",
            "read",
            "write",
            "file",
            "os",
            "exec",
            "eval",
            "socket",
            "http",
            "requests",
            "urllib",
            "sys",
            "traceback",
        ];

        let re_find_commented_lines = Regex::new(r"^#.*").unwrap();
        let code_without_comments = re_find_commented_lines.replace_all(code, "");

        for keyword in blacklist {
            match code_without_comments.find(keyword) {
                Some(_) => { return false; },
                None => (),
            }
        }

        true
    }

Is this approach somewhat secure? And especially: Could the user manipulate the check for commented lines to import custom libraries anyway?