Skip to content

SafeOutputs: add NFKC + Cyrillic/Greek homoglyph normalization; harden threat_detection Secret Leak check#25458

Merged
pelikhan merged 3 commits intomainfrom
copilot/fix-harden-unicode-text-normalization
Apr 9, 2026
Merged

SafeOutputs: add NFKC + Cyrillic/Greek homoglyph normalization; harden threat_detection Secret Leak check#25458
pelikhan merged 3 commits intomainfrom
copilot/fix-harden-unicode-text-normalization

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 9, 2026

hardenUnicodeText only applied NFC normalization and full-width ASCII mapping, leaving Cyrillic/Greek lookalike characters (e.g. А→A, С→C, Т→T) untouched — allowing homoglyph-substituted secrets to reach the GitHub API verbatim. Separately, the threat_detection.md "Encoded Strings" sub-check was nested under "Malicious Patch", so Base64/hex-encoded content in create_issue-only workflows had no explicit AI detection instruction.

sanitize_content_core.cjshardenUnicodeText

  • Step 6: result.normalize("NFKC") after NFC — decomposes ligatures (fi→fi), superscripts, circled letters, and other compatibility forms.
  • Step 7: HOMOGLYPH_MAP covering 46 Cyrillic and Greek → Latin mappings per Unicode TR#39. HOMOGLYPH_REGEX is pre-built from map keys so only the exact mapped characters are matched.
// Before: Cyrillic-substituted "ATTACK" passed through unchanged
sanitizeContent("\u0410\u0422\u0422\u0410\u0421\u041A") // → "АТТАСК"

// After: normalized to Latin equivalents
sanitizeContent("\u0410\u0422\u0422\u0410\u0421\u041A") // → "ATTACK"

threat_detection.md (both copies)

