Security & Privacy — Ninja-Shield v2

PON_DI_RULEZ compliance

  • No persistent host identities: counting happens on the full address inside
    the process (so hit counts stay exact), but every address is masked to its
    /24 network before it leaves the tool. No emitted artifact — JSON aggregate,
    MIDI event, or embedded dashboard data — carries a host identity. See
    mask_ip() in bin/access2ninja.py and bin/crumbmidi_bridge.py.
  • /24 granularity on purpose: the network prefix is kept so geo and threat
    context survive — the same granularity top_nets already uses. A host is a
    person; a network is a neighbourhood.
  • No tracking: the dashboard makes no outbound calls unless you explicitly provide a ?log= URL
  • Offline-first: all assets (CSS, fonts, JS) are local; CDN fallbacks are optional and fail-safe

Note on fixtures: samples/*_access.log are raw nginx logs kept as parser
fixtures and do contain full client IPs (mostly public scanners plus the
node's own address). They are inputs, never served by the dashboard. The
GEO_MAP in access2ninja.py likewise lists /24-level prefixes only.
If a fully IP-free repo is wanted, mask the fixtures too — separate step.

ninjad hardening

  • Binds to 0.0.0.0 by default — restrict via firewall if exposed to WAN
  • No authentication: treat as read-only public telemetry
  • Set NINJA_VERBOSE=1 only for debugging; request logging is off by default
  • Log file path is read from NINJA_LOG environment — no path traversal possible

access2ninja.py / crumbmidi_bridge.py

  • Pure Python stdlib, no third-party dependencies
  • No network calls, no file writes (except stdout)
  • Regex patterns are pre-compiled and bounded; no ReDoS surface

Dashboard

  • fetch() is only used for the explicit ?log= parameter
  • No cookies, no localStorage, no session state
  • Terminal input is simulated client-side only; no real shell commands are executed

Report issues via the Crumbforest dojo channels.