Question: We recently had issues with people messing around inside our system. To prevent code injections within my python code, I implemented the following `if` block:

```
#! /usr/bin/python3
#-*- coding:utf-8 -*-
def main():
    print("Your interactive Python shell!")
    text = input('>>> ')
    for keyword in ['eval', 'exec', 'import', 'open', 'os', 'read', 'system', 'write']:
        if keyword in text:
            print("You are not allowed to do this!")
            return;
    else:
        exec(text)
        print('Executed your code!')
if __name__ == "__main__":
    main()

```

A few (user) people can run this python file with sudo rights inside our Ubuntu system. I know this sounds like a security hole, but I don't see any possibility to escape from this. Is there any possibility to inject inside my code block? Do you have any tips to prevent code injections?

Answer: 
Simple blacklists are about the worst way to patch a vulnerability. They'll create a lot of false positives and any determined attacker will usually find a way around them.

Web Application Firewalls are a good example. The detection rules they employ are way more complicated than your simplistic blacklist, yet they don't catch everything, and every now and then, bypasses come up for things they *are* supposed to catch.

> 
> I don't see any possibility to escape from this.
> 
> 
> 

Or so you think. You just haven't looked long enough.

```
vars(__builtins__)['ex'+'ec']("print('pwned')")
```

This sails right through your filter. It calls the `exec()` function which then goes on to print '*pwned*'.

Now you can modify your blacklist to catch this as well, but someone else will come up with another way.

---

99% of the time I see someone using something like `exec` or `eval`, it's completely unnecessary. If you can avoid using `exec`, do yourself a favor and get rid of this vulnerability waiting to be exploited. If, however, you absolutely **need** to use `exec`, then do as @amon [suggested in the comments](https://security.stackexchange.com/questions/246157/does-blocking-keywords-prevent-code-injection-inside-this-interactive-python-fil#comment506935_246157): Create a new pipe, fork and drop as many privileges in the child as possible, and then execute the code. Use the pipe to communicate between the child and the parent processes. Or [sandbox it](https://security.stackexchange.com/questions/216372/how-to-sandbox-students-python-3-code-submissions-for-automatic-assignment-eval) as Steffen Ullrich suggested.
The problem I see with your blacklist is that in Python, one could write Python code that generates additional Python code, and then run the additional code. So one could generate the word 'eval' from inside of a program that itself doesn't contain the word. Part of the problem is the dynamism of Python itself, whereas a more strongly typed, static language might be safer.

The Computer Science Theory way of accepting a valid string is by constructing a grammar, and then using a grammar parser.

<https://en.wikipedia.org/wiki/Formal_grammar>

You'd need to understand how grammar parsers work in order to construct one.
However, in this case your grammar parser would be a subset of python's grammar parser itself, so it would be a lot of work, if you had unlimited resources I'd go for it but otherwise don't pick this solution.