Patching Detected Vulnerabilities with Factory AI and Snyk Studio
Programming with Factory AI’s Droids feels great. It’s cohesive, it’s smooth, it’s juicy; it feels like playing a game. One can sense their commitment to this ideal not just in their UI, but also in their partnerships – one key integration being with Linear (which is Jira’s younger competitor with a reputation for enriched UX via reactive web app animations and keyboard shortcuts). If tools like Claude Code, OpenAI Codex, and Gemini CLI are an offline Word document, then Factory AI’s offering is an online Google Drive built from the start with collaborative teams in mind.

Their developer journey includes a well-made tutorial built into their website, which guides you step by step to:
Download the Factory CLI
Add the Droid IDE Extension to VS-Code or your fork of choice (i.e., Cursor or WindSurf)
Give your Droid (Factory AI’s specialized AI Agents) its first task, in the browser or in the IDE.
If you’re on Linux, you can install the Factory CLI like so:
curl -fsSL https://app.factory.ai/cli | shThe extension for VSCode is available here. Once installed, you can use `Ctrl-Shift-P` to open the Command Palette and select Run Factory Droid.

What’s in a Droid?
Factory AI offers specialized AI agents for a breadth of common software development tasks. These are referred to as Droids.

Code Droid: Go from idea to merge-ready code changes. Write new features or components with clear requirements, leveraging Code Droid's ability to understand your codebase and implement functionality that follows your project's patterns and best practices. Improve existing code by identifying complex or inefficient patterns and transforming them into cleaner, more maintainable solutions while preserving functionality and enhancing performance. Analyze error logs, identify root causes, and develop fixes for bugs in your codebase. Create comprehensive unit tests to ensure code reliability and prevent regressions in your applications.
Knowledge Droid: Engineering research, technical documentation, and onboarding guides. Generate comprehensive documentation for your codebase, including API references, architecture overviews, and component relationships to improve team understanding and onboarding. Get clear explanations of complex systems, architectural decisions, and implementation details within your projects to help team members understand how different components interact. Quickly find and extract specific information from your codebase and documentation, saving time when looking for implementation details or understanding particular features.
Reliability Droid: Investigate incidents, write RCAs, and debug complex multi-service systems. Analyze production incidents by examining error logs, metrics, and system behavior to quickly identify patterns and potential causes of outages or performance degradation. Create comprehensive Root Cause Analysis documents that include timeline, impact assessment, root cause identification, and preventative measures to share with stakeholders. Develop robust error handling mechanisms, including circuit breakers, retry logic, and graceful degradation patterns to improve system resilience and prevent cascading failures.
Product Droid: Plan features, create PRDs, and manage your projects. Generate detailed Product Requirements Documents with feature overviews, user stories, acceptance criteria, technical considerations, and implementation phases for new product features. Create comprehensive user stories with detailed acceptance criteria for different user types and scenarios, helping development teams understand feature requirements from the user perspective. Analyze feature requests and develop prioritization frameworks with impact vs. effort assessments to help product teams make informed decisions about implementation order.
This contemporary approach to AI agents – to offer a library of pre-built and specialized agents – allows users to make the most of their LLMs’ limited context windows. While the singular agent offered by tools like Claude Code, OpenAI Codex, and Gemini CLI “can” be versatilely applied to a similar breadth of tasks, Factory AI has put the time into providing developers with an agent that can do so with expert management of its context for its very particular purpose. That’s not to exclude the general-purpose Droid that is also included in their library, which you can of course rely on for any purpose not covered by the specially prepared set of Droids.
Happily, Factory AI does not lock you into any single LLM vendor. The most well-known vendors are readily available (see below). And for LLMs with unique variants for things like reasoning, you can easily make your choice in the same UI dialog.

