Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django-允许用户运行自定义python代码_Python_Django - Fatal编程技术网

Django-允许用户运行自定义python代码

Django-允许用户运行自定义python代码,python,django,Python,Django,我似乎找不到答案的简单问题: django中是否有一种方法允许用户在文本框中编写自己的自定义代码,并在稍后或单击按钮时执行代码? 我的意思是,在w3scools中也实现了同样的功能: 我不需要能够在第二个屏幕或任何东西中可视化结果。目标是允许用户编写一些基本但自定义的功能 假设用户可以访问字典,并且希望转换其中一个键的值: e、 g 用户可以创建一个自定义键3,它是其他两个键的串联 _dict['key3'] = _dict['key!'] + _dict['key2'] 因此,这里我必须公

我似乎找不到答案的简单问题: django中是否有一种方法允许用户在文本框中编写自己的自定义代码,并在稍后或单击按钮时执行代码? 我的意思是,在w3scools中也实现了同样的功能:

我不需要能够在第二个屏幕或任何东西中可视化结果。目标是允许用户编写一些基本但自定义的功能

假设用户可以访问字典,并且希望转换其中一个键的值: e、 g

用户可以创建一个自定义键3,它是其他两个键的串联

_dict['key3'] = _dict['key!'] + _dict['key2'] 
因此,这里我必须公开包含字典的变量,并允许用户编写自定义python代码,以便对其执行任何操作。或者在运行时将自定义代码嵌入到实际代码中


目前,安全性不是一个问题,但了解如何处理这一问题很有趣。

让用户输入在您的服务器上执行是一个非常巨大的安全风险

例如,用户可以编写代码,尝试删除在硬盘上找到的所有文件,或者删除django服务器可以访问的所有数据库中的所有条目

短!这是一个危险的想法,除非您信任所有可以访问服务器的人。虽然通常你甚至不应该相信自己-

但从技术上讲,这是非常简单的

您可以使用表单,在表单中填写文本,django将表单数据解析为任何其他表单字段

例如,如果字符串是

import os, glob
for fname in glob.glob("/www/data/uploads/*"):
    os.unlink(fname)
包含该字符串的变量名为code_to_execute

然后,您可以在django视图中调用execcode_to_execute,以允许用户删除上载到/www/data/uploads的所有文件

也许有更好的方法,一个更安全的解决方案来实现您所需要的。 用户应该能够实现什么样的功能

为了让事情变得更难,你可以做一些不同的事情

您有一个单独的、应该从dict中删除的密钥列表,您可以有一对密钥名和表达式来计算密钥名。表达式将使用eval而不是exec进行计算

我不会说,这给了您100%的安全性,但比允许exec更安全

因为您只能实现表达式,并且可以限制可用的符号

import os

from math import pi

user_data = [
    {"name": "item1", "location": "place1", "shape": "rectangle", "width": 5, "height": 2},
    {"name": "item2", "location": "place2", "shape": "circle", "radius": 3},
    {"name": "item3", "location": "place1", "shape": "square", "width": 5},
    {"name": "item4", "location": "place2", "shape": "rectangle", "width": 3, "height": 2},
    {"name": "item5", "location": "place1", "shape": "circle", "radius": 2},
    {"name": "item6", "location": "place3", "shape": "triangle", "width": 2, "height": 5},
    ]

### That's what you would get from a web form
### formula to calculate a dict, that will be used to update an entry
userinput = """
{"area": item["radius"] ** 2 * pi,
 "comment": "I love circles",
}
if item["shape"] == "circle"
else (
{"area": item["width"] ** 2,
 "comment": "squares aren't too bad"}
if item["shape"] == "square"
else (
{"area": item["width"] * item["height"],
 "comment": "I don't really like rectangles"}
if item["shape"] == "rectangle" else
{"area": "?",
 "comment": "never heard of a %s" % item["shape"]}
))
"""
userinput = userinput.replace("\n"," ")

for item in user_data:
    print("    ", item)
    user_rslt = eval(
        userinput,
        {"__builtins__":{}, "pi": pi}, # add any other functions, that should be allowed
        {"item": item},
        )
    if user_rslt:
        item.update(user_rslt)
        print("--->", item)

你有没有想过这个问题?如果用户需要做某些特定的事情,请使用自己的代码来处理这些情况,而不是打开整个代码库进行攻击。您可以使用eval,但我强烈建议您不要使用。谢谢您的回答,我知道其中的风险!目标是允许用户在应用于所有数据的lambda函数中修改/添加/删除记录/列数据。在我以前的一个项目中,出于安全考虑,我们用非常有限的函数构建了自己的编程语言,但我不想落入同一个陷阱!添加了一个解决方案,至少更安全一点。仅供参考。您甚至可以使用exec并禁用导入,方法是将globals参数中的{uu内置项{uu}设置为{},然后只提供希望用户使用的任何符号。这样就更容易创建可读性好的代码了。看起来这是一个很好的处理方法!谢谢你的帮助,我会努力实现的
import os

from math import pi

user_data = [
    {"name": "item1", "location": "place1", "shape": "rectangle", "width": 5, "height": 2},
    {"name": "item2", "location": "place2", "shape": "circle", "radius": 3},
    {"name": "item3", "location": "place1", "shape": "square", "width": 5},
    {"name": "item4", "location": "place2", "shape": "rectangle", "width": 3, "height": 2},
    {"name": "item5", "location": "place1", "shape": "circle", "radius": 2},
    {"name": "item6", "location": "place3", "shape": "triangle", "width": 2, "height": 5},
    ]

### That's what you would get from a web form
### formula to calculate a dict, that will be used to update an entry
userinput = """
{"area": item["radius"] ** 2 * pi,
 "comment": "I love circles",
}
if item["shape"] == "circle"
else (
{"area": item["width"] ** 2,
 "comment": "squares aren't too bad"}
if item["shape"] == "square"
else (
{"area": item["width"] * item["height"],
 "comment": "I don't really like rectangles"}
if item["shape"] == "rectangle" else
{"area": "?",
 "comment": "never heard of a %s" % item["shape"]}
))
"""
userinput = userinput.replace("\n"," ")

for item in user_data:
    print("    ", item)
    user_rslt = eval(
        userinput,
        {"__builtins__":{}, "pi": pi}, # add any other functions, that should be allowed
        {"item": item},
        )
    if user_rslt:
        item.update(user_rslt)
        print("--->", item)