Static analysis

kern review

Static analysis for code written by people, agents, and LLMs.

kern review is a semantic companion to your linter. It combines AST rules, TypeScript and Python concept extraction, taint analysis, native .kern review rules, confidence scoring, and MCP security checks.

See it catch a prompt injection — live

Your codevulnerable
async function chat(db, llm, userId) {
  // DB results go straight into prompt
  const history = await db.query(
    `SELECT msg FROM chat
     WHERE user_id = '${userId}'`
  );

  const prompt =
    `Assistant: ${history.rows
      .map(r => r.msg).join('\n')}`

  // User input unsanitized
  return llm.complete(prompt);
}
kern review output
! indirect-prompt-injection
  DB result 'history' from db.query
  used in LLM prompt without
  sanitization — indirect injection
  risk
  chat.ts:9

~ unguarded-effect
  Network/DB effect without
  auth/validation guard
  chat.ts:3

~ unrecovered-effect
  db effect without error recovery
  chat.ts:3

Syntax linters can miss this class of generated-code bug. kern review follows the data and effect boundaries.

kern review src/ --recursive
  @kernlang/review — analyzing src/

  ! indirect-prompt-injection
    DB result used in LLM prompt without sanitization
    src/chat/handler.ts:9

  ! llm-output-execution
    LLM output passed to eval() — arbitrary code execution
    src/agent/runner.ts:17

  ! prompt-injection
    User input embedded in prompt without sanitization
    src/api/chat.ts:23

  ~ encoding-bypass
    Decoded content from Buffer.from() used in prompt
    src/utils/decode.ts:50

  ~ json-output-manipulation
    JSON.parse on LLM output without schema validation
    src/api/structured.ts:69

  ~ missing-output-validation
    LLM response used without validation
    src/codegen/generate.ts:75

  ~ unguarded-effect  (×3)
    Network/DB effect without error recovery

  ~ rag-poisoning
    Retrieval result embedded in prompt unsanitized
    src/rag/search.ts:28

  ~ tool-calling-manipulation
    LLM-returned tool calls executed without allowlist
    src/agent/tools.ts:41

  ~ unsanitized-history
    Unsanitized messages spread into LLM API call
    src/chat/multi-turn.ts:63

   847 lines scanned · 3 errors · 8 warnings
   prompt-injection patterns reviewed

Representative output from the security benchmark patterns. The important part is the file:line evidence and rule ID.

233

rule registry entries

12

MCP security rule IDs

2

languages (TS + Python)

conf

scored findings

What kern review catches

kern review doesn't just lint syntax. It understands concepts: entrypoints, effects, guards, state mutations, boundaries.

Security

rules

Prompt injection patterns, RAG poisoning, encoding bypasses, taint analysis, path traversal, prototype pollution, crypto issues, and sensitive logs

React

rules

Hooks, composition, setState in render, stale closures, conditional hooks, missing deps, render side effects

Base

rules

Floating promises, unused exports, complex conditionals, hardcoded secrets, handler size, memory leaks

Dead Logic

rules

Unreachable code after return, dead branches, exhaustiveness gaps in switches, unused collections

Framework

rules

Next.js App Router, Express middleware, Vue reactivity, Nuxt SSR, FastAPI async, Terminal, Ink, CLI

A11y + Perf + Async

rules

Accessibility checks, performance patterns, abort-controller leaks, Promise.all handling, and async safety

Concepts

graph

Concept rules reason over entrypoints, effects, guards, mutations, boundaries, routes, request bodies, and response shapes

MCP Security

12 IDs

Command injection, path traversal, tool poisoning, secrets exposure, missing auth, typosquatting, data injection, and resource exhaustion

How it compares

kern review isn't trying to replace your linter. It catches what they miss.

kern reviewESLintSonarQube
Concept-level analysisYesNoLimited
Prompt-injection review patternsYesRulepack-dependentRulepack-dependent
LLM-ready outputYes (5x smaller IR)NoNo
TypeScript + PythonBothTS onlyMany languages
Framework-aware rulesNext.js, Express, VueVia pluginsLimited
Rule count233 registry entriesHundredsThousands
SARIF / CI integrationYesYesYes
Free for developersYesYesCommunity only

ESLint and SonarQube have more rules and broader language coverage. kern review focuses on concept-level generated-code analysis, prompt-injection review patterns, and LLM-exportable findings. Use them together.

Prompt injection detection

CWE-1427: Improper Neutralization of Input Used for LLM Prompting. The Kern repo includes a security benchmark with 10 code patterns for LLM prompt-injection style failures.

The benchmark file is public: examples/security-benchmark.ts. Use this table as a reproducible project benchmark, not a universal claim about every codebase.

The practical reason to run Kern here is evidence: it points to the exact source span where untrusted data enters prompts, tools, eval, JSON parsing, or output handling.

Attack vectorkernEvidenceScopeStatus
Indirect injection (DB→prompt)Yessource spandata to promptactive
LLM output executionYessource spaneval boundaryactive
System prompt leakageYessource spanprompt boundaryactive
RAG poisoningYessource spanretrieval flowactive
Tool calling manipulationYessource spantool boundaryactive
Encoding bypassesYessource spanencoded inputactive
Delimiter injectionYessource spanprompt formatactive
Unsanitized historyYessource spanchat historyactive
JSON output manipulationYessource spanoutput parsingactive
Missing output validationYessource spanvalidationactive
Project benchmarkcoveredfile:linegenerated-code flowsdocumented

Methodology

The project benchmark file contains vulnerable TypeScript patterns used to exercise generated-code review rules. Keep benchmark examples in context: rulepacks change, and results vary by configuration.

Run the project benchmark locally:

kern review examples/security-benchmark.ts

These checks are mapped to prompt-injection and generated-code failure modes such as RAG poisoning, encoding bypass, delimiter injection, tool calling validation, and unsanitized history. Mapped to CWE-1427 and OWASP LLM01:2025.

MCP server security

12 rules purpose-built for MCP servers. Static analysis that scans the code that makes the server dangerous — no running server required.

Mapped to OWASP MCP Top 10 categories with source-code rule IDs for dangerous MCP server patterns.

kern review --mcp server.ts
// Vulnerable MCP server
server.tool('run', 'Run command', {}, async (params) => {
  execSync(`${params.cmd}`);
});

! mcp-command-injection
  Shell command execution in MCP tool handler
  server.ts:3  confidence: 0.95

! mcp-ir-unguarded-effect
  action "run" has shell-exec effect without any guard
  server.ts:3  confidence: 0.90
Capabilitykern reviewmcp-scanProximity
Analysis typeStatic (source code)Dynamic (running server)Dynamic (running server)
LanguagesTypeScript + PythonAny (protocol-level)Any (protocol-level)
Prompt injectionYes (code + data)Yes (tool descriptions)Yes (tool descriptions)
Command injectionYes (taint + IR)NoNo
Path traversalYes (AST + IR)NoNo
Secrets detectionYes (pattern + base64)NoNo
Auth checksYes (middleware)NoNo
Structural analysisYes (KERN IR)NoNo
Requires running serverNoYesYes
Confidence scoringYes (0.70–0.95)NoNo

KERN scans the code that makes the server dangerous. mcp-scan checks running servers. Use both.

Free CLI. Hosted and BYOK tiers for teams.

See pricing →