ktg-plugin-marketplace/plugins
Kjell Tore Guttormsen ec4ae268da feat(injection): E16 — homoglyph NFKC fold before every pattern match
Critical-review §4 E16 finding: pre-v7.2.0 homoglyph normalization fired
ONLY for the MEDIUM-advisory "obfuscation present" signal. Pattern
matchers in scanForInjection compared against raw + decoded variants
only — they did NOT compare against a fold-normalized variant. As a
result, "ignоre previous instructions" (Cyrillic о, U+043E) bypassed
the CRITICAL "ignore previous" pattern.

Two coordinated edits:

scanners/lib/string-utils.mjs
- Adds HOMOGLYPH_MAP (frozen) — surgical Cyrillic/Greek → Latin map.
  ~25 entries focused on injection-vocabulary letters
  (a, e, o, c, p, x, y, i, j, s, l, A, E, O, C, P, X, Y, T).
- Adds foldHomoglyphs(s) — pipeline: NFKC → apply HOMOGLYPH_MAP.
  NFKC handles Mathematical Alphanumeric (U+1D400 block), fullwidth
  Latin (U+FF21 block), ligatures, width variants.

Excluded by design from HOMOGLYPH_MAP:
- Latin Extended (æ, ø, å, é, è, ñ, ü, ö, ä, ç, ß, þ, ð) — legitimate
  Norwegian/German/French/Spanish letters. Map them and we false-positive
  on every non-English source file.
- Greek letters not visually overlapping (β, γ, δ, ...)
- Cyrillic letters not visually overlapping (б, г, д, ж, ...)

scanners/lib/injection-patterns.mjs
- scanForInjection now builds a 4-variant set: raw, normalized,
  folded(raw), folded(normalized). Set deduplication skips redundant
  identical variants. Existing dedup-by-label (seenLabels Set) prevents
  double-counts when the same pattern matches in multiple variants.
- foldHomoglyphs added to the imports.

Tests: +27 cases in tests/lib/string-utils-homoglyph.test.mjs:
- 6 Cyrillic → Latin (lowercase, uppercase, multiple substitutions,
  Palochka U+04CF)
- 3 Greek → Latin
- 2 NFKC normalization (Math Bold, Fullwidth)
- 8 preserves-non-confusable (Norwegian æøå, German umlauts, French
  accents, Spanish ñ, emoji, CJK, Arabic/Hebrew)
- 3 edge cases (empty, null/undefined, idempotency)
- 5 scanForInjection integration (Cyrillic ignore, Cyrillic Assistant,
  Norwegian non-trigger, benign "ignore" comment, mixed Cyrillic+Greek)

Test-development found: U+1D5DC is "I" not "A" (test pin caught my
codepoint mistake — fixed during dev).

Suite: 1617 → 1644 (+27). All green.
2026-04-29 14:22:05 +02:00
..
ai-psychosis docs: add AI-generated code disclosure to marketplace and all plugins 2026-04-19 19:27:05 +02:00
config-audit docs(config-audit): straggler sweep — 7 → 8 quality areas in agent + command 2026-04-19 22:58:50 +02:00
graceful-handoff feat(graceful-handoff): initial plugin with /graceful-handoff command 2026-04-19 22:54:10 +02:00
linkedin-thought-leadership docs: add AI-generated code disclosure to marketplace and all plugins 2026-04-19 19:27:05 +02:00
llm-security feat(injection): E16 — homoglyph NFKC fold before every pattern match 2026-04-29 14:22:05 +02:00
ms-ai-architect docs: add AI-generated code disclosure to marketplace and all plugins 2026-04-19 19:27:05 +02:00
okr docs: add AI-generated code disclosure to marketplace and all plugins 2026-04-19 19:27:05 +02:00
ultraplan-local feat(ultraplan-local)!: v2.4.0 — version bump 2026-04-19 21:46:17 +02:00