How Common Misconfigurations Could Lead to Massive Data Exposure
9 min readJust now
–
In The Previous Episodes
In the second part of our series, we showcased how AI Agents introduce new attack vectors for organizations using an HR Assistant Agent as an example. Additionally, we uncovered a critical vulnerability in Flowise (CVE-2025–26319) a leading AI agent development platform.
TL;DR
In this post, we’re covering one of the most popular agentic workflow development platforms — Dify. We’ll show how simple misconfigurations can lead to the theft of critical enterprise assets, and just how common these misconfigurations actually are.
Press enter or click to view image in full size
**…
How Common Misconfigurations Could Lead to Massive Data Exposure
9 min readJust now
–
In The Previous Episodes
In the second part of our series, we showcased how AI Agents introduce new attack vectors for organizations using an HR Assistant Agent as an example. Additionally, we uncovered a critical vulnerability in Flowise (CVE-2025–26319) a leading AI agent development platform.
TL;DR
In this post, we’re covering one of the most popular agentic workflow development platforms — Dify. We’ll show how simple misconfigurations can lead to the theft of critical enterprise assets, and just how common these misconfigurations actually are.
Press enter or click to view image in full size
Disclaimer:* The issues discussed in this post aren’t vulnerabilities in the traditional sense. They’re common misconfigurations that appear across thousands of deployments because the product doesn’t sufficiently emphasize the importance of changing default secrets and properly configuring services.*
The platform
Dify is an open-source platform designed to simplify the development and management of AI applications. It offers a user-friendly interface that lets both developers and non-technical users create, deploy, and manage AI-driven solutions with ease.
Dify is incredibly popular — it has roughly 120,000 stars on GitHub, millions of downloads from DockerHub, and thousands of organizations using it, including major enterprises like Volvo, Thermo Fisher, Panasonic, and Maersk.
Press enter or click to view image in full size
Logos From dify.ai Website
Press enter or click to view image in full size
Repository from Github
Building AI Applications
Dify offers various ways to build AI applications, including Workflows, Chatbots, Agents, and more. Users can either create applications from scratch by selecting their own tools, models, and knowledge connectors, or choose from predefined agents in the marketplace. Building from scratch is straightforward thanks to the drag-and-drop interface.
Press enter or click to view image in full size
Example Agent — Bug Tracking Agent with tool calling capabilities
Users can use Dify’s platform in different ways — through Dify’s Cloud or local deployment (either building from source or using the pre-made Docker image). In this research, I mainly focused on local deployments. I found that certain misconfigurations keep appearing across real-world instances, including at large enterprises, putting those organizations and their critical assets at risk.
Press enter or click to view image in full size
Misconfiguration #1. Default API-Keys and Secrets
In local Dify installations — whether you’re building the product from the source or using the pre-made Docker image, some services are exposed to the public.
Building Dify from source requires setting up several services, this is done by launching Docker containers from a docker-compose file called docker-compose.middleware.yaml.
Press enter or click to view image in full size
Looking at the docker-compose file, you can see that some services are exposed to the host machine (and potentially to the public).
Press enter or click to view image in full size
What’s the problem?
Dify, like most products, ships with different API keys and secrets for different services. But there’s a problem: most of these keys and secrets aren’t generated during installation — they’re static and hard-coded — and nothing forces users to change them during setup. This leads to the unfortunate situation where most servers end up keeping the default API keys and secret values, which are publicly known.
To verify if this is actually a problem in the real-world, I picked two services and checked their statistics across public servers.
dbService — RunsPostgreSQLand hosts the database that manages everything Dify needs in order to to run.
Dify’s default password for the postgres user is difyai123456.
I randomly tested 20 servers to see how many kept the default password— turns out 70% of them were still using it.
Press enter or click to view image in full size
plugin-deamon— This service manages the plugins used by Dify (like the GitHub addon and web search tool) and handles communication with LLM models. The next section covers this service in more detail, including how it can be exploited and some statistics.
How can attacker abuse this misconfigurations?
Each one of the services, if compromised, has the potential to let an attacker compromise the entire Dify instance. The fact that some of these services use default secrets and API keys (which are publicly known) makes them easy targets.
While I’m not going to cover every service, I will take a closer look at one in particular: plugin-daemon.
plugin-deamon service takeover
Dify Plugin Daemon is a service that manages the lifecycle of plugins. It’s written mostly in Go and exposes two interfaces:
- HTTP interface on port 5002 (used by the main Dify API server to install plugins, invoke LLM model queries, and more)
- TCP interface on port 5003 (for remote plugin installation)
While there are also some issues with the TCP interface, we’re going to focus on the HTTP interface running on port 5002.
The HTTP interface is defined in the http_server.go file. The server starts by defining some base routes (/e, /plugin:tenant_id, /debug/pprof, /backwards-invocation), then adds sub-routes under each one.
Press enter or click to view image in full size
All routes except /health/check and /e require authentication.
The server enforces this by calling the CheckingKey function, which compares the X-Api-Key header value with the SERVER_KEY variable in the configuration — a configuration that, as I mentioned earlier, usually stays at its default, publicly known value.
Assuming the SERVER_KEY is at its default value — how can attackers take over this service? They can abuse the legitimate plugin upload and installation mechanism with the following steps:
***Step 1 — creating a malicious plugin
***One can create a plugin with malicious tool using Dify’s official dify-plugin dev binary. I’ll skip the boring details and focus on what matters:
when initializing a tool project, the creator (or attacker) provides some basic info like author name and tool description.
Then they choose the template type (tool / llm / tts / ..), when selecting “tool,” the binary generates a folder with several files, including the actual plugin logic and a main.py file as the entry point.
Press enter or click to view image in full size
You don’t need to be a genius to make this plugin malicious — just modify the main.py file, add your payload on initialization, and you’re done.
Press enter or click to view image in full size
To wrap things up, I use once again the dify-plugin dev binary to make the plugin a package, and that’s it — your plugin is ready
Press enter or click to view image in full size
***step 2 — Upload the malicious plugin package
***To upload the malicious plugin, an attacker can use the route /plugin/:tenant_id/management/install/upload/package.
The function handling this request extracts the tenant_id from the URI, along with the package file and a parameter called verify_signature.
In the default configuration, the function checks that the package is signed with Dify’s key — which is weird, because apparently, anyone can create a signed package using the dify-plugin dev binary.
After that, the function writes the package to disk and adds a record to the database with all the plugin information.
Press enter or click to view image in full size
***Step 3 — Installing the plugin
***To install the uploaded plugin, you need to send another HTTP request to /plugin/:tenant_id/management/install/identifiers.
The function handling this request grabs the unique identifier from the JSON body — if a plugin with that identifier exists in the database (which we just registered in step 2), the system installs and loads the plugin, essentially running our malicious main.py code.
Press enter or click to view image in full size
The result? Arbitrary code execution on the plugin-daemon container.
Press enter or click to view image in full size
Prerequisites
To exploit this misconfiguration, the target instance needs to have some of these ports open (PostgreSQL, Redis, plugin-daemon) and be using the default API keys and secrets.
Additionally, to exploit the plugin-daemon service specifically, the attacker needs to know a valid tenant_idvalue — which can be retrieved from any chat or agent instance without authentication.
Misconfiguration #2. SSRF Proxy
One of the features that comes with chatbots and agent workflows is the ability to upload files. This is essential for lots of use cases — from uploading CVs to submitting bug reports and many more use-cases.
When setting up this feature, the creator picks which file extensions are allowed and where users can upload from: either their local computer or a remote URL. By default, both sources are enabled
Press enter or click to view image in full size
In local deployments (Docker and built from source), Dify comes with an ssrf-proxy service.
As the name suggests, this service is meant to prevent users from uploading files from unwanted networks.
The problem? Almost no one sets it up properly, and by default it doesn’t actually prevent SSRFs. This means attackers can “upload” files from the enterprise’s internal network, potentially extracting critical assets.
Oh, and there’s another problem. Remember that setting to block unwanted file extensions? It’s really easy to bypass.
I’ll spare you the technical details, but here’s how it works: when someone uploads a file, an HTTP request is sent to /api/remote-files/upload with a JSON payload containing the remote URL they want to upload.
Press enter or click to view image in full size
And the response? contains a file-preview link that when accessing to — you’ll get the content of the uploaded file
Press enter or click to view image in full size
How can attacker abuse this misconfiguration?
An attacker can exploit this misconfiguration to run a full network scan on the victim’s internal Docker network, essentially turning Dify’s server into a scanning proxy. They’ll be hunting for vulnerable web applications or critical assets accessible via HTTP requests.
That said, there are some limitations to this bug:
- Attackers can only send HTTP GET requests
- Attackers can’t manipulate the headers
- Scanning an entire network (every IP address across all 65,535 ports) would take forever
To speed things up and increase their chances of success, attackers could target specific services that respond to HTTP GET requests on well-known ports (like Grafana on port 3000), or services that contain specific paths revealing they’ve found their target (for example, GitLab has the /explore/groups.json path).
Press enter or click to view image in full size
Statistics
A quick scan found roughly 25K servers running Dify. I randomly picked 20 servers to test how many were misconfigured.
The results were pretty shocking — around 90% of the servers I checked weren’t set up with proper SSRF prevention in their Squid proxy, and I could access their internal services.
This brings up an interesting question: who’s actually responsible here? The provider has given users a way to lock things down, and sometimes accessing internal IPs is totally legitimate and part of how the product works. But the fact that so many users have their stuff exposed means the risk probably wasn’t explained clearly enough.
Prerequisites
To abuse this misconfiguration, an attacker just needs to find a chat interface — that’s all it takes to grab the “anonymous user” authorization key and start scanning the victim’s internal network.
Summary and Call To Action
Dify is a great product with an overall excellent level of security. That being said, some common misconfigurations put organizations using it at high risk, and they should take this into account.
- Make sure only necessary services are exposed to the public (ideally, only nginx should be publicly accessible)
- Review your Dify instance configuration and verify that the following variables aren’t set to their defaults:
DB_PASSWORDREDIS_PASSWORDPLUGIN_DAEMON_KEYINNER_API_KEY_FOR_PLUGIN- Ensure the
ssrf_proxyservice (Squid service) is configured properly — modify/etc/squid/squid.confto meet your security requirements