Report Type
Technical Analysis
Deep-dive technical reports for security engineers and developers. Includes code context, data flow diagrams, and remediation guidance.
Overview
Technical analysis reports provide the detailed information developers need to understand and fix vulnerabilities. Each finding includes full code context, data flow traces, and specific remediation instructions.
Bash
1# Generate technical analysis report2bloodhound report technical --output analysis.html34# JSON format for integration with other tools5bloodhound report technical --format json --output analysis.json67# Focus on specific severity levels8bloodhound report technical --severity critical,high --output critical-analysis.md910# Include full code context (±20 lines)11bloodhound report technical --context 20 --output detailed-analysis.html
Full Context
Code snippets
Data Flow
Trace diagrams
Fix Code
Ready to apply
Finding Details
Each finding in the technical report includes comprehensive details for understanding and fixing the issue.
Text
1# Sample Technical Finding23═══════════════════════════════════════════════════════════════════4FINDING: SQL-INJ-0015═══════════════════════════════════════════════════════════════════67Title: SQL Injection via User Input8Severity: CRITICAL9CWE: CWE-89 (SQL Injection)10CVSS: 9.8 (Critical)11File: src/api/users/controller.ts12Line: 14213Function: getUserById()1415DESCRIPTION16───────────────────────────────────────────────────────────────────17User-supplied input from the 'id' parameter is concatenated directly18into an SQL query without sanitization or parameterization. An19attacker can inject arbitrary SQL commands to read, modify, or20delete database contents.2122DETECTION ENGINE23───────────────────────────────────────────────────────────────────24Primary: Taint Analysis (confidence: 98%)25Confirmed by: Pattern Matching, SAST2627EXPLOITABILITY28───────────────────────────────────────────────────────────────────29Attack Vector: Network (public API endpoint)30Complexity: Low (no authentication required)31Privileges: None32User Interaction: None3334PROOF OF CONCEPT35───────────────────────────────────────────────────────────────────36Request:37 GET /api/users/1' OR '1'='1' --3839Expected Result:40 Returns all users in database, bypassing ID filter4142Automated Test:43 bloodhound test SQL-INJ-001 --target http://localhost:3000
Code Context
Full code context with syntax highlighting and vulnerability markers.
Text
1VULNERABLE CODE2───────────────────────────────────────────────────────────────────3File: src/api/users/controller.ts45 135 │ import { db } from '../database';6 136 │ import { Request, Response } from 'express';7 137 │8 138 │ export async function getUserById(req: Request, res: Response) {9 139 │ const userId = req.params.id; // ← TAINT SOURCE10 140 │11 141 │ // VULNERABILITY: Unsanitized user input in SQL query12 ► 142 │ const query = `SELECT * FROM users WHERE id = '${userId}'`;13 │ ^^^^^^^^14 │ TAINT SINK15 143 │16 144 │ try {17 145 │ const result = await db.query(query); // ← SQL executed18 146 │ res.json(result.rows[0]);19 147 │ } catch (error) {20 148 │ res.status(500).json({ error: 'Database error' });21 149 │ }22 150 │ }2324TAINT FLOW25───────────────────────────────────────────────────────────────────26req.params.id (line 139)27 │28 ▼ [Assignment]29userId (line 139)30 │31 ▼ [String Interpolation]32query (line 142) ← SQL Injection Point33 │34 ▼ [Function Argument]35db.query(query) (line 145) ← SQL Execution
Data Flow Analysis
Visual representation of how tainted data flows through your application.
Text
1DATA FLOW DIAGRAM2───────────────────────────────────────────────────────────────────34┌─────────────────────────────────────────────────────────────────┐5│ HTTP Request │6│ GET /api/users/:id │7└─────────────────────────────────────────────────────────────────┘8 │9 ▼10┌─────────────────────────────────────────────────────────────────┐11│ Express Router │12│ routes/users.ts:12 │13│ router.get('/:id', getUserById) │14└─────────────────────────────────────────────────────────────────┘15 │16 ▼17┌─────────────────────────────────────────────────────────────────┐18│ Controller │19│ controller.ts:139 │20│ const userId = req.params.id ◄── TAINT SOURCE │21└─────────────────────────────────────────────────────────────────┘22 │23 ▼ (propagates through assignment)24┌─────────────────────────────────────────────────────────────────┐25│ String Template │26│ controller.ts:142 │27│ `SELECT * FROM users WHERE id = '${userId}'` ◄── TAINT SINK │28│ │29│ ⚠️ NO SANITIZER APPLIED │30└─────────────────────────────────────────────────────────────────┘31 │32 ▼33┌─────────────────────────────────────────────────────────────────┐34│ Database Adapter │35│ database.ts:45 │36│ pool.query(queryString) ◄── SQL EXECUTION │37└─────────────────────────────────────────────────────────────────┘3839MISSING SANITIZERS40───────────────────────────────────────────────────────────────────41The following sanitizers would have prevented this vulnerability:4243• db.query() with parameterized query: db.query('SELECT ... WHERE id = $1', [id])44• Input validation: parseInt(id) or UUID validation45• ORM usage: User.findByPk(id) (Sequelize) or prisma.user.findUnique()
Engine Insights
Understand how each analysis engine contributed to the finding.
Text
1ENGINE ANALYSIS2───────────────────────────────────────────────────────────────────34┌─────────────────────────────────────────────────────────────────┐5│ Engine 1: Pattern Matching │6├─────────────────────────────────────────────────────────────────┤7│ Matched Pattern: sql-injection-template-literal │8│ Confidence: HIGH (92%) │9│ Regex: /\`SELECT.*FROM.*WHERE.*\$\{.*\}\`/ │10│ Note: Template literal with variable interpolation in SQL │11└─────────────────────────────────────────────────────────────────┘1213┌─────────────────────────────────────────────────────────────────┐14│ Engine 4: Taint Analysis │15├─────────────────────────────────────────────────────────────────┤16│ Taint Source: req.params (HTTP request parameter) │17│ Taint Sink: db.query() (SQL execution) │18│ Path Length: 3 nodes │19│ Sanitizers Found: 0 │20│ Confidence: VERY HIGH (98%) │21│ │22│ Interprocedural: YES (crosses function boundaries) │23│ Cross-file: YES (routes/users.ts → controller.ts → database.ts) │24└─────────────────────────────────────────────────────────────────┘2526┌─────────────────────────────────────────────────────────────────┐27│ Engine 7: AI Verification │28├─────────────────────────────────────────────────────────────────┤29│ False Positive Check: PASSED (this is a real vulnerability) │30│ │31│ AI Analysis: │32│ "The req.params.id value is used directly in a SQL template │33│ string without any validation, escaping, or parameterization. │34│ The db.query() function executes raw SQL, making this a │35│ confirmed SQL injection vulnerability." │36│ │37│ Severity Calibration: CRITICAL (no changes from base score) │38│ Reason: Public endpoint, no authentication, database access │39└─────────────────────────────────────────────────────────────────┘
Remediation Code
Ready-to-apply fixes tailored to your codebase patterns.
Diff
1RECOMMENDED FIX2───────────────────────────────────────────────────────────────────34Option 1: Parameterized Query (Recommended)5───────────────────────────────────────────────────────────────────67- const query = `SELECT * FROM users WHERE id = '${userId}'`;8- const result = await db.query(query);9+ const query = 'SELECT * FROM users WHERE id = $1';10+ const result = await db.query(query, [userId]);111213Option 2: Input Validation + Parameterization14───────────────────────────────────────────────────────────────────1516+ import { z } from 'zod';17+18+ const userIdSchema = z.string().uuid();19+20 export async function getUserById(req: Request, res: Response) {21- const userId = req.params.id;22+ const parseResult = userIdSchema.safeParse(req.params.id);23+ if (!parseResult.success) {24+ return res.status(400).json({ error: 'Invalid user ID format' });25+ }26+ const userId = parseResult.data;2728 const query = 'SELECT * FROM users WHERE id = $1';29 const result = await db.query(query, [userId]);303132Option 3: Use ORM (Your codebase uses Prisma elsewhere)33───────────────────────────────────────────────────────────────────3435+ import { prisma } from '../prisma';3637 export async function getUserById(req: Request, res: Response) {38- const userId = req.params.id;39- const query = `SELECT * FROM users WHERE id = '${userId}'`;40- const result = await db.query(query);41- res.json(result.rows[0]);42+ const user = await prisma.user.findUnique({43+ where: { id: req.params.id }44+ });45+ if (!user) {46+ return res.status(404).json({ error: 'User not found' });47+ }48+ res.json(user);49 }505152APPLY FIX53───────────────────────────────────────────────────────────────────54# Preview the fix55bloodhound fix SQL-INJ-001 --preview5657# Apply automatically58bloodhound fix SQL-INJ-001 --apply5960# Apply with specific option61bloodhound fix SQL-INJ-001 --option 2 --apply
Automatic Fixes
Use
bloodhound fix --apply to automatically apply fixes. Changes are staged for review before committing.