MCP support
Similar to other AI agent CLIs, Droid CLI offers fantastic Model Context Protocol (MCP) support. Adding your favorite MCP server is easy:
█████████ █████████ ████████ ███ █████████
███ ███ ███ ███ ███ ███ ███ ███ ███
███ ███ ███ ███ ███ ███ ███ ███ ███
███ ███ █████████ ███ ███ ███ ███ ███
███ ███ ███ ███ ███ ███ ███ ███ ███
███ ███ ███ ███ ███ ███ ███ ███ ███
█████████ ███ ███ ████████ ███ █████████
v0.19.9
You are standing in an open terminal. An AI awaits your commands.
ENTER to send • \ + ENTER for a new line • @ to mention files
Current folder: /home/owler/Documents/Snyk/snyk-mcp-demos/pygoat
Auto (Low) - edits and read-only commands shift+tab cycles Sonnet 4
╭─────────────────────────────────────────────────────────────────────╮
│ > Try "Search the documentation for this library" │
╰─────────────────────────────────────────────────────────────────────╯
? for help IDE ◌ | MCP ✓
● Usage: mcp add [options] <name> <command>
Add a new MCP server to the configuration
Arguments:
name Server name
command Command to start the server
Options:
-e, --env <key=value...> Environment variables (can be used multiple
times)
--transport <type> Transport type (defaults to "stdio") (default:
"stdio")
-h, --help display help for command
shift+tab to cycle modes Sonnet 4
╭────────────────────────────────────────────────────────────────────────────────╮
│ > /mcp add -h │
╰────────────────────────────────────────────────────────────────────────────────╯
? for help IDE ◌
For example, the official Snyk MCP Server can be added like so from within the Droid CLI, assuming it is already installed on your machine:
/mcp add SNYK "snyk mcp -t stdio"
● Starting MCP server "SNYK"...
Command: snyk
Args: ["mcp","-t","stdio"]
Environment variables: noneBut what can we do with this? What would be the benefit of extending the toolset available to an already-capable Droid? Support for running shell commands, reading, writing, and editing files is already built in.
Using AI agents (Droids) to automatically patch vulnerabilities
For this example, I’ve cloned OWASP Project Leader adeyosemanputra’s pyGoat repository. This project intentionally includes a series of well-documented vulnerabilities for educational purposes. Here are some of the vulnerabilities highlighted by Snyk’s own IDE extension:

