Starphix
Software Engineering / Sources
The Lab / Sources / Software Engineering / Tools/Static-Analysis.md

Static Analysis

Linting, type checking, and static application security testing (SAST) for code quality and security.


Static Analysis Categories

Category Purpose When It Runs
Linting Style, best practices, potential bugs Every commit (pre-commit), CI
Type Checking Type safety, contract verification Every commit, CI
SAST Security vulnerabilities in code CI, scheduled, pre-merge
Dependency Scanning Vulnerable/outdated dependencies CI, scheduled, PR
Secrets Detection Hardcoded secrets, API keys Pre-commit, CI, push

Language-Specific Tooling

TypeScript / JavaScript

Tool Purpose Config
Biome Lint + format (fast, Rust) biome.json
ESLint Lint (extensible, plugin ecosystem) eslint.config.js (flat)
Prettier Format (opinionated) .prettierrc
TypeScript Type check tsconfig.json
tsc --noEmit Fast type check —

Recommended: Biome (replaces ESLint + Prettier + lint-staged)

// biome.json
{
  "$schema": "https://biomejs.dev/schemas/1.8.0/schema.json",
  "organizeImports": { "enabled": true },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "correctness": { "noUnusedVariables": "error" },
      "style": { "useConst": "error", "noNonNullAssertion": "warn" },
      "suspicious": { "noExplicitAny": "error" }
    }
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100
  },
  "javascript": {
    "formatter": { "quoteStyle": "double", "trailingCommas": "es5" }
  }
}

TypeScript Strict Config

// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "lib": ["ES2022"],
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true,
    "resolveJsonModule": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true
  }
}

Python

Tool Purpose
Ruff Lint + format (replaces flake8, black, isort, pyupgrade)
mypy Type checking
pyright Fast type checking (VS Code Pylance)

Ruff Config

# pyproject.toml
[tool.ruff]
target-version = "py311"
line-length = 100
select = [
  "E",   # pycodestyle
  "F",   # pyflakes
  "I",   # isort
  "UP",  # pyupgrade
  "B",   # flake8-bugbear
  "C4",  # flake8-comprehensions
  "PTH", # flake8-use-pathlib
  "TRY", # tryceratops
  "EM",  # flake8-errmsg
  "PIE", # flake8-pie
  "T20", # flake8-print
]
ignore = ["E501"]
fixable = ["ALL"]
unfixable = []

[tool.ruff.format]
quote-style = "double"
indent-style = "space"

mypy Config

# pyproject.toml
[tool.mypy]
python_version = "3.11"
strict = true
warn_return_any = true
warn_unused_ignores = true
disallow_untyped_defs = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true
check_untyped_defs = true

Go

Tool Purpose
golangci-lint Aggregates 50+ linters
go vet Built-in suspicious code
staticcheck Advanced static analysis
govulncheck Vulnerability scanning

golangci-lint Config

# .golangci.yml
linters:
  enable:
    - errcheck
    - gosec
    - govet
    - ineffassign
    - staticcheck
    - unused
    - misspell
    - nakedret
    - prealloc
    - bodyclose
    - noctx
    - rowserrcheck
    - sqlclosecheck
    - errorlint
    - revive
    - goimports
linters-settings:
  errcheck:
    check-type-assertions: true
    check-blank: true
  gosec:
    excludes: [G104] # errors unhandled
  revive:
    rules:
      - name: exported
        disabled: true
issues:
  exclude-rules:
    - path: _test\.go
      linters: [errcheck, gosec, revive]

Rust

Tool Purpose
clippy Lint (built-in)
rustfmt Format (built-in)
cargo-audit Vulnerability scanning
cargo-deny License, bans, sources policy

Clippy Config

# Cargo.toml
[workspace.lints]
rust_2021_incompatible_closure_captures = "warn"
rust_2021_prefixes_incompatible_syntax = "warn"
rust_2021_prelude_collisions = "warn"

# clippy.toml (optional)
# [clippy]
# pedantic = true
# nursery = true

JVM (Kotlin/Java/Scala)

Tool Language Purpose
detekt Kotlin Linting
ktlint Kotlin Formatting + linting
scalafix Scala Linting + rewrites
scalafmt Scala Formatting
Checkstyle Java Linting
SpotBugs Java Bug patterns
Error Prone Java Compile-time error detection

detekt + ktlint (Kotlin)

// build.gradle.kts
plugins {
    id("io.gitlab.arturbosch.detekt") version "1.23.0"
    id("org.jlleitschuh.gradle.ktlint") version "12.0.0"
}

detekt {
    config = files("config/detekt/detekt.yml")
    baseline = file("config/detekt/baseline.xml")
    reports {
        html.enabled = true
        xml.enabled = true
        sarif.enabled = true
    }
}

ktlint {
    reporters {
        plain {}
        checkstyle.outputFile = file("$buildDir/reports/ktlint/ktlint-checkstyle.xml")
    }
}

Security (SAST)

Open Source SAST

Tool Languages Integration
Semgrep 30+ CLI, CI, IDE, rules registry
CodeQL 10+ GitHub Actions, CLI
SonarQube 25+ Server, CI, IDE
Bearer JS/TS, Python, Ruby, Go CLI, CI
TruffleHog Secrets CLI, CI, pre-commit
GitLeaks Secrets CLI, CI, pre-commit
# .semgrep.yml
rules:
  - id: no-sql-injection
    pattern-either:
      - pattern: execute($X, ...)
      - pattern: query($X, ...)
    message: "Potential SQL injection - use parameterized queries"
    languages: [python, javascript, typescript, go, java]
    severity: ERROR

  - id: hardcoded-secret
    pattern-either:
      - pattern: $X = "sk-..."
      - pattern: $X = "ghp_..."
      - pattern: $X = "xoxb-..."
    message: "Hardcoded secret detected"
    languages: [generic]
    severity: ERROR

  - id: path-traversal
    pattern: open($PATH, ...) where $PATH.contains("..")
    message: "Potential path traversal"
    languages: [python, go, java]
    severity: WARNING
