security-posture-analyzer
SKILL.md
Security Posture Analyzer Skill
Purpose
Analyze the organization's security posture by examining security headers, Content Security Policy, HSTS configuration, security.txt file, and other security indicators.
Input
Raw signals from Phase 2:
http_signals- Security headers, CSP, HSTSdns_signals- DMARC, SPF, DKIM recordshtml_signals- Meta tags for security policiesrepository_signals- Security configurations
Security Categories
HTTP Security Headers
| Header | Purpose | Strength Indicator |
|---|---|---|
| Strict-Transport-Security | HTTPS enforcement | max-age value, includeSubDomains |
| Content-Security-Policy | XSS prevention | Policy complexity |
| X-Frame-Options | Clickjacking prevention | DENY vs SAMEORIGIN |
| X-Content-Type-Options | MIME sniffing prevention | nosniff |
| X-XSS-Protection | XSS filter (legacy) | 1; mode=block |
| Referrer-Policy | Referrer leakage control | strict-origin-when-cross-origin |
| Permissions-Policy | Feature restrictions | Comprehensive vs minimal |
| Cross-Origin-Opener-Policy | Cross-origin isolation | same-origin |
| Cross-Origin-Embedder-Policy | Embedding restrictions | require-corp |
| Cross-Origin-Resource-Policy | Resource sharing control | same-origin |
Content Security Policy Analysis
| Directive | Security Implication |
|---|---|
| default-src 'self' | Restrictive baseline |
| script-src 'unsafe-inline' | XSS vulnerability |
| script-src 'unsafe-eval' | Code injection risk |
| upgrade-insecure-requests | Mixed content handling |
| report-uri / report-to | Active monitoring |
Email Security (DNS)
| Record | Purpose |
|---|---|
| SPF (TXT) | Email sender validation |
| DKIM | Email signing |
| DMARC | Email authentication policy |
| MTA-STS | Email transport security |
Security Discovery Files
| File | Purpose |
|---|---|
| /.well-known/security.txt | Security contact info |
| /security.txt | Security contact info |
| /.well-known/change-password | Password change endpoint |
| /humans.txt | Team information |
Analysis Logic
def analyze_security_posture(signals):
results = {
"security_headers": [],
"csp_analysis": None,
"email_security": [],
"security_files": [],
"overall_score": 0,
"technologies_detected": []
}
# Security Header Analysis
for header in SECURITY_HEADERS:
if header.name in signals.http_signals.headers:
value = signals.http_signals.headers[header.name]
score, analysis = analyze_header(header.name, value)
results["security_headers"].append({
"header": header.name,
"value": value,
"present": True,
"score": score,
"analysis": analysis
})
results["overall_score"] += score
else:
results["security_headers"].append({
"header": header.name,
"present": False,
"recommendation": header.recommendation
})
# CSP Deep Analysis
if 'Content-Security-Policy' in signals.http_signals.headers:
csp = signals.http_signals.headers['Content-Security-Policy']
results["csp_analysis"] = analyze_csp(csp)
# Extract third-party domains from CSP
third_parties = extract_csp_domains(csp)
for domain in third_parties:
results["technologies_detected"].append({
"name": identify_service(domain),
"source": "CSP allowed domain",
"domain": domain
})
# Email Security Analysis
for record_type in ['SPF', 'DMARC', 'DKIM']:
for txt in signals.dns_signals.txt_records:
if record_type.lower() in txt.lower() or is_record_type(txt, record_type):
score, analysis = analyze_email_record(record_type, txt)
results["email_security"].append({
"type": record_type,
"value": txt,
"score": score,
"analysis": analysis
})
# Security File Discovery
security_files = [
"/.well-known/security.txt",
"/security.txt"
]
for file_url in security_files:
# Check if file exists in signals
if file_exists_in_signals(signals, file_url):
content = get_file_content(signals, file_url)
results["security_files"].append({
"path": file_url,
"exists": True,
"content_analysis": analyze_security_txt(content)
})
return results
CSP Analysis Function
def analyze_csp(csp_value):
directives = parse_csp(csp_value)
analysis = {
"directives_count": len(directives),
"security_level": "Unknown",
"issues": [],
"strengths": [],
"third_party_domains": []
}
# Check for unsafe directives
if "'unsafe-inline'" in csp_value:
analysis["issues"].append({
"severity": "High",
"issue": "unsafe-inline allows inline scripts",
"recommendation": "Use nonces or hashes instead"
})
if "'unsafe-eval'" in csp_value:
analysis["issues"].append({
"severity": "High",
"issue": "unsafe-eval allows dynamic code execution",
"recommendation": "Refactor to avoid eval()"
})
# Check for good practices
if "upgrade-insecure-requests" in csp_value:
analysis["strengths"].append("Upgrades HTTP to HTTPS")
if "report-uri" in csp_value or "report-to" in csp_value:
analysis["strengths"].append("CSP violation reporting enabled")
if "default-src 'self'" in csp_value:
analysis["strengths"].append("Restrictive default policy")
# Extract allowed domains
domains = re.findall(r'https?://([^\s;\'\"]+)', csp_value)
analysis["third_party_domains"] = list(set(domains))
# Calculate security level
if len(analysis["issues"]) == 0 and len(analysis["strengths"]) >= 3:
analysis["security_level"] = "Strong"
elif len(analysis["issues"]) <= 1:
analysis["security_level"] = "Moderate"
else:
analysis["security_level"] = "Weak"
return analysis
Output
{
"skill": "security_posture_analyzer",
"results": {
"security_headers": [
{
"header": "Strict-Transport-Security",
"value": "max-age=31536000; includeSubDomains; preload",
"present": true,
"score": 10,
"analysis": {
"max_age": 31536000,
"include_subdomains": true,
"preload": true,
"assessment": "Strong - HSTS preload eligible"
}
},
{
"header": "Content-Security-Policy",
"value": "default-src 'self'; script-src 'self' https://cdn.example.com; ...",
"present": true,
"score": 8,
"analysis": "See csp_analysis"
},
{
"header": "X-Frame-Options",
"present": false,
"recommendation": "Add 'X-Frame-Options: DENY' to prevent clickjacking"
}
],
"csp_analysis": {
"directives_count": 8,
"security_level": "Moderate",
"issues": [
{
"severity": "Medium",
"issue": "Script sources include external CDN",
"domain": "cdn.example.com"
}
],
"strengths": [
"Restrictive default policy",
"CSP violation reporting enabled"
],
"third_party_domains": [
"cdn.example.com",
"analytics.example.com",
"api.stripe.com"
]
},
"email_security": [
{
"type": "SPF",
"value": "v=spf1 include:_spf.google.com ~all",
"score": 7,
"analysis": "Good - SPF configured with softfail"
},
{
"type": "DMARC",
"value": "v=DMARC1; p=reject; rua=mailto:dmarc@example.com",
"score": 10,
"analysis": "Strong - DMARC reject policy with reporting"
}
],
"security_files": [
{
"path": "/.well-known/security.txt",
"exists": true,
"content_analysis": {
"contact": "security@example.com",
"encryption_key": true,
"bug_bounty": "https://example.com/bug-bounty",
"expires": "2025-12-31"
}
}
],
"overall_score": {
"score": 72,
"max_score": 100,
"grade": "B",
"assessment": "Good security posture with some improvements needed"
},
"technologies_detected": [
{
"name": "Google Workspace",
"source": "SPF include",
"confidence": 90
},
{
"name": "Stripe",
"source": "CSP allowed domain: api.stripe.com",
"confidence": 95
}
],
"recommendations": [
{
"priority": "High",
"item": "Add X-Frame-Options header",
"current": "Missing",
"recommended": "DENY"
},
{
"priority": "Medium",
"item": "Enable HSTS preload",
"current": "Not preloaded",
"recommended": "Submit to HSTS preload list"
}
]
}
}
Third-Party Detection from Security Headers
| CSP Domain Pattern | Service |
|---|---|
| *.stripe.com | Stripe Payments |
| *.google-analytics.com | Google Analytics |
| *.googletagmanager.com | Google Tag Manager |
| *.facebook.com | Facebook SDK |
| *.intercom.io | Intercom |
| *.zendesk.com | Zendesk |
| *.sentry.io | Sentry Error Tracking |
| .datadog.com | Datadog |
| *.newrelic.com | New Relic |
Error Handling
- Missing headers: Note as finding, provide recommendations
- Malformed CSP: Parse what's possible, flag errors
- DNS lookup failures: Continue with HTTP-based analysis
Weekly Installs
5
Repository
transilienceai/…itytoolsGitHub Stars
67
First Seen
13 days ago
Security Audits
Installed on
opencode5
gemini-cli5
github-copilot5
codex5
amp5
cline5