OWASP Top 10 Vulnerability Scanning
Fence detects vulnerabilities from the OWASP Top 10 2021, the industry-standard list of the most critical web application security risks.
OWASP Top 10 2021 Coverage
A01:2021 - Broken Access Control
What it is: Users can access resources they shouldn't (e.g., other users' data, admin panels)
What Fence checks:
- Insecure Direct Object References (IDOR)
- Missing authorization checks
- Privilege escalation (regular user โ admin)
- Directory traversal (../../../../etc/passwd)
- Force browsing to restricted pages
Example vulnerability:
GET /api/users/123/profile โ Returns user 123's data โ
GET /api/users/456/profile โ Returns user 456's data (unauthorized) โ
Remediation:
- Implement authorization checks on every endpoint
- Validate user ownership before returning data
- Use role-based access control (RBAC)
- Deny access by default
A02:2021 - Cryptographic Failures
What it is: Sensitive data transmitted or stored without proper encryption
What Fence checks:
- Missing HTTPS enforcement
- Weak SSL/TLS configuration
- Passwords stored in plaintext
- Sensitive data in HTTP responses
- Missing encryption for PII/PHI
Example vulnerability:
<!-- Password sent in cleartext over HTTP -->
<form action="http://example.com/login" method="POST">
<input type="password" name="password">
</form>
Remediation:
- Force HTTPS everywhere (HSTS header)
- Encrypt data at rest (AES-256)
- Use bcrypt/Argon2 for password hashing
- Never log sensitive data
A03:2021 - Injection
What it is: Untrusted data sent to an interpreter as part of a command or query
What Fence checks:
- SQL Injection - Database queries with user input
- Command Injection - OS commands with user input
- LDAP Injection - Directory queries with user input
- XPath Injection - XML queries with user input
- NoSQL Injection - MongoDB/Redis queries with user input
Example SQL injection:
# โ VULNERABLE
username = request.POST['username']
query = f"SELECT * FROM users WHERE username='{username}'"
cursor.execute(query)
# Input: admin' OR '1'='1
# Result: SELECT * FROM users WHERE username='admin' OR '1'='1'
# Returns all users!
Remediation:
# โ
SECURE (Django ORM)
username = request.POST['username']
user = User.objects.get(username=username)
# โ
SECURE (Parameterized query)
cursor.execute("SELECT * FROM users WHERE username=%s", [username])
A04:2021 - Insecure Design
What it is: Missing or ineffective security controls due to design flaws
What Fence checks:
- Missing rate limiting on authentication
- No CAPTCHA on public forms
- Weak password requirements
- Missing multi-factor authentication
- Business logic flaws
Example vulnerability:
# โ VULNERABLE - No rate limiting
def login(request):
username = request.POST['username']
password = request.POST['password']
if authenticate(username, password):
return HttpResponse("Login successful")
# Attacker can brute-force 10,000 passwords/second
Remediation:
# โ
SECURE - Rate limiting with django-ratelimit
from django_ratelimit.decorators import ratelimit
@ratelimit(key='ip', rate='5/m', method='POST')
def login(request):
# ... same code
A05:2021 - Security Misconfiguration
What it is: Insecure default configurations, incomplete setups, or verbose error messages
What Fence checks:
- DEBUG mode enabled in production
- Default credentials (admin/admin)
- Directory listings enabled
- Unnecessary services running
- Verbose error messages revealing stack traces
- Missing security headers
Example vulnerability:
# settings.py - โ VULNERABLE
DEBUG = True # In production!
ALLOWED_HOSTS = ['*']
SECRET_KEY = 'django-insecure-hardcoded-key'
Remediation:
# settings.py - โ
SECURE
DEBUG = False
ALLOWED_HOSTS = ['example.com', 'www.example.com']
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')
# Security headers
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
A06:2021 - Vulnerable and Outdated Components
What it is: Using libraries/frameworks with known vulnerabilities
What Fence checks:
- Outdated JavaScript libraries (jQuery 1.x, Angular 1.x)
- Vulnerable npm packages
- Outdated web server versions (Apache 2.2, Nginx 1.10)
- EOL frameworks (Python 2.7, PHP 5.x)
- Known CVEs in dependencies
Example detection:
jQuery 1.12.4 detected (CVE-2020-11022, CVE-2020-11023)
Recommendation: Upgrade to jQuery 3.6.0+
Remediation:
# Check for vulnerable dependencies
npm audit
pip-audit
# Update dependencies
npm update
pip install --upgrade -r requirements.txt
# Use Dependabot for automated updates
A07:2021 - Identification and Authentication Failures
What it is: Broken authentication mechanisms
What Fence checks:
- Weak password policies (no minimum length)
- Missing account lockout
- Session tokens in URL
- Session fixation vulnerabilities
- Missing logout functionality
- Credential stuffing attacks possible
Example vulnerability:
# โ VULNERABLE - Weak password policy
password = request.POST['password']
if len(password) >= 6: # Only 6 characters!
user.set_password(password)
Remediation:
# โ
SECURE - Strong password policy
from django.contrib.auth.password_validation import validate_password
password = request.POST['password']
validate_password(password) # Django's validators:
# - Minimum 8 characters
# - Not too similar to username
# - Not entirely numeric
# - Not in common password list
A08:2021 - Software and Data Integrity Failures
What it is: Code and infrastructure that doesn't protect against integrity violations
What Fence checks:
- Missing Subresource Integrity (SRI) on CDN resources
- Insecure deserialization (pickle, YAML)
- Auto-update mechanisms without verification
- Unsigned CI/CD pipelines
Example vulnerability:
<!-- โ VULNERABLE - No SRI -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
Remediation:
<!-- โ
SECURE - With SRI -->
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous">
</script>
A09:2021 - Security Logging and Monitoring Failures
What it is: Insufficient logging and monitoring to detect breaches
What Fence checks:
- Missing login attempt logging
- No audit trails for sensitive operations
- Logs not retained long enough
- No alerting on suspicious activity
- Logs containing sensitive data (passwords, tokens)
Example vulnerability:
# โ VULNERABLE - No logging
def delete_user(request, user_id):
User.objects.get(id=user_id).delete()
return HttpResponse("User deleted")
# Who deleted? When? Why? Unknown!
Remediation:
# โ
SECURE - Audit logging
import logging
logger = logging.getLogger('audit')
def delete_user(request, user_id):
user = User.objects.get(id=user_id)
logger.info(f"User {request.user.username} deleted user {user.username} (ID: {user_id})")
user.delete()
return HttpResponse("User deleted")
A10:2021 - Server-Side Request Forgery (SSRF)
What it is: Application fetches a remote resource without validating user-supplied URL
What Fence checks:
- URL validation on user-supplied inputs
- Requests to internal IP ranges (127.0.0.1, 10.0.0.0/8, 192.168.0.0/16)
- Cloud metadata endpoint access (169.254.169.254)
- File:// protocol usage
Example vulnerability:
# โ VULNERABLE
url = request.GET['url']
response = requests.get(url) # User can access internal services!
# ?url=http://localhost:6379/ โ Access Redis
# ?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ โ AWS keys
Remediation:
# โ
SECURE
import ipaddress
from urllib.parse import urlparse
url = request.GET['url']
parsed = urlparse(url)
# Block private IPs
ip = ipaddress.ip_address(parsed.hostname)
if ip.is_private:
return HttpResponse("Private IPs not allowed", status=400)
# Allow only HTTPS
if parsed.scheme != 'https':
return HttpResponse("Only HTTPS URLs allowed", status=400)
response = requests.get(url)
Severity Scoring
Fence uses CVSS scoring to prioritize OWASP vulnerabilities:
| Severity | CVSS Score | Examples | Action Required |
|---|---|---|---|
| Critical | 9.0-10.0 | SQL injection, RCE, authentication bypass | Fix immediately (24-48 hours) |
| High | 7.0-8.9 | XSS, CSRF, insecure deserialization | Fix within 7 days |
| Medium | 4.0-6.9 | Weak crypto, missing headers, info disclosure | Fix within 30 days |
| Low | 0.1-3.9 | Verbose errors, outdated libraries (no exploit) | Fix within 90 days |
Testing Methodology
Fence uses Wapiti for OWASP Top 10 detection:
- Crawling - Discovers all pages, forms, and endpoints
- Attack vectors - Generates payloads for each vulnerability type
- Injection - Tests each input with malicious payloads
- Analysis - Identifies vulnerable parameters
- Verification - Confirms exploitability
Scan duration: 3-8 minutes per domain (depends on site size)
False Positive Handling
Mark false positives in Fence dashboard:
1. Go to Issues โ Select vulnerability
2. Click Mark as False Positive
3. Add reason (e.g., "Input sanitized by WAF")
4. Fence learns from feedback
Compliance Mapping
| OWASP Category | PCI DSS | HIPAA | SOC 2 | ISO 27001 |
|---|---|---|---|---|
| Broken Access Control | 6.5.8, 7.1 | ยง 164.312(a)(1) | CC6.1 | A.9.2.1 |
| Cryptographic Failures | 3.4, 4.1 | ยง 164.312(e)(1) | CC6.7 | A.10.1.1 |
| Injection | 6.5.1 | ยง 164.308(a)(4) | CC7.1 | A.14.2.5 |
| Insecure Design | 6.5.10 | ยง 164.308(a)(1) | CC3.1 | A.14.1.2 |