# Run
semgrep ci --config=.semgrep.yml
# Or use registry
semgrep ci --config=p/ci --config=p/secrets --config=p/security-audit

GitHub CodeQL

# .github/workflows/codeql.yml
name: "CodeQL"
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 0 * * 0'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write
    strategy:
      fail-fast: false
      matrix:
        language: [javascript, typescript, python, go, java, rust]
    steps:
      - uses: actions/checkout@v4
      - uses: github/codeql-action/init@v3
        with:
          languages: ${{ matrix.language }}
      - uses: github/codeql-action/analyze@v3

Dependency Scanning

Tool Ecosystem Features
OWASP Dependency Check All (Java, JS, .NET, etc.) CVE, NVD, Sonatype OSS Index
Snyk All CLI, IDE, PR checks, auto-fix
Dependabot GitHub native Auto-PRs, security alerts
Renovate All platforms Flexible, auto-merge, group updates
Trivy Containers, FS, Git Vulns, misconfig, secrets, SBOM
Grype Containers, FS Syft SBOM input, fast
cargo-audit / govulncheck / pip-audit Lang-specific Lockfile analysis

Recommended: Renovate + Trivy

// renovate.json
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["config:recommended"],
  "packageRules": [
    { "matchUpdateType": "minor", "matchCurrentVersion": "!/^0\\./", "automerge": true },
    { "matchUpdateType": "patch", "automerge": true },
    { "matchDatasource": "github-releases", "enabled": false }
  ],
  "schedule": ["every weekend"],
  "timezone": "UTC",
  "prConcurrentLimit": 10
}
# .github/workflows/trivy.yml
name: Trivy Scan
on: [push, pull_request]
jobs:
  fs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Trivy
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: 'fs'
          format: 'sarif'
          output: 'trivy-results.sarif'
      - name: Upload to Code Scanning
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: 'trivy-results.sarif'

Secrets Detection

Pre-commit (Local)

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.18.0
    hooks:
      - id: gitleaks
        args: [--verbose]

  - repo: https://github.com/trufflesecurity/trufflehog
    rev: v3.70.0
    hooks:
      - id: trufflehog
        args: [--no-fail, --json]

  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.5.0
    hooks:
      - id: detect-private-key
      - id: detect-aws-credentials

CI (Blocking)

# .github/workflows/secrets.yml
name: Secrets Scan
on: [push, pull_request]
jobs:
  gitleaks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}

CI/CD Integration

Pre-commit Hooks (All Languages)

# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: biome
        name: Biome (JS/TS)
        entry: biome check --write
        language: system
        types: [javascript, typescript, json]
      - id: ruff
        name: Ruff (Python)
        entry: ruff check --fix
        language: system
        types: [python]
      - id: golangci-lint
        name: golangci-lint (Go)
        entry: golangci-lint run
        language: system
        types: [go]
      - id: cargo-clippy
        name: Clippy (Rust)
        entry: cargo clippy --workspace -- -D warnings
        language: system
        types: [rust]

CI Pipeline Stages

# .github/workflows/ci.yml
jobs:
  static-analysis:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # Language-specific
      - name: Biome
        run: biome ci .
      - name: TypeScript
        run: tsc --noEmit
      - name: Ruff
        run: ruff check .
      - name: mypy
        run: mypy src
      - name: golangci-lint
        run: golangci-lint run ./...
      - name: Clippy
        run: cargo clippy --workspace -- -D warnings
      - name: detekt
        run: ./gradlew detekt

      # Security
      - name: Semgrep
        uses: returntocorp/semgrep-action@v1
      - name: Trivy FS
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: 'fs'
      - name: Secrets
        uses: gitleaks/gitleaks-action@v2

Metrics & Quality Gates

Quality Gate Thresholds

Metric Warning Fail
Code Coverage < 80% < 60%
Duplicated Lines > 3% > 5%
Complexity (cyclomatic) > 15 > 25
Maintainability Index < 70 < 50
Security Hotspots > 0 > 0 (critical)
Vulnerable Dependencies Any Any (high/critical)

SonarQube / SonarCloud

# sonar-project.properties
sonar.projectKey=my-org_my-service
sonar.sources=src
sonar.tests=tests
sonar.exclusions=**/node_modules/**,**/target/**,**/dist/**
sonar.coverage.exclusions=**/*Test*,**/*Spec*
sonar.typescript.lcov.reportPaths=coverage/lcov.info
sonar.python.coverage.reportPaths=coverage.xml
sonar.go.coverage.reportPaths=coverage.out

  • Developer Tools — IDE integration
  • Build Tools — Build pipeline integration
  • Package Management — Dependency scanning
  • Secure Coding — Secure coding practices
  • Supply Chain Security — SBOM, signing
  • CI CD Best Practices — Pipeline gates

Sources: Biome, ESLint, TypeScript, Ruff, mypy, golangci-lint, clippy, detekt, ktlint, Semgrep, CodeQL, Trivy, Renovate, Dependabot, OWASP, GitHub Security, pre-commit

From the Software Engineering research vault · CC BY 4.0 · all notes · raw markdown