diff --git a/.acraconfigs/acra-server/acra-censor.norules.yaml b/.acraconfigs/acra-server/acra-censor.norules.yaml
index 9e1e7d9..445ea88 100644
--- a/.acraconfigs/acra-server/acra-censor.norules.yaml
+++ b/.acraconfigs/acra-server/acra-censor.norules.yaml
@@ -1,2 +1,2 @@
ignore_parse_error: true
-version: 0.85.0
\ No newline at end of file
+version: 0.95.0
diff --git a/.acraconfigs/acra-server/acra-censor.ruleset01.yaml b/.acraconfigs/acra-server/acra-censor.ruleset01.yaml
index 5c76467..d7e5bbb 100644
--- a/.acraconfigs/acra-server/acra-censor.ruleset01.yaml
+++ b/.acraconfigs/acra-server/acra-censor.ruleset01.yaml
@@ -1,5 +1,5 @@
ignore_parse_error: true
-version: 0.85.0
+version: 0.95.0
handlers:
- handler: query_ignore
queries:
diff --git a/.acraconfigs/acra-server/acra-censor.ruleset02.yaml b/.acraconfigs/acra-server/acra-censor.ruleset02.yaml
index eb5fc3e..f5553be 100644
--- a/.acraconfigs/acra-server/acra-censor.ruleset02.yaml
+++ b/.acraconfigs/acra-server/acra-censor.ruleset02.yaml
@@ -1,5 +1,5 @@
ignore_parse_error: true
-version: 0.85.0
+version: 0.95.0
handlers:
- handler: deny
queries:
diff --git a/.acraconfigs/acra-server/acra-censor.ruleset03.yaml b/.acraconfigs/acra-server/acra-censor.ruleset03.yaml
index b66cb2c..046e8a8 100644
--- a/.acraconfigs/acra-server/acra-censor.ruleset03.yaml
+++ b/.acraconfigs/acra-server/acra-censor.ruleset03.yaml
@@ -1,4 +1,4 @@
ignore_parse_error: true
-version: 0.85.0
+version: 0.95.0
handlers:
- handler: denyall
diff --git a/.acraconfigs/acra-server/acra-censor.yaml b/.acraconfigs/acra-server/acra-censor.yaml
index 9e1e7d9..445ea88 100644
--- a/.acraconfigs/acra-server/acra-censor.yaml
+++ b/.acraconfigs/acra-server/acra-censor.yaml
@@ -1,2 +1,2 @@
ignore_parse_error: true
-version: 0.85.0
\ No newline at end of file
+version: 0.95.0
diff --git a/README.md b/README.md
index eedd5c3..4b899ef 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# What is this?
-This project illustrates how to use [AcraCensor](https://docs.cossacklabs.com/pages/documentation-acra/#acracensor-acra-s-firewall) as SQL firewall to prevent SQL injections. Target application is a well-known vulnerable web application [OWASP Mutillidae 2](https://github.com/webpwnized/mutillidae).
+This project illustrates how to use [AcraCensor](https://docs.cossacklabs.com/pages/documentation-acra/#acracensor-acra-s-firewall) as SQL firewall to prevent SQL injections. Target application is a well-known vulnerable web application [OWASP Mutillidae 2](https://github.com/webpwnized/mutillidae).
AcraCensor – is a built-in SQL firewall of [Acra data protection suite](https://cossacklabs.com/acra/). This project is one of numerous Acra's example applications. If you are curious about other Acra features, like transparent encryption, intrusion detection, load balancing support – [Acra Example Applications](https://github.com/cossacklabs/acra-engineering-demo/).
@@ -21,21 +21,21 @@ This is a slide from [a talk by Cossack Labs' security software engineer Artem S
## Screencast
-
+
## How to run the demo
-1. Use docker-compose command to set up and run the whole infrastructure:
+1. Use docker-compose command to set up and run the whole infrastructure:
```
-docker-compose -f docker-compose.acra-censor-demo.yml up
+docker-compose -f docker-compose.acra-censor-demo.yml up --build
```
-2. Check that the containers are up and running:
+2. Check that the containers are up and running:
```
docker ps -a
@@ -47,7 +47,7 @@ docker ps -a
-4. The database is still empty so we need to fill it first by clicking on `setup/reset the DB`.
+4. The database is still empty so we need to fill it first by clicking on `Click here to attempt to setup the database` and then `Opt out of database warnings`.
In the Docker console you should see SQL queries in Acra logs. After resetting the database, the main page of Mutillidae application looks like this:
@@ -60,16 +60,16 @@ In the Docker console you should see SQL queries in Acra logs. After resetting t
-2. Now, let's run an SQL injection. Try to login any name and password `' or 1='1`.
+2. Now, let's run an SQL injection. Try to login any name and password `' or 1='1`.
-This will construct an SQL query `SELECT * FROM accounts WHERE username='' AND password='' or 1='1'` — containing a typical SQL injection — to the database.
+This will construct an SQL query `SELECT * FROM accounts WHERE username='' AND password='' or 1='1'` — containing a typical SQL injection — to the database.
## How AcraCensor prevents SQL injections
-1. Now, let's fine-tune AcraCensor for preventing this injection.
+1. Now, let's fine-tune AcraCensor for preventing this injection.
There are configuration files in `./.acraconfigs/acra-server/` folder:
- `acra-censor.norules.yaml` (minimal configuration that simply creates valueless AcraCensor);
@@ -83,7 +83,7 @@ Replace the active config with `acra-censor.ruleset01.yaml` (or `acra-censor.rul
```bash
cp ./.acraconfigs/acra-server/acra-censor.ruleset01.yaml ./.acraconfigs/acra-server/acra-censor.yaml
-docker restart
+docker restart acra-censor-demo_acra-server_1
```
In the docker log, you will see that AcraServer has restarted with an updated configuration file:
@@ -96,9 +96,9 @@ acra-censor-demo-master_acra-server_1_979c50cd7b3e exited with code 0
2. Test if the new AcraCensor configuration prevents injections.
-On the same web page, try to login again using the password `' or 1='1`.
+On the same web page, try to login again using the password `' or 1='1`.
-You should see that the response from MySQL server is blocked. In Acra's console, you can see that the malicious query is forbidden:
+You should see that the response from MySQL server is blocked. In Acra's console, you can see that the malicious query is forbidden:
@@ -122,7 +122,7 @@ and try to use `admin` as a username and `' or 1='1` as a password.
2. Read out blog post [how we built AcraCensor](https://www.cossacklabs.com/blog/how-to-build-sql-firewall-acracensor.html).
3. Watch the slides about the developers' perspective on [building SQL firewall](https://speakerdeck.com/storojs72/building-sql-firewall-insights-from-developers).
4. Check [Mutillidae repository](https://github.com/webpwnized/mutillidae).
-5. Check [Mutillidae docker image by @edoz90](https://github.com/edoz90/docker-mutillidae).
+5. Check [Mutillidae docker](https://github.com/webpwnized/mutillidae-docker).
# Further steps
diff --git a/docker-compose.acra-censor-demo.yml b/docker-compose.acra-censor-demo.yml
index 82c42d5..f768e5c 100644
--- a/docker-compose.acra-censor-demo.yml
+++ b/docker-compose.acra-censor-demo.yml
@@ -1,138 +1,77 @@
version: "3"
services:
- # Create keys:
- # - ./.acrakeys/acra-server/${ACRA_CLIENT_ID}_server
- # - ./.acrakeys/acra-connector/${ACRA_CLIENT_ID}_server.pub
- acra-keymaker_server:
- # You can specify docker image tag in the environment
- # variable ACRA_DOCKER_IMAGE_TAG or run by default with 'latest' images
- image: "cossacklabs/acra-keymaker:${ACRA_DOCKER_IMAGE_TAG:-latest}"
- environment:
- # INSECURE!!! You MUST define your own ACRA_MASTER_KEY
- # The default is only for testing purposes
- ACRA_MASTER_KEY: ${ACRA_MASTER_KEY:-UHZ3VUNNeTJ0SEFhbWVjNkt4eDdVYkc2WnNpUTlYa0E=}
- volumes:
- # Mount the whole ./.acrakeys directory to be able generate keys and
- # place them in services' subdirectories
- - ./.acrakeys:/keys
- # Please specify ACRA_CLIENT_ID environment variable, otherwise run with
- # default 'testclientid' client id
- command: >-
- --client_id=${ACRA_CLIENT_ID:-testclientid}
- --generate_acraserver_keys
- --keys_output_dir=/keys/acra-server
- --keys_public_output_dir=/keys/acra-connector
- # Create keys:
- # - ./.acrakeys/acra-connector/${ACRA_CLIENT_ID}
- # - ./.acrakeys/acra-server/${ACRA_CLIENT_ID}.pub
- acra-keymaker_connector:
- image: "cossacklabs/acra-keymaker:${ACRA_DOCKER_IMAGE_TAG:-latest}"
- environment:
- ACRA_MASTER_KEY: ${ACRA_MASTER_KEY:-UHZ3VUNNeTJ0SEFhbWVjNkt4eDdVYkc2WnNpUTlYa0E=}
- volumes:
- - ./.acrakeys:/keys
- command: >-
- --client_id=${ACRA_CLIENT_ID:-testclientid}
- --generate_acraconnector_keys
- --keys_output_dir=/keys/acra-connector
- --keys_public_output_dir=/keys/acra-server
-
-
#===== Acra ================================================================
-
acra-server:
- image: "cossacklabs/acra-server:${ACRA_DOCKER_IMAGE_TAG:-latest}"
+ image: "cossacklabs/acra-server:${ACRA_DOCKER_IMAGE_TAG:-0.95.0}"
# Restart server after correct termination, for example after the config
# was changed through the API
restart: always
- depends_on:
- - acra-keymaker_server
- - acra-keymaker_connector
networks:
- - acraconnector-acraserver
+ - mutillidae-acraserver
- acraserver-db
environment:
ACRA_MASTER_KEY: ${ACRA_MASTER_KEY:-UHZ3VUNNeTJ0SEFhbWVjNkt4eDdVYkc2WnNpUTlYa0E=}
volumes:
# Mount the directory with only the keys for this service. Must be
# rewriteable in case of using API, otherwise should be read-only.
- - ./.acrakeys/acra-server:/keys
# Directory with configuration, rewriteable
- ./.acraconfigs/acra-server:/config
command: >-
--mysql_enable
- --db_host=mutillidae
+ --db_host=database
--db_port=3306
- --keys_dir=/keys
- --auth_keys=/keys/httpauth.accounts
- --http_api_enable
- --incoming_connection_api_string=tcp://0.0.0.0:9090
+ --keystore_cache_on_start_enable=false
--acracensor_config_file=/config/acra-censor.yaml
- -v
+ --v
+ --d
+ #===== OWASP Mutillidae II =================================================
- acra-connector:
- image: "cossacklabs/acra-connector:${ACRA_DOCKER_IMAGE_TAG:-latest}"
- restart: always
+ mutillidae:
+ container_name: mutillidae
depends_on:
- - acra-keymaker_server
- - acra-keymaker_connector
+ - database
- acra-server
- # Open the port outside for client application
+ image: mutillidae
+ build:
+ context: https://github.com/webpwnized/mutillidae-docker.git#1.0.39:www
+ args:
+ DATABASE_HOST: acra-server
+ DATABASE_PORT: 9393
ports:
- - "3306:3306"
+ - 127.0.0.1:8080:80
networks:
- - acraconnector-acraserver
- - mutillidae-acraconnector
- environment:
- ACRA_MASTER_KEY: ${ACRA_MASTER_KEY:-UHZ3VUNNeTJ0SEFhbWVjNkt4eDdVYkc2WnNpUTlYa0E=}
- volumes:
- # Mount the directory with only the keys for this service
- - ./.acrakeys/acra-connector:/keys:ro
- command: >-
- --acraserver_connection_host=acra-server
- --keys_dir=/keys
- --client_id=${ACRA_CLIENT_ID:-testclientid}
- --incoming_connection_string=tcp://0.0.0.0:3306
- --http_api_enable
- --incoming_connection_api_string=tcp://0.0.0.0:9191
- -v
-
-
- #===== OWASP Mutillidae II =================================================
-
- edoz90_mutillidae:
- # Build base image
- build:
- context: https://github.com/storojs72/docker-mutillidae.git
- image: storojs72/edoz90_mutillidae:latest
- # We don't need to run the container based on the original image
- entrypoint: /bin/true
- restart: 'no'
+ - world
+ - mutillidae-acraserver
+ #===== OWASP Mutillidae DB =================================================
- mutillidae:
- depends_on:
- - acra-connector
- - edoz90_mutillidae
+ database:
+ container_name: database
+ image: webpwnized/mutillidae:database
+ healthcheck:
+ test: "/usr/bin/mysql --user=root --password=mutillidae --execute \"SHOW DATABASES;\""
+ interval: 5s
+ timeout: 30s
+ retries: 10
build:
- context: ./mutillidae
- image: mutillidae:latest
- ports:
- - "8080:80"
- - "3306:3306"
+ context: https://github.com/webpwnized/mutillidae-docker.git#1.0.39:database
networks:
- - world
- - mutillidae-acraconnector
- acraserver-db
+ healthcheck-wait:
+ image: busybox
+ container_name: healthcheck-wait
+ depends_on:
+ database:
+ condition: service_healthy
networks:
world:
acraserver-db:
internal: true
- acraconnector-acraserver:
+ mutillidae-acraserver:
internal: true
- mutillidae-acraconnector:
+ mutillidae-db:
internal: true
diff --git a/images/acra-censor-scheme-noac.png b/images/acra-censor-scheme-noac.png
deleted file mode 100644
index a0bdd8f..0000000
Binary files a/images/acra-censor-scheme-noac.png and /dev/null differ
diff --git a/images/acra-censor-scheme.png b/images/acra-censor-scheme.png
old mode 100755
new mode 100644
index cfcb1bb..8af80a9
Binary files a/images/acra-censor-scheme.png and b/images/acra-censor-scheme.png differ
diff --git a/images/image_1.png b/images/image_1.png
index 1ed5643..e23a1bf 100644
Binary files a/images/image_1.png and b/images/image_1.png differ
diff --git a/images/image_2.png b/images/image_2.png
index 0c8c2e7..794dfa7 100644
Binary files a/images/image_2.png and b/images/image_2.png differ
diff --git a/images/image_3.png b/images/image_3.png
index 496e550..dcdd81c 100644
Binary files a/images/image_3.png and b/images/image_3.png differ
diff --git a/images/image_7.png b/images/image_7.png
index 38cdb54..7207eca 100644
Binary files a/images/image_7.png and b/images/image_7.png differ
diff --git a/mutillidae/Dockerfile b/mutillidae/Dockerfile
deleted file mode 100644
index f75e8fe..0000000
--- a/mutillidae/Dockerfile
+++ /dev/null
@@ -1,7 +0,0 @@
-FROM storojs72/edoz90_mutillidae:latest
-
-ADD ./configure_db.sh /tmp/configure_db.sh
-RUN /bin/bash /tmp/configure_db.sh
-RUN rm /tmp/configure_db.sh
-
-EXPOSE 80 3306
diff --git a/mutillidae/configure_db.sh b/mutillidae/configure_db.sh
deleted file mode 100644
index df25763..0000000
--- a/mutillidae/configure_db.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-MYSQL_ROOT_PASSWORD='test'
-
-MYSQL_DB='mutillidae'
-MYSQL_USER='mutillidae'
-MYSQL_PASSWORD='mutillidae'
-
-cat < /usr/share/nginx/html/mutillidae/includes/database-config.php
-
-EOF
-
-cat < /etc/my.cnf.d/mariadb-server.cnf
-[mysqld]
-bind-address=0.0.0.0
-EOF