8.3 KiB
Security Testing Guide
Overview
This document outlines the security testing methodology and test cases for ActivityPub implementations.
Security Test Categories
1. Cross-Site Scripting (XSS)
Objective: Identify if user-supplied content is properly sanitized before display.
Test Cases:
- Script tag injection:
<script>alert('XSS')</script> - Event handler injection:
<img src=x onerror=alert('XSS')> - JavaScript protocol:
javascript:alert('XSS') - SVG-based XSS:
<svg/onload=alert('XSS')> - Encoded payloads:
<script>alert('XSS')</script>
Vulnerable Scenarios:
- Content rendered without HTML escaping
- Markdown/rich text processing vulnerabilities
- URL handling in attachment previews
2. Server-Side Request Forgery (SSRF)
Objective: Test if the server can be tricked into making requests to internal resources.
Test Cases:
- Internal network:
http://localhost:8080,http://127.0.0.1 - Cloud metadata:
http://169.254.169.254/latest/meta-data/ - IPv6 localhost:
http://[::1]:8080 - File protocol:
file:///etc/passwd - DNS rebinding attacks
Vulnerable Scenarios:
- Fetching remote avatars/images without validation
- Link previews/unfurling
- WebFinger lookups without URL validation
3. Object Injection & Type Confusion
Objective: Test object validation and type handling.
Test Cases:
- Multiple type values:
"type": ["Note", "Delete"] - Missing required fields
- Prototype pollution:
__proto__injection - Constructor manipulation
- Unexpected nested objects
Vulnerable Scenarios:
- Weak JSON schema validation
- Dynamic property assignment
- Type coercion vulnerabilities
4. Authentication & Authorization
Objective: Verify proper access controls and signature verification.
Test Cases:
- Missing HTTP signatures
- Invalid/forged signatures
- Actor impersonation
- Unauthorized deletions
- Private content access
- Relay poisoning
Vulnerable Scenarios:
- Weak signature verification
- Missing authorization checks
- Confused deputy attacks
5. Injection Attacks
Objective: Test for command and SQL injection vulnerabilities.
Test Cases:
- SQL injection:
' OR '1'='1,'; DROP TABLE-- - Command injection:
; ls -la,| whoami,$(uname -a) - LDAP injection
- Template injection
- Path traversal:
../../etc/passwd
Vulnerable Scenarios:
- Direct database queries with user input
- System command execution
- Template rendering with user content
6. Denial of Service (DoS)
Objective: Test resilience against resource exhaustion.
Test Cases:
- Large payloads (MB-sized JSON)
- Deeply nested objects
- Circular references
- Excessive followers/following counts
- Rapid activity submission
Vulnerable Scenarios:
- No rate limiting
- Unbounded resource allocation
- Inefficient parsing
Testing Methodology
1. Reconnaissance
# Fetch actor profile
node src/cli.js fetch-actor --target https://target.example/users/alice
# Check outbox
node src/cli.js test-outbox --target https://target.example/users/alice/outbox
2. Baseline Testing
# Send valid activity
node src/cli.js test-inbox \
--target https://target.example/users/alice/inbox \
--payload examples/create-note.json
3. Automated Security Scan
# Run all tests
node src/cli.js security-scan \
--target https://target.example/users/alice/inbox \
--output scan-results.json
4. Manual Payload Testing
# Test specific vulnerability
node src/cli.js test-inbox \
--target https://target.example/users/alice/inbox \
--payload examples/xss-payload.json
5. Analysis
Review logs, responses, and behavior:
- HTTP status codes
- Error messages
- Server-side rendering
- Database queries
- Network traffic
Responsible Disclosure
If you discover a vulnerability:
- Do not exploit beyond proof-of-concept
- Document the issue thoroughly
- Report privately to the maintainers
- Allow time for fixes (typically 90 days)
- Coordinate public disclosure
Common Vulnerabilities in ActivityPub
1. Inadequate Input Validation
// Vulnerable
app.post('/inbox', (req, res) => {
const activity = req.body;
db.query(`INSERT INTO activities VALUES ('${activity.id}')`); // SQL injection
});
// Secure
app.post('/inbox', (req, res) => {
const activity = req.body;
if (!validateActivitySchema(activity)) {
return res.status(400).send('Invalid activity');
}
db.query('INSERT INTO activities VALUES (?)', [activity.id]);
});
2. Missing Signature Verification
// Vulnerable
app.post('/inbox', (req, res) => {
// No signature check
processActivity(req.body);
});
// Secure
app.post('/inbox', async (req, res) => {
if (!await verifyHTTPSignature(req)) {
return res.status(401).send('Invalid signature');
}
processActivity(req.body);
});
3. SSRF in Media Fetching
// Vulnerable
async function fetchAvatar(url) {
return await fetch(url); // No URL validation
}
// Secure
async function fetchAvatar(url) {
const parsed = new URL(url);
// Block internal IPs
if (isInternalIP(parsed.hostname)) {
throw new Error('Invalid URL');
}
// Only allow http/https
if (!['http:', 'https:'].includes(parsed.protocol)) {
throw new Error('Invalid protocol');
}
return await fetch(url, { redirect: 'manual' });
}
4. Unescaped Content Rendering
// Vulnerable
function renderNote(note) {
return `<div>${note.content}</div>`; // XSS
}
// Secure
function renderNote(note) {
const escaped = escapeHtml(note.content);
return `<div>${escaped}</div>`;
}
Security Checklist
- HTTP signatures verified on all inbox POST requests
- Actor URLs validated (no internal IPs, valid protocols)
- Content sanitized before display (HTML escaping)
- Rate limiting on endpoints
- JSON schema validation
- Authorization checks on Delete/Update activities
- SSRF protection on media fetching
- Proper error handling (no sensitive info in errors)
- CSRF protection
- Content Security Policy headers
- Input size limits
- Secure session management
Tools & Resources
Testing Tools
- This ActivityPub Security PoC
- Burp Suite
- OWASP ZAP
- curl/httpie
References
Reporting Format
When reporting issues, include:
- Title: Brief description
- Severity: Critical/High/Medium/Low
- Description: What the vulnerability is
- Steps to Reproduce: Detailed reproduction steps
- Impact: What an attacker could do
- Proof of Concept: Code/payload demonstrating the issue
- Remediation: Suggested fix
- References: Related CVEs, articles
Example Report
## XSS in Note Content
**Severity**: High
**Description**: User-supplied content in Note objects is rendered without HTML escaping, allowing arbitrary JavaScript execution.
**Steps to Reproduce**:
1. Send Create activity with XSS payload in content field
2. View the note in web interface
3. Observe JavaScript execution
**Impact**: Account takeover, data theft, malware distribution
**Proof of Concept**:
```json
{
"type": "Create",
"object": {
"type": "Note",
"content": "<script>alert(document.cookie)</script>"
}
}
Remediation: Implement HTML escaping for all user content before rendering.
## Legal Considerations
- Only test systems you own or have explicit permission to test
- Comply with computer fraud and abuse laws
- Respect bug bounty program terms
- Obtain written authorization for penetration testing
- Don't disrupt services or access private data
## Continuous Testing
Integrate security testing into CI/CD:
```yaml
# .github/workflows/security-test.yml
name: Security Tests
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run security scan
run: |
cd activitypub-security-poc
npm install
npm run mock-server &
sleep 5
node src/cli.js security-scan --target http://localhost:3000/users/alice/inbox