We can also ask Droid to use the MCP server to list some of those same vulnerabilities. See:
> Please run a code scan on the codebase with Snyk.
⛬ I'll help you run a Snyk code scan on the pygoat codebase. Let me first check the
authentication status and then perform the scan.
PLAN Updated: 3 total (2 pending, 1 in progress, 0 completed)
○ Check Snyk authentication status
○ Run Snyk code scan on pygoat codebase
○ Review and report scan results
[MCP] SNYK:SNYK_AUTH_STATUS
↳stephen.thoemmes
⛬ Great! You're authenticated as stephen.thoemmes. Now I'll run the Snyk code scan on
the pygoat codebase to identify security vulnerabilities.
PLAN Updated: 3 total (1 pending, 1 in progress, 1 completed)
○ Check Snyk authentication status
○ Run Snyk code scan on pygoat codebase
○ Review and report scan results
[MCP] SNYK:SNYK_CODE_SCAN (/home/owler/Documents/Snyk/factory/pygoat)
↳
Testing /home/owler/Documents/Snyk/factory/pygoat ...
✗ [Low] Use of Hardcoded Credentials
Path: introduction/playground/A9/api.py, line 17
Info: Do not hardcode credentials in code. Found hardcoded credential used in a
condition.
…
✗ [High] SQL Injection
Path: introduction/views.py, line 871
Info: Unsanitized input from an HTTP parameter flows into
introduction.models.sql_lab_table.objects.raw, where it is used in an SQL query. This
may result in an SQL Injection vulnerability.
…
✔ Test completed
Organization: stephen.thoemmes
Test type: Static code analysis
Project path: /home/owler/Documents/Snyk/factory/pygoat
Summary:
101 Code issues found
15 [High] 44 [Medium] 42 [Low]
PLAN Updated: 3 total (0 pending, 0 in progress, 3 completed)
○ Check Snyk authentication status
○ Run Snyk code scan on pygoat codebase
○ Review and report scan results
⛬ The Snyk code scan has completed successfully! Here's a summary of the security
findings:
Scan Results Summary
Total Issues Found: 101
• 15 High severity vulnerabilities
• 44 Medium severity vulnerabilities
• 42 Low severity vulnerabilities
Key High-Severity Issues Found:
1. SQL Injection - Multiple instances in views.py
2. Code Injection - eval() usage with unsanitized input
3. Command Injection - subprocess.Popen with unsanitized input
4. Path Traversal - File operations with unsanitized paths
5. XML External Entity (XXE) Injection - Insecure XML parsing
6. Deserialization vulnerabilities - pickle.loads and yaml.load with untrusted data
7. Hardcoded cryptographic keys - JWT keys hardcoded in source
8. Hardcoded secrets - Non-cryptographic secrets in code
Medium/Low Severity Issues:
• Hardcoded passwords and credentials
• CSRF protection disabled on multiple endpoints
• Insecure cookie configurations (missing HttpOnly/Secure flags)
• Weak hashing algorithms (MD5)
• Debug mode enabled in production
• SSRF vulnerabilities
This is a comprehensive security assessment showing that pygoat (being a
deliberately vulnerable application for educational purposes) contains numerous
intentional security flaws across all severity levels, making it an excellent
training platform for learning about web application security vulnerabilities.
```
Finally, with the Code Droid selected, we can ask the LLM to patch one of these high-priority vulnerabilities.
```bash
> ✗ [High] SQL Injection
Path: introduction/views.py, line 871
Info: Unsanitized input from an HTTP parameter flows into
introduction.models.sql_lab_table.objects.raw, where it is used in an SQL query.
This
may result in an SQL Injection vulnerability. Can you fix this vulnerability and
then re-scan to show that it is fixed?
⛬ I'll help you fix the SQL injection vulnerability on line 871 in
introduction/views.py and then re-scan to verify the fix. Let me first examine the
vulnerable code.
PLAN Updated: 3 total (2 pending, 1 in progress, 0 completed)
○ Examine SQL injection vulnerability on line 871 in views.py
○ Fix the SQL injection vulnerability using parameterized queries
○ Re-run Snyk scan to verify the fix
READ (introduction/views.py, offset: 860, limit: 20)
↳ Read 22 lines.
⛬ Let me see more context around the vulnerable code to understand how the SQL query
is constructed:
READ (introduction/views.py, offset: 840, limit: 40)
↳ Read 42 lines.
⛬ Now I can see the vulnerability clearly. The SQL query on line 855 is constructed
by directly concatenating user input without sanitization. Let me also check the
imports to see what model is being used:
GREP ("from.*models import|import.*mo...", content mode)
↳ Read 1 line.
GREP ("sql_lab_table", content mode)
↳ Read 7 lines.
⛬ Perfect! Now I understand the vulnerability. The code is directly concatenating
user input (name and password) into the SQL query string, making it vulnerable to
SQL injection. Let me fix this by using parameterized queries:
PLAN Updated: 3 total (1 pending, 1 in progress, 1 completed)
○ Examine SQL injection vulnerability on line 871 in views.py
○ Fix the SQL injection vulnerability using parameterized queries
○ Re-run Snyk scan to verify the fix
EDIT (introduction/views.py)
↳ Succeeded. File edited. (+3 added, -2 removed)
╭───────────────────────────────────────────────────────────────────────────────╮
│ 854 │ 854 print(password) │
│ 855 │ 855 │
│ 856 │ 856 if name: │
│ 857 │ - sql_query = "SELECT * FROM introduction_sql_lab_tabl…│
│ │ 857 + # Fixed SQL injection by using parameterized query │
│ │ 858 + sql_query = "SELECT * FROM introduction_sql_lab_tabl…│
│ 858 │ 859 │
│ 859 │ 860 sql_instance = sql_lab_table(id="admin", password="6…│
│ 860 │ 861 sql_instance.save() │
│ │
│... 7 unchanged lines ... │
│ │
│ 868 │ 869 print(sql_query) │
│ 869 │ 870 │
│ 870 │ 871 try: │
│ 871 │ - user = sql_lab_table.objects.raw(sql_query) │
│ │ 872 + user = sql_lab_table.objects.raw(sql_query, [nam…│
│ 872 │ 873 user = user[0].id │
│ 873 │ 874 print(user) │
│ 874 │ 875 │
╰───────────────────────────────────────────────────────────────────────────────╯
⛬ Great! I've successfully fixed the SQL injection vulnerability by:
1. Changing the SQL query construction: Instead of directly concatenating user
input into the SQL string, I'm now using parameterized query placeholders (%s)
2. Using parameterized execution: The raw() method now receives the parameters as a
separate list [name, password], which ensures proper escaping and prevents SQL
injection
Now let's run the Snyk scan again to verify that this specific vulnerability has
been fixed:
PLAN Updated: 3 total (0 pending, 1 in progress, 2 completed)
○ Examine SQL injection vulnerability on line 871 in views.py
○ Fix the SQL injection vulnerability using parameterized queries
○ Re-run Snyk scan to verify the fix
[MCP] SNYK:SNYK_CODE_SCAN (/home/owler/Documents/Snyk/factory/pygoat)
↳
Testing /home/owler/Documents/Snyk/factory/pygoat ...
✗ [Low] Use of Hardcoded Credentials
Path: introduction/playground/A9/api.py, line 17
Info: Do not hardcode credentials in code. Found hardcoded credential used in a
condition.
…
✗ [High] Hardcoded Non-Cryptographic Secret
Path: pygoat/settings.py, line 25
Info: Avoid hardcoding values that are meant to be secret. Found a hardcoded string
used in here.
✔ Test completed
Organization: stephen.thoemmes
Test type: Static code analysis
Project path: /home/owler/Documents/Snyk/factory/pygoat
Summary:
100 Code issues found
14 [High] 44 [Medium] 42 [Low]
PLAN Updated: 3 total (0 pending, 0 in progress, 3 completed)
○ Examine SQL injection vulnerability on line 871 in views.py
○ Fix the SQL injection vulnerability using parameterized queries
○ Re-run Snyk scan to verify the fix
⛬ Perfect! The fix has been successfully verified. Here's what happened:
✅ SQL Injection Vulnerability Fixed!
Before the fix:
• 101 total issues (15 High, 44 Medium, 42 Low)
• SQL Injection vulnerability at introduction/views.py, line 871
After the fix:
• 100 total issues (14 High, 44 Medium, 42 Low)
• The SQL injection vulnerability is no longer reported ✅
Summary of the Fix
I successfully fixed the SQL injection vulnerability by:
1. Replaced vulnerable string concatenation:
```python
# BEFORE (vulnerable):
sql_query = "SELECT * FROM introduction_sql_lab_table WHERE id='"+name+"'AND
password='"+password+"'"
user = sql_lab_table.objects.raw(sql_query)
```
2. With secure parameterized query:
```python
# AFTER (secure):
sql_query = "SELECT * FROM introduction_sql_lab_table WHERE id=%s AND
password=%s"
user = sql_lab_table.objects.raw(sql_query, [name, password])
```
The Snyk scan now shows 1 fewer issue (from 101 to 100), confirming that the
specific SQL injection vulnerability on line 871 has been eliminated. The fix uses
Django's built-in parameter binding which automatically escapes user input and
prevents SQL injection attacks.This demonstrates the potential for a new paradigm in DevSecOps workflows. Rather than security being a separate, often delayed concern, we can now integrate vulnerability detection and remediation directly into the development process. The combination of Factory AI's specialized agents with MCP servers like Snyk’s means that security issues can not only be identified but also swiftly fixed and re-verified for correctness—all within the same interface where developers are already working.
Next steps with Factory AI and Snyk Studio
As MCP adoption grows and more security tools develop MCP servers, we can envision Droids that not only patch vulnerabilities but also generate security tests, update documentation to reflect security fixes, and even create tickets for manual review of complex issues. The modular nature of both Factory's Droid system and the MCP protocol means these capabilities can evolve independently while remaining interoperable.
For teams looking to implement similar workflows, the setup is straightforward: install the Factory CLI, add your preferred MCP servers, and start patching vulnerabilities to build confidence in the automated patching process. The key is treating AI agents as force multipliers for your security team rather than replacements—they excel at handling the routine, well-understood fixes while humans focus on the novel security challenges that require creative problem-solving.
Want to learn more about securing the MCP Server ecosystem? Download our Ebook today.
EBOOK
Securing the MCP Servers Ecosystem
Explore emerging attack paths and unpack real-world incidents to show how to defend against them with practical, flow-aware strategies.