This question is how to have a python script that other (non-root) users can run but not inspect.
Example use case:
#!/usr/bin/env python
import requests
params = { 'user':'fred', 'password':'123' }
url = 'https://.......'
print(requests.get(url, params).content)
In this example (but it is only an example), I want to let users run the script in order to get the web content that was fetched, but not see the credentials that were used to fetch that content.
Setting execute permission but not read permission does not achieve the same result that it does for a compiled executable. Here is a "hello world" example.
In C:
$ cat test.c
#include <stdio.h>
int main() {
puts("secret message");
return 0;
}
$ gcc -o secret test.c
$ chmod 711 secret
$ sudo -u nobody ./secret
secret message
$ sudo -u nobody strings ./secret
strings: ./secret: Permission denied
In Python:
$ cat test.py
#!/usr/bin/python
print("secret message")
$ chmod 711 test.py
$ sudo -u nobody ./test.py
/usr/bin/python: can't open file './test.py': [Errno 13] Permission denied
(Of course the python
executable itself could be set to octal mode 711, but this is not the thing that I want to protect.)
So then, what can I do about it?
Possible solutions I thought about, but I think won't work:
(1) Translate the entire Python program into C.
Possible in principle but not a practical solution. Even for this simple example, it would mean having to look for an equivalent of the requests
library.
(2) Have a helper C program that is called by Python.
What should the helper C program actually do though? If it just prints the password, then the user can run it directly to obtain the password. If it also fetches the web page (in this example) then we are back to problem 1.
(3) Have a C program that starts python and passes the secret data to python:
(a) via the command line
ps
or /proc/<pid>/cmdline
(b) via the environment
ps
or /proc/<pid>/environ
(c) via standard input
(d) via a named pipe
killall -STOP python
in a tight loop, then with the python process suspended it is trivial to win the race to read from the named pipe)Actually I did think of one other thing - an adaptation of 3c - a C program forks and execs a python process and sends to it (via stdin) a secret followed by the data from its own stdin. The python process starts by reading the secret, and is then free to read other user input from stdin. But all this it is starting to seem clunky (we now have this extra process sitting there copying data from stdin for the duration of the python process) and anyway I have no clue how to write such a C program.
What can I do please?
Can you not use your Python code as an interpreted script, but compile it into command-line executable? It is similar to your first proposed solution, but in that case it would not be needed to compile .py file into .c file, and then .c file into executable. You will compile .py file directly into executable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With