Add a layer of active defense to your cloud applications.
- About this project
- Requirements
- Quickstart
- Architecture and Philosophy
- Configuration and advanced topics
- Support, Feedback, Contributing
- Security / Disclosure
- On the TODO list
- Code of Conduct
- Licensing
Cloud active defense lets you deploy decoys right into your cloud applications, putting adversaries into a dilemma: to hack or not to hack?
- If they interact with any of your decoys, they are instantly detected.
- If they refrain, they reduce their ability to attack, making your applications safer.
You win in either case.
- Docker 🐳
- Docker Compose (you can do without, but this will make your life easier)
If you want to rebuild the plugin, you'll need these:
- clone the repo
git clone https://github.com/SAP/cloud-active-defense.git
- start in demo mode
cd cloud-active-defense
docker-compose up --build
- check that it works
Visit http://localhost:8000
from a web browser. You should be granted by a 'welcome' page. Inpect the network traffic (In Firefox: CTRL+SHIFT+I
, visit 'Network', then click on the / request), notice the presence of an HTTP Response Header saying x-cloud-active-defense=ACTIVE
Let's add a first simple decoy. It won't be very useful but it is easy to understand.
-
open file
cloud-active-defense/configmanager/cad-default.json
-
replace the content with the following:
{
"filters": [
{
"decoy": {
"key": "x-cloud-active-defense",
"separator": "=",
"value": "ACTIVE"
},
"inject": {
"store": {
"inResponse": ".*",
"as": "header"
}
}
},
{
"decoy": {
"key": "forbidden"
},
"detect": {
"seek": {
"inRequest": ".*",
"withVerb": "GET",
"in": "url"
},
"alert": {
"severity": "LOW",
"whenSeen": true
}
}
}
]
}
-
check the console for the following line:
wasm log: read new config
-
visit
http://localhost:8000/forbidden
. This should give you an error messageCannot GET /forbidden
. Check that an alert was sent to the console with LOW severity.
The decoy we just added might trigger if your application is scanned by bots, but what's more interesting is to detect compromised user accounts. So let's create a decoy which will be visible only to authenticated users.
-
open file
cloud-active-defense/configmanager/cad-default.json
-
replace the content with the following:
{
"filters": [
{
"decoy": {
"key": "x-cloud-active-defense",
"separator": "=",
"value": "ACTIVE"
},
"inject": {
"store": {
"inResponse": ".*",
"as": "header"
}
}
},
{
"decoy": {
"key": "forbidden"
},
"detect": {
"seek": {
"inRequest": ".*",
"withVerb": "GET",
"in": "url"
},
"alert": {
"severity": "LOW",
"whenSeen": true
}
}
},
{
"decoy": {
"key": "role",
"separator": "=",
"value": "user"
},
"inject": {
"store": {
"inResponse": ".*",
"as": "cookie",
"whenTrue": [
{
"key": "SESSION",
"value": ".*",
"in": "cookie"
}
],
"whenFalse": [
{
"key": "role",
"value": ".*",
"in": "cookie"
}
]
}
},
"detect": {
"seek": {
"inRequest": ".*",
"in": "cookie"
},
"alert": {
"severity": "HIGH",
"whenModified": true
}
}
}
]
}
-
check the console for the following line:
wasm log: read new config
-
visit
http://localhost:8000/login
. Login as bob@myapp.com/bob. PressCTRL-SHIFT-I
to open the developer tools and navigate to the 'storage' tab. Notice how, upon login, a 'role=user' cookie was injected into your cookie jar.
Modify manually the value of the role cookie by double-clicking its value in the developer view. Set it to 'admin', then refresh the page. Notice that an alert was sent to the console with HIGH severity. Seems that Bob is a hacker or that someone who guessed his not-so-strong password is trying to escalate privileges!
(the alert shows twice as it is triggered once by the GET /
request and once by the GET /favicon.ico
request)
Cloud active defense is about making hacking painful. Today, attackers rely on the information provided by the application to successfully exploit it. This information is under our control - and there is no reason not to lie to attackers. We're not the first one to think about deploying deceptive element into applications. The OWASP AppSensor project came there first. But adding deceptive traps is an effort that's best kept separate from your application code:
- developers might not have the time or security skills for that
- adding code always bears the risk to introduce new (security!) bugs
Our approach was thus to let applications be protected by introducing a reverse-proxy, reading instructions from a versatile configuration file. No risk to introduce bugs to the application, and easy maintenance.
For the reverse-proxy, we chose Envoy. At its heart, cloud active defense is simply a plugin for Envoy. We chose Envoy because it's open source, fast, extensible, and because it's a popular choice as a Service Mesh solution. What this means is that cloud active defense can easily be deployed as a side-car if you use a kubernetes platform such as SAP Kyma. We are doing our best to provide a working solution, but consider testing it heavily before using it productively (and please report any issues you discover!)
Architecture-wise, cloud active defense is a WASM file deployed within Envoy in its own container. As WASM cannot read files from the filesystem, we instead expose the config file in its own configmanager service and retrieve it from Envoy via HTTP. The default config file is named cad-default.json, by default this is what Envoy will fetch. When deployed in Kubernetes, each service can have its own config file, this is described in its own section.
Envoy receives a request from the browser and forwards it to the application. Upon receiving the response from the application, Envoy checks if there is something to inject and behaves accordingly. On a subsequent request, Envoy checks if injected elements were interacted with and alerts accordingly.
Cloud active defense complements existing solutions such as Intrusion Detection Systems and honeypot-based deception by instrumenting the target web application itself. By adding decoys based on the application's business logic, you can raise high value, true positive alerts that warn your SOC team in real time before any harm is done. If you deploy decoys visible only to authenticated users, you can further detect account impersonation. This approach makes our solution unique.
Myapp is a demo application which can be used to test how decoys work. It is a simplistic web application with the following features:
GET /
: the front page, displays 'welcome' if you're not authenticated. Displays a static 'dashboard' page otherwise.GET /login
: a form displaying a login field, a password field, and a submit button.POST /login
: checks if username is 'bob@myapp.com' and password is 'bob'. It not, sends an error message. If yes, authenticates by setting a (hardcoded) 'SESSION' cookie
There is no logout mechanism. Delete the SESSION cookie to log out.
A simple application which returns the decoy config upon query.
GET /:namespace/:application
: searches on disk for a file named /data/cad-${namespace}-${application}.json, and returns its content. If not found, returns the content of cad-default.json
Envoy will send a GET request to configmanager a few times per minute and update its config accordingly. If running on docker-compose, 'namespace' and 'application' will both be empty strings, thus Envoy will always fetch the content of cad-default.json. If running on kubernetes, 'namespace' and 'application' will be properly set, allowing you to define one configuration per application per namespace.
Envoy is an open-source reverse proxy. Upon start, it reads the envoy.yaml config file, which loads the cloud-active-defense.wasm plugin. This plugin reads the content of cad-default.json and applies it upon receiving HTTP requests from the browser and HTTP responses from myapp.
The full architecture comprises extra containers which achieve the following goals:
Alerts raised by Envoy are sent to its console log. By configuring 'fluentd' as a logging driver, these alerts are sent to a fluent-bit container. Fluent-bit can be seen as a pipe which can collect and forward data. By default, fluent-bit will display the collected data to its own console log. Now, fluent-bit can be configured to forward these logs to your favorite monitoring tool, such as Splunk, Loki or Elasticsearch. Please refer to fluentbit.io for details.
On top of alerting, cloud active defense can be configured to execute an automated response. One such response is to divert the adversary to, essentially, a honeypot.
We pre-defined two such diversion endpoints: clone and exhaust. As with how myapp should be replaced with your own application, these two endpoints should be replaced too if you chose to use diversion as a response mechanism.
Think of this endpoint as a fake facade. From the outside it looks like your application, but there is nothing behind. The goal of this facade is to exhaust attackers resources against what is basically a wall.
If, upon detection of an attack, envoy detects that the request to be diverted is not authenticated, then it will forward it to the exhaust endpoint instead of myapp. The exhaust honeypot can be simply a copy of myapp's publicly reachable pages, with no business logic behind. For the demo, the exhaust app is a copy of myapp without any business logic, meaning that trying to login with valid credentials will be denied. All requests sent to exhaust should be considered malicious and are thus logged.
Think of this endpoint as a regular honeypot. It looks like what is inside your application, but all the content is fake and worthless. The goal of this trap is to further blur the line between what is real and what is not.
If, upon detection of an attack, envoy detects that the request to divert is authenticated, then it will forward it to the clone endpoint instead of myapp. The clone honeypot should keep the illusion that the user is logged into the real application, so the clone should be a copy of myapp, except for its data, which should be faked. Creating a believable, fake copy of an application is a complex task that we might visit someday. In the meantime, you may want to deploy a second copy of your exhaust application as your clone. All requests sent to clone should be considered malicious and are thus logged.
Please refer to our wiki for details.
Please refer to our wiki page to learn about decoys in details, and about how to modify the source code.
The code is provided "as-is" and will be maintained with a best effort approach. Let's make defense a fun topic ! We hope that you'll fall in love with the concept as much as we are and help us break the attack / defense assymmetry.
This project is open to feature requests/suggestions, bug reports etc. via GitHub issues. Contribution and feedback are encouraged and always welcome.
We are welcoming contributions such as:
- bug reports
- security improvements
- decoy ideas (mimicking existing vulnerabilities such as CVE-2023-32725)
For more information about how to contribute, the project structure, as well as additional contribution information, see our Contribution Guidelines.
If you find any bug that may be a security problem, please follow our instructions at in our security policy on how to report it. Please do not create GitHub issues for security-related doubts or problems.
Features we plan to eventually release:
- [DONE] adding a configuration specifying where to find information about the user's session. We want to use this to add session / logged in user information in the alert.
- [DONE] show how to ingest alerts into fluentd for further processing (currently alerts are simply shown on the console)
- show how to deploy into SAP Kyma as an extension of the mesh service
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone. By participating in this project, you agree to abide by its Code of Conduct at all times.
Copyright 2024 SAP SE or an SAP affiliate company and cloud-active-defense contributors. Please see our LICENSE for copyright and license information. Detailed information including third-party components and their licensing/copyright information is available via the REUSE tool.