Backend Inferencer Skill
Purpose
Infer backend technologies by analyzing HTTP headers, cookies, error pages, DNS records, and repository data.
Input
Raw signals from Phase 2:
http_signals - Server headers, X-Powered-By, cookies
dns_signals - Service verification TXT records
repository_signals - Dependencies, Dockerfiles
html_signals - Generator meta tags, CMS patterns
Technology Categories
Web Servers
| Technology |
Detection Signals |
Weight |
| nginx |
Server: nginx, nginx error pages |
35-40 |
| Apache |
Server: Apache, Apache error pages |
35-40 |
| Microsoft IIS |
Server: Microsoft-IIS |
40 |
| Caddy |
Server: Caddy |
35 |
| LiteSpeed |
Server: LiteSpeed |
35 |
Programming Languages
| Technology |
Detection Signals |
Weight |
| Node.js |
X-Powered-By: Express, connect.sid cookie |
30-40 |
| Python |
X-Powered-By: gunicorn/Werkzeug, django_session cookie |
30-40 |
| PHP |
X-Powered-By: PHP, PHPSESSID cookie |
35-40 |
| Ruby |
_rails_session cookie, X-Request-Id |
30-40 |
| Java |
JSESSIONID cookie, X-Powered-By: Servlet |
35-40 |
| Go |
Custom patterns, repo analysis |
25-35 |
| .NET |
ASP.NET_SessionId cookie, X-AspNet-Version |
40 |
Backend Frameworks
| Technology |
Detection Signals |
Implies |
Weight |
| Express.js |
X-Powered-By: Express |
Node.js |
40 |
| NestJS |
Nest patterns, repo analysis |
Node.js, TypeScript |
35 |
| Fastify |
Fastify patterns |
Node.js |
35 |
| Django |
csrftoken/django_session cookies |
Python |
40 |
| Flask |
Werkzeug server |
Python |
35 |
| FastAPI |
uvicorn patterns |
Python |
35 |
| Rails |
_rails_session cookie |
Ruby |
40 |
| Laravel |
laravel_session cookie, XSRF-TOKEN |
PHP |
40 |
| Symfony |
symfony cookie patterns |
PHP |
35 |
| Spring |
JSESSIONID, X-Application-Context |
Java |
35 |
| ASP.NET |
ASP.NET_SessionId |
.NET |
40 |
Content Management Systems
| Technology |
Detection Signals |
Weight |
| WordPress |
/wp-content/, /wp-admin/, generator meta |
45 |
| Drupal |
X-Drupal-Cache, /sites/default/ |
45 |
| Joomla |
generator meta, /components/ |
40 |
| Magento |
/skin/frontend/, Mage patterns |
40 |
| Shopify |
myshopify.com, Shopify patterns |
45 |
| Contentful |
Contentful API patterns |
35 |
| Strapi |
Strapi patterns |
35 |
| Ghost |
Ghost generator meta |
40 |
Databases (Indirect Signals)
| Technology |
Detection Signals |
Weight |
| PostgreSQL |
pg dependency, Heroku Postgres |
25-30 |
| MySQL |
mysql dependency, common patterns |
25-30 |
| MongoDB |
mongoose dependency, MongoDB Atlas TXT |
30 |
| Redis |
redis dependency, session patterns |
25-30 |
| Elasticsearch |
elasticsearch dependency |
25-30 |
| DynamoDB |
AWS SDK patterns, boto3 |
25-30 |
API Technologies
| Technology |
Detection Signals |
Weight |
| GraphQL |
/graphql endpoint, schema patterns |
35 |
| REST |
/api/v1, OpenAPI spec |
25 |
| gRPC |
grpc patterns in repos |
30 |
| tRPC |
tRPC patterns |
30 |
Inference Logic
def infer_backend_technologies(signals):
results = []
# Web Server Detection
server_header = signals.http_signals.get('Server', '')
for server in SERVER_PATTERNS:
if server.pattern.match(server_header):
results.append({
"name": server.name,
"category": "Web Server",
"version": extract_version(server_header, server.pattern),
"signals": [{"type": "http_header", "value": f"Server: {server_header}"}],
"total_weight": server.weight
})
# Language/Framework from X-Powered-By
powered_by = signals.http_signals.get('X-Powered-By', '')
for framework in POWERED_BY_PATTERNS:
if framework.pattern in powered_by:
results.append({
"name": framework.name,
"category": framework.category,
"implies": framework.implies,
"signals": [{"type": "http_header", "value": f"X-Powered-By: {powered_by}"}],
"total_weight": framework.weight
})
# Cookie-based Detection
for cookie in signals.http_signals.cookies:
for pattern in COOKIE_PATTERNS:
if pattern.name in cookie:
results.append({
"name": pattern.tech,
"category": pattern.category,
"implies": pattern.implies,
"signals": [{"type": "cookie", "value": f"Cookie: {cookie}"}],
"total_weight": pattern.weight
})
# CMS Detection from HTML
for cms in CMS_PATTERNS:
score = 0
evidence = []
if cms.generator_pattern in signals.html_signals.generators:
score += 40
evidence.append("Generator meta tag")
for url_pattern in cms.url_patterns:
if url_pattern in signals.html_signals.script_urls:
score += 20
evidence.append(f"URL pattern: {url_pattern}")
if score > 0:
results.append({
"name": cms.name,
"category": "CMS",
"signals": evidence,
"total_weight": score
})
# Repository-based Detection
if signals.repository_signals:
for dep_file, deps in signals.repository_signals.dependencies.items():
for dep in deps:
if dep.name in DEPENDENCY_PATTERNS:
pattern = DEPENDENCY_PATTERNS[dep.name]
results.append({
"name": pattern.tech,
"category": pattern.category,
"version": dep.version,
"signals": [{"type": "dependency", "value": f"{dep.name}@{dep.version}"}],
"total_weight": pattern.weight
})
return results
Output
{
"skill": "backend_inferencer",
"results": {
"technologies": [
{
"name": "nginx",
"category": "Web Server",
"version": "1.18.0",
"signals": [
{
"type": "http_header",
"value": "Server: nginx/1.18.0",
"source": "https://example.com",
"weight": 40
}
],
"total_weight": 40
},
{
"name": "Express.js",
"category": "Backend Framework",
"signals": [
{
"type": "http_header",
"value": "X-Powered-By: Express",
"source": "https://api.example.com",
"weight": 40
},
{
"type": "cookie",
"value": "connect.sid session cookie",
"source": "https://example.com",
"weight": 30
}
],
"total_weight": 70,
"implies": ["Node.js"]
},
{
"name": "Node.js",
"category": "Runtime",
"signals": [
{
"type": "implied",
"value": "Implied by Express.js detection",
"weight": 0
},
{
"type": "dependency",
"value": "node version in package.json",
"source": "github.com/example/repo",
"weight": 35
}
],
"total_weight": 35
},
{
"name": "PostgreSQL",
"category": "Database",
"signals": [
{
"type": "dependency",
"value": "pg@8.11.0 in package.json",
"source": "github.com/example/repo",
"weight": 30
}
],
"total_weight": 30
}
],
"implied_technologies": [
{
"name": "Node.js",
"implied_by": ["Express.js"],
"confidence": "High"
}
],
"summary": {
"web_server": "nginx",
"runtime": "Node.js",
"framework": "Express.js",
"database": "PostgreSQL",
"cms": null
}
}
}
Version Detection
From Headers
Server: nginx/1.18.0 → nginx 1.18.0
X-Powered-By: PHP/8.1.0 → PHP 8.1.0
X-AspNet-Version: 4.0.30319 → ASP.NET 4.x
From Dependencies
// package.json
"express": "^4.18.2" → Express.js 4.18.x
// requirements.txt
Django==4.2.1 → Django 4.2.1
// Gemfile
gem 'rails', '~> 7.0' → Rails 7.0.x
Error Handling
- Missing headers: Continue with other signals
- Ambiguous cookies: Include all possibilities
- Conflicting signals: Report both, flag for correlation phase
1---2name: backend-inferencer3description: Infers backend technologies including servers, languages, frameworks, databases, and CMS4---56# Backend Inferencer Skill78## Purpose910Infer backend technologies by analyzing HTTP headers, cookies, error pages, DNS records, and repository data.1112## Input1314Raw signals from Phase 2:15- `http_signals` - Server headers, X-Powered-By, cookies16- `dns_signals` - Service verification TXT records17- `repository_signals` - Dependencies, Dockerfiles18- `html_signals` - Generator meta tags, CMS patterns1920## Technology Categories2122### Web Servers2324| Technology | Detection Signals | Weight |25|------------|-------------------|--------|26| nginx | Server: nginx, nginx error pages | 35-40 |27| Apache | Server: Apache, Apache error pages | 35-40 |28| Microsoft IIS | Server: Microsoft-IIS | 40 |29| Caddy | Server: Caddy | 35 |30| LiteSpeed | Server: LiteSpeed | 35 |3132### Programming Languages3334| Technology | Detection Signals | Weight |35|------------|-------------------|--------|36| Node.js | X-Powered-By: Express, connect.sid cookie | 30-40 |37| Python | X-Powered-By: gunicorn/Werkzeug, django_session cookie | 30-40 |38| PHP | X-Powered-By: PHP, PHPSESSID cookie | 35-40 |39| Ruby | _rails_session cookie, X-Request-Id | 30-40 |40| Java | JSESSIONID cookie, X-Powered-By: Servlet | 35-40 |41| Go | Custom patterns, repo analysis | 25-35 |42| .NET | ASP.NET_SessionId cookie, X-AspNet-Version | 40 |4344### Backend Frameworks4546| Technology | Detection Signals | Implies | Weight |47|------------|-------------------|---------|--------|48| Express.js | X-Powered-By: Express | Node.js | 40 |49| NestJS | Nest patterns, repo analysis | Node.js, TypeScript | 35 |50| Fastify | Fastify patterns | Node.js | 35 |51| Django | csrftoken/django_session cookies | Python | 40 |52| Flask | Werkzeug server | Python | 35 |53| FastAPI | uvicorn patterns | Python | 35 |54| Rails | _rails_session cookie | Ruby | 40 |55| Laravel | laravel_session cookie, XSRF-TOKEN | PHP | 40 |56| Symfony | symfony cookie patterns | PHP | 35 |57| Spring | JSESSIONID, X-Application-Context | Java | 35 |58| ASP.NET | ASP.NET_SessionId | .NET | 40 |5960### Content Management Systems6162| Technology | Detection Signals | Weight |63|------------|-------------------|--------|64| WordPress | /wp-content/, /wp-admin/, generator meta | 45 |65| Drupal | X-Drupal-Cache, /sites/default/ | 45 |66| Joomla | generator meta, /components/ | 40 |67| Magento | /skin/frontend/, Mage patterns | 40 |68| Shopify | myshopify.com, Shopify patterns | 45 |69| Contentful | Contentful API patterns | 35 |70| Strapi | Strapi patterns | 35 |71| Ghost | Ghost generator meta | 40 |7273### Databases (Indirect Signals)7475| Technology | Detection Signals | Weight |76|------------|-------------------|--------|77| PostgreSQL | pg dependency, Heroku Postgres | 25-30 |78| MySQL | mysql dependency, common patterns | 25-30 |79| MongoDB | mongoose dependency, MongoDB Atlas TXT | 30 |80| Redis | redis dependency, session patterns | 25-30 |81| Elasticsearch | elasticsearch dependency | 25-30 |82| DynamoDB | AWS SDK patterns, boto3 | 25-30 |8384### API Technologies8586| Technology | Detection Signals | Weight |87|------------|-------------------|--------|88| GraphQL | /graphql endpoint, schema patterns | 35 |89| REST | /api/v1, OpenAPI spec | 25 |90| gRPC | grpc patterns in repos | 30 |91| tRPC | tRPC patterns | 30 |9293## Inference Logic9495```python96def infer_backend_technologies(signals):97 results = []9899 # Web Server Detection100 server_header = signals.http_signals.get('Server', '')101 for server in SERVER_PATTERNS:102 if server.pattern.match(server_header):103 results.append({104 "name": server.name,105 "category": "Web Server",106 "version": extract_version(server_header, server.pattern),107 "signals": [{"type": "http_header", "value": f"Server: {server_header}"}],108 "total_weight": server.weight109 })110111 # Language/Framework from X-Powered-By112 powered_by = signals.http_signals.get('X-Powered-By', '')113 for framework in POWERED_BY_PATTERNS:114 if framework.pattern in powered_by:115 results.append({116 "name": framework.name,117 "category": framework.category,118 "implies": framework.implies,119 "signals": [{"type": "http_header", "value": f"X-Powered-By: {powered_by}"}],120 "total_weight": framework.weight121 })122123 # Cookie-based Detection124 for cookie in signals.http_signals.cookies:125 for pattern in COOKIE_PATTERNS:126 if pattern.name in cookie:127 results.append({128 "name": pattern.tech,129 "category": pattern.category,130 "implies": pattern.implies,131 "signals": [{"type": "cookie", "value": f"Cookie: {cookie}"}],132 "total_weight": pattern.weight133 })134135 # CMS Detection from HTML136 for cms in CMS_PATTERNS:137 score = 0138 evidence = []139140 if cms.generator_pattern in signals.html_signals.generators:141 score += 40142 evidence.append("Generator meta tag")143144 for url_pattern in cms.url_patterns:145 if url_pattern in signals.html_signals.script_urls:146 score += 20147 evidence.append(f"URL pattern: {url_pattern}")148149 if score > 0:150 results.append({151 "name": cms.name,152 "category": "CMS",153 "signals": evidence,154 "total_weight": score155 })156157 # Repository-based Detection158 if signals.repository_signals:159 for dep_file, deps in signals.repository_signals.dependencies.items():160 for dep in deps:161 if dep.name in DEPENDENCY_PATTERNS:162 pattern = DEPENDENCY_PATTERNS[dep.name]163 results.append({164 "name": pattern.tech,165 "category": pattern.category,166 "version": dep.version,167 "signals": [{"type": "dependency", "value": f"{dep.name}@{dep.version}"}],168 "total_weight": pattern.weight169 })170171 return results172```173174## Output175176```json177{178 "skill": "backend_inferencer",179 "results": {180 "technologies": [181 {182 "name": "nginx",183 "category": "Web Server",184 "version": "1.18.0",185 "signals": [186 {187 "type": "http_header",188 "value": "Server: nginx/1.18.0",189 "source": "https://example.com",190 "weight": 40191 }192 ],193 "total_weight": 40194 },195 {196 "name": "Express.js",197 "category": "Backend Framework",198 "signals": [199 {200 "type": "http_header",201 "value": "X-Powered-By: Express",202 "source": "https://api.example.com",203 "weight": 40204 },205 {206 "type": "cookie",207 "value": "connect.sid session cookie",208 "source": "https://example.com",209 "weight": 30210 }211 ],212 "total_weight": 70,213 "implies": ["Node.js"]214 },215 {216 "name": "Node.js",217 "category": "Runtime",218 "signals": [219 {220 "type": "implied",221 "value": "Implied by Express.js detection",222 "weight": 0223 },224 {225 "type": "dependency",226 "value": "node version in package.json",227 "source": "github.com/example/repo",228 "weight": 35229 }230 ],231 "total_weight": 35232 },233 {234 "name": "PostgreSQL",235 "category": "Database",236 "signals": [237 {238 "type": "dependency",239 "value": "pg@8.11.0 in package.json",240 "source": "github.com/example/repo",241 "weight": 30242 }243 ],244 "total_weight": 30245 }246 ],247 "implied_technologies": [248 {249 "name": "Node.js",250 "implied_by": ["Express.js"],251 "confidence": "High"252 }253 ],254 "summary": {255 "web_server": "nginx",256 "runtime": "Node.js",257 "framework": "Express.js",258 "database": "PostgreSQL",259 "cms": null260 }261 }262}263```264265## Version Detection266267### From Headers268```269Server: nginx/1.18.0 → nginx 1.18.0270X-Powered-By: PHP/8.1.0 → PHP 8.1.0271X-AspNet-Version: 4.0.30319 → ASP.NET 4.x272```273274### From Dependencies275```json276// package.json277"express": "^4.18.2" → Express.js 4.18.x278279// requirements.txt280Django==4.2.1 → Django 4.2.1281282// Gemfile283gem 'rails', '~> 7.0' → Rails 7.0.x284```285286## Error Handling287288- Missing headers: Continue with other signals289- Ambiguous cookies: Include all possibilities290- Conflicting signals: Report both, flag for correlation phase