当前位置: 代码网 > it编程>前端脚本>Python > 基于Python AST实现代码安全检测功能

基于Python AST实现代码安全检测功能

2025年12月03日 Python 我要评论
在某些场景下(在线代码执行平台、脚本上传平台、自动任务系统等),我们必须限制用户代码中危险模块(如 os、sys、socket)以及危险函数(如 eval、exec)的使用,否则会带来安全风险。本文介

在某些场景下(在线代码执行平台、脚本上传平台、自动任务系统等),我们必须限制用户代码中危险模块(如 ossyssocket)以及危险函数(如 evalexec)的使用,否则会带来安全风险。

本文介绍一种 基于 python ast(抽象语法树) 的代码安全检查方案,并给出完整示例代码,适用于实际生产环境。

一、为什么使用 ast

常见的字符串匹配方式容易被绕过,例如:

e = ev
b = al
(e + b)("print(123)")

而 ast 解析后,所有语句都会被解析成结构化节点,从根本上杜绝字符串拼接绕过的可能性。

二、完整检测代码

下面是完整的 ast 检测类 checkfun

import ast

class checkfun(ast.nodevisitor):
    def __init__(self):
        super().__init__()
        self.ban_moudel = [
            "os",
            "sys",
            "socket",
            "multiprocessing",
            "requests",
        ]
        self.ban_func = ["exec", "eval"]
        self.allow = true
        self.res = []

    def visit_import(self, node):
        # 禁止导入模块
        for item in node.names:
            if item.name in self.ban_moudel:
                self.allow = false
                self.res.append("不允许导入 %s 包" % item.name)

    def visit_assign(self, node):
        # 禁止赋值后调用危险函数,如 b = eval
        try:
            if node.value.id in self.ban_func:
                self.allow = false
                self.res.append("赋值右侧不允许出现 %s" % node.value.id)
        except:
            pass

    def visit_call(self, node):
        # 禁止直接调用 eval、exec
        try:
            if isinstance(node.func, ast.name):
                if node.func.id in self.ban_func:
                    self.allow = false
                    self.res.append("不允许调用 %s" % node.func.id)
        except:
            pass

    def visit_importfrom(self, node):
        # 禁止 from xxx import xx
        if node.module in self.ban_moudel:
            self.allow = false
            self.res.append("不允许导入 %s 包" % node.module)


def test_function(fn_str):
    root_node = ast.parse(fn_str)
    ckf = checkfun()
    ckf.visit(root_node)
    if ckf.allow:
        print("allow")
    else:
        print("unallow")
        for item in ckf.res:
            print(item)

三、测试示例

示例一:包含危险模块和危险函数的代码

func2 = """
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
b=eval
b(123)
eval(321)
def aaaaaa(text):
    import sx
    import sys
    print(1)
    return re.search(r"\d+", text).group(0)
"""

检测执行:

test_function(func2)

输出示例:

e = ev
b = al
(e + b)("print(123)")

四、从文件读取并检测

如果需要从外部文件读取用户代码并检测,可以这样写:

with open('./tmp/' + args[1], 'r') as f:
    root_node = ast.parse(f.read())
    ckf = checkfun()
    ckf.visit(root_node)
    if ckf.allow:
        print("allow")
    else:
        print("unallow")

五、实际应用场景

该方式非常适合:

  • 在线代码执行平台
  • webide / 教程平台
  • 自动 python 任务系统
  • 安全沙箱
  • 禁止用户访问系统资源的场景

因为 ast 是结构化的,无法通过字符串拼接绕过,是目前最可靠的静态检测方式之一。

到此这篇关于基于python ast实现代码安全检测功能的文章就介绍到这了,更多相关python代码检测内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com