Securing LangChain Agents
Add AgentCop scanning, monitoring, and execution gating to your LangChain agents.
Common LangChain vulnerabilities
LangChain is the most widely-deployed agent framework — and one of the most frequently exploited. The patterns below appear repeatedly in production codebases.
- Prompt injection via user input — user-controlled strings passed directly into ReAct prompts without sanitization or parameterization
- eval() on LLM output — seen in LangChain expression parsers and output parsers that interpret model-generated code
- ShellTool without an execution gate — exposes the host OS to any instruction the LLM produces
-
CVE-2025-68664 — LangChain arbitrary code execution via eval in output parser
CVE-2025-68664
Affected LangChain versions prior to 0.2.14. The
StructuredOutputParsercalledeval()on LLM-generated content without sandboxing. Patch: upgrade to ≥ 0.2.14 and add an ExecutionGate.
Scanning a LangChain agent
Run the AgentCop scanner against your agent file before deploying. This catches static issues — hardcoded keys, eval calls, injection patterns — that would otherwise reach production.
# 1. Scan before deploy
import httpx
with open("my_langchain_agent.py") as f:
code = f.read()
result = httpx.post("https://api.agentcop.live/api/scan", json={
"code": code,
"description": "LangChain ReAct agent with web search and calculator"
}).json()
print(f"Score: {result['trust_score']}/100")
# Check: result['issues'] for specific findings
AgentBob's vulnerable LangChain pattern
This is what not to do. AgentBob's agent passes user input directly into the prompt and exposes a shell tool with no gate — two critical vulnerabilities that work together.
# AgentBob's LangChain agent — full of issues
from langchain.agents import initialize_agent, AgentType
from langchain.tools import ShellTool
from langchain_openai import ChatOpenAI
# LLM01: user_input injected directly into prompt
def run_agentbob(user_input: str):
agent = initialize_agent(
tools=[ShellTool()], # LLM08: shell tool without gate
llm=ChatOpenAI(),
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
)
# No sanitization, no gate, no monitoring
return agent.run(f"Complete this task: {user_input}") # LLM01
Safe LangChain pattern with AgentCop
The safe version uses a PromptTemplate to isolate user input as a parameter — it never touches the instruction structure. The commented gate lines show where runtime enforcement slots in once the AgentCop runtime module is installed.
from langchain.agents import initialize_agent, AgentType
from langchain.tools import DuckDuckGoSearchRun
from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplate
# from agentcop import ExecutionGate, GatePolicy # Runtime module
llm = ChatOpenAI()
tools = [DuckDuckGoSearchRun()]
# Safe: parameterized prompt prevents injection
prompt = PromptTemplate(
template="You are a research assistant. Answer: {question}",
input_variables=["question"]
)
# Gate blocks unauthorized tools (runtime module)
# gate = ExecutionGate(policy=GatePolicy(
# allow=["duckduckgo_search"],
# block=["shell", "file_write"]
# ))
agent = initialize_agent(
tools=tools,
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
)
def run_safe_agent(user_question: str):
# user_question is a parameter, not concatenated
return agent.run(prompt.format(question=user_question))
CI integration
Gate merges on trust score. The workflow below fails the build if any agent scores below 75, blocking vulnerable code from reaching production.
# .github/workflows/security.yml
name: AgentCop Security Scan
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with: { python-version: '3.11' }
- run: pip install agentcop
- run: agentcop scan agents/ --min-score 75 --output json > scan_results.json
- uses: actions/upload-artifact@v3
with:
name: agentcop-results
path: scan_results.json
Checklist
- No f-string interpolation of user input into prompts
- Use PromptTemplate with input_variables
- No ShellTool without an ExecutionGate
- No eval() on agent output
- API keys from environment variables, never hardcoded
- Trust Score ≥ 75 in CI