Expanded the Secret Leak check with explicit sub-bullets:

  • Encoded Representations — flag Base64, hex, ROT13, etc. in any output type (issue bodies, PR descriptions, comments), not only in code patches.
  • Homoglyph Substitution — flag content where Latin characters are replaced with visually identical Cyrillic/Greek lookalikes.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw /tmp/go-build265rev-parse 1/x64/bin/node git rev-�� --show-toplevel /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linutest@example.com /usr/bin/git ithub/workflows/git -buildtags /usr/lib/git-cor--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw sh /usr/local/bin/b--show-toplevel git rev-�� --show-toplevel bash /usr/bin/git --noprofile sh /usr/lib/git-cor--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw git 1/x64/bin/node git rev-�� --show-toplevel 3w/dmTUyvNff8IHlFo22gmC/x6WxTAyILvHXTXsFt6jd /usr/bin/git --show-toplevel git b1e78e3f1659fdcb--show-toplevel git (http block)
  • https://api.github.com/orgs/test-owner/actions/secrets
    • Triggering command: /usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE xq3TT-m/y51iLq3--buildtags env -json 1.5.0/internal/m-ifaceassert x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name if [ -f .github/GOINSECURE git 64/bin/go --show-toplevel git /home/REDACTED/go/prettier go env -json GO111MODULE /node GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name go1.25.8 -c=4 -nolocalimports -importcfg /tmp/go-build2911019868/b399/importcfg -pack /tmp/go-build2911019868/b399/_testmain.go env h ../../../.prettierignore GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha --show-toplevel 64/pkg/tool/linuTest User /usr/bin/git 3830489/b212/_pkgit g-gh/tcTLxKIFRzerev-parse 64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel 64/pkg/tool/linux_amd64/link /usr/bin/git ger.test 8204608/b244/vetrev-parse ortcfg.link git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha --get remote.origin.url /usr/bin/git nitize_content.tgit GO111MODULE k git init�� GOMODCACHE go /usr/bin/git -json GO111MODULE in/node git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel git /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel /opt/hostedtoolcrev-parse /usr/bin/grep git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha --show-toplevel l /usr/bin/git -json GO111MODULE x_amd64/vet git conf�� --get remote.origin.url /opt/hostedtoolcache/node/24.14.1/x64/bin/node -json GO111MODULE x_amd64/vet node (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git rev-�� --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha --show-toplevel git 1/x64/bin/node --show-toplevel git /usr/bin/git git t-ha�� ithub/workflows/approach-validator.md git ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet --show-toplevel infocmp /usr/bin/git ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha guzS/QS0ZOvhayjOXU8RCguzS -trimpath .cfg -p internal/trace/tremote -lang=go1.25 ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel ache/go/1.25.8/x--json /usr/bin/git 3830489/b192/impgit -trimpath ache/go/1.25.8/x--show-toplevel git rev-�� --show-toplevel ache/go/1.25.8/x64/pkg/tool/linuremote1 /usr/bin/git 594850461 -trimpath 64/pkg/tool/linu--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel ps /usr/bin/git t k/gh-aw/gh-aw/pkrev-parse /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git p/TestGetNpmBinPgit x_amd64/cgo /opt/hostedtoolc--show-toplevel git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/git LsRemoteWithRealgit LsRemoteWithRealrev-parse 64/pkg/tool/linu--show-toplevel /usr/bin/git remo�� -v 64/pkg/tool/linuorigin /usr/bin/git y_with_repos=pubgit .cfg 64/pkg/tool/linu--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha --show-toplevel 64/pkg/tool/linuremote /usr/bin/git 3830489/b037/_pkgit om/segmentio/asmrev-parse 64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel 64/pkg/tool/linumyorg /usr/bin/git ithout_min-integgit .cfg 64/pkg/tool/linu--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha uest|push_to_pull_request_branch)" 1/x64/bin/node /usr/bin/git ons-test16104523git x_amd64/asm /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git /tmp/gh-aw-test-git url /usr/bin/git git (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha -json GO111MODULE x_amd64/asm GOINSECURE GOMOD GOMODCACHE x_amd64/asm env -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha -json gset/set.go x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha 1 t/format.go x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/git KnTAukpxv .cfg 64/pkg/tool/linu--show-toplevel /usr/bin/git conf�� --get-regexp ^remote\..*\.gh-resolved$ /usr/bin/git y_with_repos_arrgit .cfg 64/pkg/tool/linu--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha --show-toplevel go /usr/bin/git LsRemoteWithRealgit LsRemoteWithRealrev-parse ules/.bin/node git rev-�� --show-toplevel go /usr/bin/git y_with_repos=pubgit GO111MODULE 64/pkg/tool/linu--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha 69 --log-level /usr/bin/git --log-target journal-or-kmsg /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git -template-expresgit git /usr/bin/git git (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha --show-toplevel 64/pkg/tool/linu-importcfg /usr/bin/git Wwm4jUvL6 .cfg 64/pkg/tool/linu--show-toplevel /usr/bin/git conf�� --get-regexp ^remote\..*\.gh-resolved$ /usr/bin/git 3830489/b048/_pkgit .cfg 64/pkg/tool/linu--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha --show-toplevel go /usr/bin/git '**/*.ts' '**/*.git GO111MODULE 8d519d9/node_mod--show-toplevel git rev-�� --git-dir go /usr/bin/git rdian.md GO111MODULE ache/go/1.25.8/x--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha 1/x64/bin/node git /usr/bin/git --show-toplevel 1/x64/bin/node /usr/bin/git git rev-�� --show-toplevel git /opt/hostedtoolcache/node/24.14.1/x64/bin/node with-tools.md git /usr/bin/git node (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha run --auto /usr/bin/git --detach GO111MODULE x_amd64/asm git rev-�� --show-toplevel r2y2bz4MIdtZ ache/node/24.14.1/x64/bin/node -json GO111MODULE x_amd64/asm git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha origin (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel /opt/hostedtoolcrev-parse /usr/bin/git git rev-�� --show-toplevel git ache/node/24.14.1/x64/bin/node --show-toplevel git-upload-pack /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v0.1.2
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq .object.sha --show-toplevel 64/pkg/tool/linu-buildtags /usr/bin/git 5YxFgGk3C .cfg 64/pkg/tool/linu--show-toplevel /usr/bin/git conf�� --get-regexp ^remote\..*\.gh-resolved$ /usr/bin/git 3830489/b158/_pkgit .cfg 64/pkg/tool/linu--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq .object.sha --show-toplevel go /usr/bin/infocmp -json GO111MODULE x_amd64/compile infocmp -1 xterm-color x_amd64/compile /usr/bin/git .js' --ignore-pagit GO111MODULE 86_64/bash git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq .object.sha 1/x64/bin/node git /usr/bin/git --show-toplevel 1/x64/bin/node /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel ache/node/24.14.rev-parse /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha run --auto /usr/bin/git --detach GO111MODULE x_amd64/compile git -C /tmp/TestGuardPolicyBlockedUsersApprovalLabelsCov1.0.0 remote clusion,workflowName,createdAt,startedAt,updated/tmp/gh-aw-git-clone-2889030818 -json GO111MODULE x_amd64/compile git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha --all-progress-implied --revs /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/compile --thin --delta-base-offrev-parse -q /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/compile -o /tmp/go-build2911019868/b434/_pkg_.a -trimpath /usr/bin/infocmp -p main -lang=go1.25 infocmp (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha --show-toplevel git 1/x64/bin/node --show-toplevel git /usr/bin/git git t-ha�� vaScript3138145416/001/test-frontmatter-with-arrays.md git ache/node/24.14.1/x64/bin/node --show-toplevel node n-dir/node git (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha --objects --stdin ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet --exclude-hiddengit --all --quiet ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha git-receive-packtest-logs/run-3 (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha --show-toplevel git 1/x64/bin/node --show-toplevel /opt/hostedtoolcrev-parse /usr/bin/git git t-ha�� vaScript3138145416/001/test-frontmatter-with-env-template-expressions.md git ache/node/24.14.1/x64/bin/node --show-toplevel node 1/x64/bin/node git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/1/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/1/artifacts --jq .artifacts[].name om/modelcontextp-nolocalimports 64/pkg/tool/linu-importcfg GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linu/home/REDACTED/work/gh-aw/gh-aw/pkg/timeutil/format_test.go env 2887641013 oYmy/n_pwg_VDfKQLamLkoYmy .cfg GOINSECURE a95/uritemplate/rev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-test.v=true (http block)
    • Triggering command: /usr/bin/gh gh run download 1 --dir test-logs/run-1 .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env 3830489/b238/_pkg_.a BHdz/-6z_QJDvZKLbBouUBHdz ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE t/feature/pluralrev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/1/artifacts --jq .artifacts[].name GO111MODULE tions/setup/node_modules/.bin/sh GOINSECURE GOMOD GOMODCACHE go env mpiledOutput3888430879/001 GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12345/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12345/artifacts --jq .artifacts[].name GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE (http block)
    • Triggering command: /usr/bin/gh gh run download 12345 --dir test-logs/run-12345 GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE /execenv GOMODCACHE 64/pkg/tool/linux_amd64/vet env 3548471481 vNkW/MmwpPo_3e3tB-Au8vNkW k GOINSECURE able GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12345/artifacts --jq .artifacts[].name GO111MODULE de_modules/.bin/node GOINSECURE GOMOD GOMODCACHE go 1/x6�� ut2424722498/001 GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12346/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12346/artifacts --jq .artifacts[].name .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE fips140/hmac GOMODCACHE 64/pkg/tool/linutest@example.com env 3830489/b217/_pkg_.a ahb4/lZep-2MiwczJtV1iahb4 ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE g/x/text/transforemote GOMODCACHE ache/go/1.25.8/xorigin (http block)
    • Triggering command: /usr/bin/gh gh run download 12346 --dir test-logs/run-12346 GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE /unix GOMODCACHE 64/pkg/tool/linux_amd64/vet env 3830489/b216/_pkg_.a 7LFx/9x5EhNlMwHDxpQFH7LFx .cfg GOINSECURE g/x/text/secure/rev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-importcfg (http block)
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12346/artifacts --jq .artifacts[].name GO111MODULE tions/node_modules/.bin/node GOINSECURE GOMOD GOMODCACHE go 1/x6�� /001/test-inlined-imports-enabled-with-env-template-expressions-in-body.md GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/2/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/2/artifacts --jq .artifacts[].name GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD (http block)
    • Triggering command: /usr/bin/gh gh run download 2 --dir test-logs/run-2 .cfg 64/pkg/tool/linu-nilfunc GOINSECURE fips140hash ache/go/1.25.8/x--git-dir 64/pkg/tool/linu-tests env 3830489/b239/_pkg_.a _cnJ/4Be12s2Y-OeyZeOx_cnJ ache/go/1.25.8/x64/pkg/tool/linu-nilfunc GOINSECURE t/internal/catmsrev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-tests (http block)
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/2/artifacts --jq .artifacts[].name GO111MODULE tions/node_modules/.bin/sh GOINSECURE GOMOD GOMODCACHE go env mpiledOutput3888430879/001 GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/3/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/3/artifacts --jq .artifacts[].name om/modelcontextp-c=4 64/pkg/tool/linu-nolocalimports GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linu/tmp/go-build2658204608/b444/_testmain.go env 3830489/b234/_pkg_.a GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE (http block)
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/3/artifacts --jq .artifacts[].name GO111MODULE de_modules/.bin/sh GOINSECURE GOMOD GOMODCACHE go env mpiledOutput3888430879/001 GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linuorigin (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/4/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/4/artifacts --jq .artifacts[].name .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD 3830489/b007/sym--show-toplevel 64/pkg/tool/linux_amd64/vet ache�� 2887641013 k-ff/hcoMcb4nJlDk1Ubnk-ff ache/go/1.25.8/x64/pkg/tool/linu-nilfunc GOINSECURE t/internal/tag GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-tests (http block)
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE fips140/edwards2/tmp/js-hash-test-1687601469/test-hash.js GOMODCACHE 64/pkg/tool/linux_amd64/vet env 3830489/b246/_pkg_.a sP8T/7wqnwPqkUSIEmzJIsP8T ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE t/message/catalorev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-test.v=true (http block)
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/4/artifacts --jq .artifacts[].name GO111MODULE ules/.bin/sh GOINSECURE GOMOD GOMODCACHE go env */*.ts' '**/*.json' --ignore-path ../../../.pret.prettierignore GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linuTest User (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/5/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/5/artifacts --jq .artifacts[].name om/yosida95/uritemplate/v3@v3.0.2/compile.go 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env 2887641013 GO111MODULE .cfg GOINSECURE contextprotocol/rev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-trimpath (http block)
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 .cfg 64/pkg/tool/linu-importcfg GOINSECURE fips140/nistec/frev-parse ache/go/1.25.8/x--show-toplevel ylQP4Z8/vCNYLdc7D8RXanEmFBss env e-analyzer.md mW0N/BDDpIqgj5QBgNtEbmW0N 64/pkg/tool/linux_amd64/vet GOINSECURE t/internal GOMODCACHE 64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/5/artifacts --jq .artifacts[].name GO111MODULE bin/sh GOINSECURE GOMOD GOMODCACHE go env 6763/001/stability-test.md GO111MODULE 64/pkg/tool/linux_amd64/link GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linutest@example.com (http block)
  • https://api.github.com/repos/github/gh-aw/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json 2/compile.go x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 100 GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 6 3830489/b078/ GOMODCACHE 64/pkg/tool/linuremote1 env 3830489/b193/_pkg_.a GO111MODULE x_amd64/compile GOINSECURE GOMOD 3830489/b078/sym--show-toplevel x_amd64/compile (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v0.47.4
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq .object.sha --show-toplevel ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet /usr/bin/git /tmp/go-build296git -trimpath 8204608/b170/vet--show-toplevel git rev-�� --show-toplevel /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linu-buildtags /usr/bin/git architecture-guagit -buildtags eutil.test git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq .object.sha 64/pkg/tool/linux_amd64/link /usr/bin/git eutil.test GO111MODULE ortcfg.link /usr/bin/git remo�� -v Qk99d9TgbambanbLremote.origin.url /usr/bin/git -json GO111MODULE g_.a git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq .object.sha --show-toplevel git ache/node/24.14.1/x64/bin/node --show-toplevel git /usr/bin/git ache/node/24.14.1/x64/bin/node 6583�� ease.assets[0].id git /usr/bin/git --show-toplevel git /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha l.go l_test.go ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE fips140/ecdsa GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linuremote.origin.url (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha on' --ignore-path ../../../.prettierignore GO111MODULE x_amd64/link GOINSECURE GOMOD GOMODCACHE x_amd64/link env 35/001 GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha ]*:[[:space:]]*"(create_pull_request|push_to_pull_request_branch)" git /usr/bin/git --show-toplevel go /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel go /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq .object.sha -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env Gitmaster_branchremote.origin.url Gitmaster_branch1582038837/001' es/.bin/sh GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env json' --ignore-path ../../../.pr**/*.json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v2.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha go1.25.8 -c=4 -nolocalimports -importcfg /tmp/go-build2658204608/b422/importcfg -pack /tmp/go-build2658204608/b422/_testmain.go env g_.a GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env 020956129/001 020956129/002/work 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v3.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq .object.sha -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env g_.a GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env lGitbranch_with_remote.origin.url lGitbranch_with_hyphen3087391445/001' 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha b/workflows .cfg ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/xtest@example.com (http block)
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha on' --ignore-path ../../../.pret.prettierignore GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE 7sC7-S6/nhA1mfGEh3U39fesu0-m env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha /repos/actions/checkout/git/ref/tags/v6 --jq /usr/bin/git --show-toplevel go /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel go /usr/bin/git git (http block)
  • https://api.github.com/repos/nonexistent/repo/actions/runs/12345
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion GOINSECURE ntio/encoding/asrev-parse GOMODCACHE 64/pkg/tool/linux_amd64/vet env 0CEW/ctpVeCUT66SDIATz0CEW GO111MODULE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu--jq (http block)
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion GOINSECURE GOMOD GOMODCACHE go tion�� -json GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD (http block)
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion **/*.json --ignore-path ../../../.pretti--show-toplevel LbhN01as79Y-_/zuYXX5TmK1qVPJGpBn5O/3ZF0gOpIOEXsTrev-parse -c ry=1 (http block)
  • https://api.github.com/repos/owner/repo/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json ag.go x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json gset/set.go x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go gh-aw ./cmd/gh-aw /home/REDACTED/.lo"prettier" --check '**/*.cjs' '**/*.ts' '**/*.json' --ignore-path ../../../.pret.prettierignore go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/owner/repo/contents/file.md
    • Triggering command: /tmp/go-build2658204608/b397/cli.test /tmp/go-build2658204608/b397/cli.test -test.testlogfile=/tmp/go-build2658204608/b397/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
    • Triggering command: /tmp/go-build2328585355/b397/cli.test /tmp/go-build2328585355/b397/cli.test -test.testlogfile=/tmp/go-build2328585355/b397/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true tierignore git /usr/bin/git /opt/hostedtoolcGO111MODULE -V=f�� /usr/bin/git git 64/bin/go ignore-path ../.sh git /home/REDACTED/wor"prettier" --check '**/*.cjs' '**/*.ts' '**/*.json' --ignore-path ../../../.prettierignore go (http block)
    • Triggering command: /tmp/go-build2911019868/b224/cli.test /tmp/go-build2911019868/b224/cli.test -test.testlogfile=/tmp/go-build2911019868/b224/testlog.txt -test.paniconexit0 -test.timeout=10m0s -c if [ -f .github/GOINSECURE go 64/bin/go -json GO111MODULE ache/uv/0.11.5/xprettier go env -json GO111MODULE /prettier GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/test-owner/test-repo/actions/secrets
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name -json 5 x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name /usr/bin/git git 64/bin/go --ignore-path ..node git /opt/hostedtoolcprettier go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name 64686286/001' 64686286/001' 64/bin/go GOINSECURE GOMOD GOMODCACHE go env h ../../../.prettierignore GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI and others added 2 commits April 9, 2026 12:33
…map; expand threat_detection.md Secret Leak check

- Add NFKC normalization (Step 6) in hardenUnicodeText to handle ligatures,
  compatibility characters, and other Unicode compatibility equivalents.
- Add homoglyph confusables map (HOMOGLYPH_MAP, Step 7) covering common
  Cyrillic and Greek characters that are visually identical to Latin letters,
  based on Unicode TR#39 confusables table. This prevents bypass of text
  filters using homoglyph substitution.
- Expand the 'Secret Leak' check in both copies of threat_detection.md to
  explicitly instruct the detection model to flag Base64/hex/ROT13-encoded
  representations of secrets and homoglyph-substituted content, regardless
  of whether a code patch is present.
- Add 14 new tests in sanitize_content.test.cjs covering Cyrillic and Greek
  homoglyph normalization; update one pre-existing test whose expectation
  changed due to NFKC composition.

Fixes #<issue>

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/b71f9897-6b05-4a51-8304-cfc79022f81e

Co-authored-by: szabta89 <1330202+szabta89@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix homoglyph normalization in hardenUnicodeText SafeOutputs: add NFKC + Cyrillic/Greek homoglyph normalization; harden threat_detection Secret Leak check Apr 9, 2026
Copilot AI requested a review from szabta89 April 9, 2026 12:52
@pelikhan pelikhan marked this pull request as ready for review April 9, 2026 13:29
Copilot AI review requested due to automatic review settings April 9, 2026 13:29
@pelikhan pelikhan merged commit 9aef501 into main Apr 9, 2026
202 of 214 checks passed
@pelikhan pelikhan deleted the copilot/fix-harden-unicode-text-normalization branch April 9, 2026 13:32
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Strengthens output sanitization and threat-detection guidance to better catch/neutralize Unicode-based evasions (compatibility forms + Cyrillic/Greek homoglyphs) and to ensure “Secret Leak” detection explicitly covers encoded/obfuscated secrets across all output types.

Changes:

  • Add NFKC normalization and Cyrillic/Greek→Latin homoglyph mapping to hardenUnicodeText.
  • Expand “Secret Leak” prompt instructions to explicitly include encoded strings and homoglyph substitution (in both prompt copies).
  • Update/extend sanitization tests to cover NFKC composition and homoglyph normalization.
Show a summary per file
File Description
actions/setup/js/sanitize_content_core.cjs Adds NFKC normalization and homoglyph mapping within hardenUnicodeText.
actions/setup/js/sanitize_content.test.cjs Adds assertions covering NFKC behavior and Cyrillic/Greek homoglyph normalization.
pkg/workflow/prompts/threat_detection.md Expands “Secret Leak” check with encoded + homoglyph-specific guidance.
actions/setup/md/threat_detection.md Mirrors the same “Secret Leak” prompt guidance updates.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 4/4 changed files
  • Comments generated: 2

Comment on lines 1029 to +1062
// Step 1: Normalize Unicode to canonical composition (NFC)
// This ensures consistent character representation across different encodings
result = result.normalize("NFC");

// Step 2: Decode HTML entities to prevent @mention bypass
// This MUST happen early, before any other processing, to ensure entities
// are converted to their actual characters for proper sanitization
result = decodeHtmlEntities(result);

// Step 3: Strip invisible zero-width characters that can hide content
// These include: zero-width space, zero-width non-joiner, zero-width joiner,
// left-to-right mark (U+200E), right-to-left mark (U+200F),
// soft hyphen (U+00AD), combining grapheme joiner (U+034F),
// word joiner, and byte order mark
result = result.replace(/[\u00AD\u034F\u200B\u200C\u200D\u200E\u200F\u2060\uFEFF]/g, "");

// Step 4: Remove bidirectional text override controls
// These can be used to reverse text direction and create visual spoofs
result = result.replace(/[\u202A\u202B\u202C\u202D\u202E\u2066\u2067\u2068\u2069]/g, "");

// Step 5: Convert full-width ASCII characters to standard ASCII
// Full-width characters (U+FF01-FF5E) can be used to bypass filters
result = result.replace(/[\uFF01-\uFF5E]/g, char => {
const code = char.charCodeAt(0);
// Map full-width to half-width by subtracting offset
const standardCode = code - 0xfee0;
return String.fromCharCode(standardCode);
});

// Step 6: Apply NFKC normalization to handle compatibility characters
// NFKC decomposes ligatures (fi→fi), superscripts, circled letters, etc.
// This must come after full-width conversion to avoid double-processing
result = result.normalize("NFKC");

Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hardenUnicodeText now performs normalize("NFC") (step 1) and later normalize("NFKC") (step 6). Since NFKC already includes canonical composition (i.e., it yields an NFC-normalized result), the earlier NFC pass is redundant and adds extra per-call cost on potentially large bodies. Consider removing the initial NFC call (or replacing step 6 with NFC only if you intentionally want to avoid compatibility folding).

Copilot uses AI. Check for mistakes.
Comment on lines +1063 to +1067
// Step 7: Map Cyrillic and Greek homoglyph characters to their Latin equivalents
// These characters are visually indistinguishable from Latin letters and are used
// to bypass text filters while appearing to contain only ASCII-like content.
// Based on Unicode TR#39 confusables (https://www.unicode.org/reports/tr39/).
result = result.replace(HOMOGLYPH_REGEX, char => HOMOGLYPH_MAP[char]);
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new homoglyph replacement (step 7) transliterates Cyrillic/Greek characters into Latin equivalents in the final output. This is a behavior-changing rewrite that will also affect legitimate non-Latin text (and any code blocks / identifiers containing these characters), not just homoglyph-substituted secrets. Consider limiting this to a detection-only path (e.g., use a folded copy for secret scanning) or gating it behind an option/config so normal content isn’t unintentionally altered.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

Hey @Copilot 👋 — great work on this security hardening PR! The homoglyph normalization fix closes a real gap: before this change, Cyrillic/Greek lookalike characters in secrets could sail straight through hardenUnicodeText undetected. The two-pronged approach (NFKC normalization + explicit HOMOGLYPH_MAP via Unicode TR#39) is well-targeted, and the threat_detection.md update closes the companion gap on the AI-detection side.

This PR looks well-structured and ready for maintainer review. ✅

Generated by Contribution Check · ● 2.2M ·

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

4 participants