译者 | 陈峻
审校 | 重楼
软件开发与编程曾经被认为是只有具备深厚专业知识与技能的程序员才能胜任的工作。不过,现在貌似任何人都可以利用自然语言工具来实现并完成了。与此同时,过去那些需要数天、甚至数月才能开发出来的功能,现在完全可以在 AI 模型的代码加持下、在几分钟之内被开发出来。例如,OpenAI的Codex 和 Google的BERT 都是接受过 Web 博客编程和Stack overflow 等方面任务的培训。
目前,许多前卫的技术尝鲜者、以及新晋的 SaaS 提供商,都在利用 AI 工具来使其产品更加智能化。SaaS 程序员也在不断探索基于 AI SaaS 工具的生成式代码的输出。不过,一些智能模型在通过数学概率演算创建代码的同时,也被发现会产生幻觉,甚至呈现了虚假的信息。学术界曾进行过一项研究并发现:由AI 生成的代码,往往会包含OWASP 10 大经典漏洞,而且有近 40% 的代码存在安全漏洞。
哪些会导致 AI 生成的代码不安全?
常言道,编程标准的遵循和代码的质量决定了软件的安全性。可是,AI 模型主要是根据互联网上不同程度的可用信息,加以训练来生成代码。因此,代码质量、可靠性、安全性等方面都可能与人类开发生成的代码有所不同。例如,由 Web 开发示例训练出的模型,很可能包含着欠缺的数据验证实践。而当模型生成的代码采用相同的不良实践时,这种验证上的不足很可能会导致系统中后续运行过程中的安全问题。
5项表明代码包含安全漏洞的指标
无论参数量级是百万、还是十亿,已知的模型都会产生幻觉,并以此做出错误的预测。而当普通的开发人员在审阅由 AI 生成的代码时,他们很可能会错过那些细微、但影响严重的安全漏洞。然而,对于那些完全了解设计和开发模式的资深开发人员来说,他们则可以从如下方面及时发现漏洞,并与 SaaS 安全的最佳实践保持一致。
1. 未强制执行类型推理和输入验证
如今,现代化的框架和代码库已严重依赖接口和枚举的方式,进行各种推理和验证。这在某种程度上保证了代码能够准确地完成其任务并保证安全性。然而,除非我们准确指导 AI 去生成代码,否则它们不会去执行各种缜密的推理。而且,即使在我们精心设计了提示,类型不匹配和验证执行也可能无法与用例相匹配(请参见如下代码段)。因此,为了能够查找和修正代码中的错配之处,开发人员必须充分了解其对应的代码域、以及具体的业务要求。
复制def reciprocal(user_input): # Insecure implementation with no type inference or validation result = 100 / user_input return result
2. 类/对象之间的非标准状态和上下文共享
众所周知,程序是以公共/私有/受保护(Public/Private/Protected) 等方式,来共享各种对象的。高阶功能函数和类往往通过直接访问公共/受保护的变量,来执行计算,进而继承对象的状态。如果在实施或执行中出现了错误,那么应用的安全性、以及性能瓶颈就会随即出现(请参见如下代码段)。对此,SaaS 开发人员必须认真地审查其共享状态和上下文的管理逻辑,以确保正确、安全的代码实现。
复制class InsecureClass: def __init__(self, owner, balance, password): self.owner = owner # Public attribute self._balance = balance # Protected attribute self.__password = password # Private attribute # Public def def get_balance(self): return self._balance # Protected def def _update_balance(self, amount): self._balance += amount # Private def def __validate_password(self, input_password): return self.__password == input_password # Insecure def exposing private data def insecure_password_exposure(self): return self.__password
3. 数据处理和共享技术的弱实施
系统中的各项服务往往需要通过网络来共享和接收信息。现如今,安全连接和数据处理对于基于云服务的系统来说尤为重要。就代码而言,我们在需要通过分布式的数据网络来读取、处理和共享组织中的敏感数据时,必须采用强大的处理协议和安全技术,以防止数据被截获。因此,在使用 AI时,SaaS 开发人员必须在成熟的应用程序中杜绝在架构层面上的数据不安全共享。下面的代码段便是一个典型的例子:
复制#Insecure Data Sharing @app.route("/user/<int:user_id>", methods=["GET"]) def get_user(user_id): user = users.get(user_id) if user: return jsonify(user) # All user data exposed, including secrets # Insecure Data Handling @app.route("/update_email", methods=["POST"]) def update_email(): data = request.json() user_id = data.get("user_id") new_email = data.get("new_email") if user_id in users: users[user_id]["email"] = new_email # No validation of new_email return jsonify({"message": "Email updated successfully"})
4. 密钥和身份验证处理不足
在如今复杂的网络环境中,实施严格的基于角色的访问控制(RBAC)是保障合理的身份与权限匹配关系,保持隐私与合规性的必要条件。而当程序代码由AI大语言模型(LLM)生成时,其默认机制便是通过基础的身份验证,便可提供程序的连接和授权。显然,这种简单的解决方案不足以在有新的网络威胁出现时,仍保持必要的安全态势(请参见如下代码段)。为此,开发人员在新增自定义函数与功能时,必须进行全面的测试,以确保密钥的安全性和身份验证的处理得到了妥善的实施。
复制# Insecure authentication @app.route("/login", methods=["POST"]) def login(): data = request.json() email = data.get("email") password = data.get("password") for user_id, user in users.items(): if user["email"] == email and user["password"] == password: return jsonify({"message": "Login successful", "user_id": user_id})
5. 过时的依赖项和已弃用的功能
如今由社区创建的开源库和框架在代码中占比并不少。不过,由于可供AI训练的数据的局限性,以及可能并非最新,这便导致了AI 编程模型在训练过程中,其知识停滞不前,无法获悉最新的版本。而随着技术的发展,许多功能将会过时,一些依赖库也将跟不上版本的迭代(请参见如下代码段)。因此,SaaS 开发人员需要仔细审查并确保使用有效的依赖项,进而保障整体的安全性、以及功能上的适用性。
复制import md5 # Outdated library def insecure_hash_password(password): # Insecure password hashing done using the deprecated MD5 algorithm. return md5.new(password).hexdigest()
使用AI 生成代码的安全提示
说到底,由大语言模型的高级编码所生成的代码,需要符合既定的安全性和编程标准。总体而言,我们可以通过如下5个方面,采取简单的检查,以确保 AI 生成代码的安全与合规。
- 与安全和架构团队一起进行代码审查,并将其作为软件开发生命周期的标准部分。
- 将自动化安全测试和验证步骤集成到版本控制的工具中。
- 在测试的 KPI 中包含依赖关系和合规性检查。
- 采用带有静态和动态安全测试工具的零信任技术架构。
- 利用 DevSecOps 的优秀实践和防范影子 AI。
使用Github Action处理不安全的 AI 生成代码
无论人工多么仔细地去审查和审计AI生成的代码,人为疏漏还是存在的。因此,我们需要一些预定义的检查,以便在代码进入版本控制系统之后,立即对其开展测试和验证。在此,我们可以引入 Github Action,自动运行安全和质量检查(请参见如下代码段)。
复制name: Simple Security Checks for AI generated Code on: push: branches: - main pull_request: branches: - main jobs: security-and-quality-check: runs-on: ubuntu-latest Steps: - name: Repository checkout uses: actions/checkout@v3 - name: Python setup uses: actions/setup-python@v4 with: python-version: ">=3.9" - name: Dependency installation run: | python -m pip install --upgrade pip pip install bandit pytest - name: Identifying insecure libraries and patterns run: | echo "Checking for insecure patterns..." if grep -r "md5.new(" .; then echo "ERROR: Insecure MD5 hashing detected. Use hashlib.sha256 or bcrypt instead." exit 1 fi echo "No insecure patterns detected." - name: Scanning for security vulnerabilities run: | echo "Running Bandit security scanner..." bandit -r . - name: Running unit tests run: | echo "Running unit tests..." pytest test/unit --cmodopt=local - name: Notifying on failure if: failure() run: | send_slack_notification(“Unsafe code merge detected, fix immediately”)
小结
综上所述,大语言模型可谓 SaaS 开发人员使用自然提示语言生成代码和信息的实用工具之一。不过,它们也会带来了各项安全风险,并且有时会提供不适合企业需求的低性能代码。对此,SaaS 开发人员应加倍小心。希望上述讨论能够给你提供确保AI生成代码安全态势的有力参考,并能在你的日常工作中被实践。
译者介绍
陈峻(Julian Chen),51CTO社区编辑,具有十多年的IT项目实施经验,善于对内外部资源与风险实施管控,专注传播网络与信息安全知识与经验。
原文标题:Is Your AI-Generated Code Really Secure?,作者:Daniel