简体   繁体   English

如何阻止服务器执行的程序删除文件?

[英]How can I stop programs executed by a server from deleting files?

I am working on a project which is a system where students can submit their coding assignments to a server where the server then executes their code as part of tests and then returns the grades they received based on the results of the tests executed.我正在开发一个项目,这是一个系统,学生可以将他们的编码作业提交到服务器,然后服务器在服务器上执行他们的代码作为测试的一部分,然后根据执行的测试结果返回他们收到的成绩。

There is a security concern that where the student submitting the code could "damage" the server by including code to delete the directory where the system's files are stored.存在一个安全问题,即提交代码的学生可能会通过包含删除系统文件存储目录的代码来“损坏”服务器。 The files are stored in a directory hierarchy where if the student somehow figured out the path to it, they could easily code their program to delete this directory.这些文件存储在一个目录层次结构中,如果学生以某种方式找到它的路径,他们可以轻松地编写程序来删除这个目录。

I have since setup permissions so that the server is run under a different user.从那以后我就有了设置权限,以便服务器在不同的用户下运行。 This user only has access to a single directory that stores all the submissions for that module.该用户只能访问存储该模块所有提交的单个目录。 They could still theoretically wipe out this directory, but it is better than deleting the whole system.他们理论上仍然可以清除该目录,但总比删除整个系统要好。 While it is still not ideal, I am not sure how to approach it.虽然它仍然不理想,但我不知道如何处理它。

The server is coded in Python.服务器编码为 Python。 I have tried using os.chown etc to change the ownership of directories to a single user, however, I found out that the program needs to be run under a superuser to change ownership and also for calls to os.setuid and os.setgid.我曾尝试使用 os.chown 等将目录的所有权更改为单个用户,但是,我发现该程序需要在超级用户下运行才能更改所有权以及调用 os.setuid 和 os.setgid。

Basically, my question is, is there any way to run a program while restricting it to the directory it's running within?基本上,我的问题是,有什么方法可以运行程序,同时将其限制在其运行的目录中? This would involve only allowing it to delete files/folders within its working directory.这将只涉及允许它删除其工作目录中的文件/文件夹。 I know there is a chroot command but that also requires superuser privilegs.我知道有一个 chroot 命令,但这也需要超级用户权限。

It is also not possible to run the program under a different user without sudo privileges either.也不可能在没有 sudo 权限的情况下在其他用户下运行程序。 The programs are executed using subprocess.Popen().程序使用 subprocess.Popen() 执行。

I know it's a long shot as I have tried a lot of research with permissions and the current solution restricting deletion down to the submissions data directory is as far as I could get.我知道这是一个很长的机会,因为我已经尝试了很多具有权限的研究,并且当前的解决方案限制删除到提交数据目录是我所能得到的。 It is still not ideal however and the server will not be allowed to be run with sudo privileges.但是它仍然不理想,并且不允许使用 sudo 权限运行服务器。

If there are any program attributes that can be set to prevent that program from deleting files, it would be great, but I don't think such a system exists.如果可以设置任何程序属性来防止该程序删除文件,那就太好了,但我认为不存在这样的系统。 I may have to resort to "scanning" the submitted code file for dangerous calls and reject the file if there are any such calls in it.我可能不得不求助于“扫描”提交的代码文件以查找危险调用,如果其中有任何此类调用,则拒绝该文件。

The current directory hierarchy is used:使用当前目录层次结构:
.handin/ module-code /data (data is where submissions for each student are stored)` .handin/ module-code /data (数据是每个学生提交的存储位置)`

Currently, the data directory is created with a group handin which allows any members of that group to create directories inside it.目前,数据目录是使用组处理创建的,该组处理允许该组的任何成员在其中创建目录。 With the server running under a user handin, it creates directories/files inside in that data directory with user handin and group handin.随着服务器在用户handin 下运行,它使用用户handin 和组handin 在该数据目录中创建目录/文件。 So, the only files the server could delete as user handin is all directories underneath data, rather than the whole.handin directory.因此,服务器可以作为用户 handin 删除的唯一文件是 data 下的所有目录,而不是整个.handin 目录。

Underneath data, you have directories named from the student ids, eg .handin/ module-code /data/12345678 and underneath that you have a directory with the assignment name.在数据下方,您有根据学生 ID 命名的目录,例如 .handin/ module-code /data/12345678,在其下方,您有一个带有作业名称的目录。 The assignment directory is the directory the code is executed in. It would be ideal if it would be that directory that could only be deleted, but if not, the student-id directory.分配目录是执行代码的目录。如果是只能删除的目录,那么最好是学生ID目录。

So, I have solved the problem using separate Docker containers for each execution.所以,我已经为每次执行使用单独的 Docker 容器解决了这个问题。 I created separate images for different languages in the programs that would be executed in. I then created a user in these containers that had just enough permissions to create/delete files inside their home directory, essentially sandboxing it.我在将要执行的程序中为不同语言创建了单独的图像。然后我在这些容器中创建了一个用户,该用户具有在其主目录中创建/删除文件的足够权限,本质上是沙箱。

I then used the epicbox python module ( https://pypi.org/project/epicbox/ ) which was created by Stepik.org to grade programming assignments in their own containers (very similar to the problem that I needed to solve).然后,我使用由 Stepik.org 创建的 epicbox python 模块 ( https://pypi.org/project/epicbox/ ) 在他们自己的容器中对编程作业进行评分(与我需要解决的问题非常相似)。

That creates a volume internally to allow each docker container that is run to share files:这会在内部创建一个卷,以允许每个运行的 docker 容器共享文件:

    with epicbox.working_directory() as workdir:
      epicbox.run(....)
      epicbox.run(....)
      .....
      epicbox.run(....) 

Each run call spins up a docker container but with the internally created volume, each container can access files produced from the previous call to run().每次运行调用都会启动一个 docker 容器,但使用内部创建的卷,每个容器都可以访问上一次调用 run() 生成的文件。 The module allows you to upload files from your local machine to the docker container and then compile/execute them there.该模块允许您将文件从本地机器上传到 docker 容器,然后在那里编译/执行它们。

I did have to do some "hacks" to configure it to my requirements (change the default working directory in the docker container as epicbox did not provide a method to change it easily).我确实必须做一些“黑客”来将其配置为我的要求(更改 docker 容器中的默认工作目录,因为 epicbox 没有提供轻松更改它的方法)。 This solution adds a few extra seconds to the execution time when compared to executing on the server itself, but for my use case, it is an acceptable trade-off for security.与在服务器本身上执行相比,此解决方案增加了几秒钟的执行时间,但对于我的用例来说,这是一个可接受的安全性权衡。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM