Skip to content

fix: prevent UTF-8 panic in chunker and URL injection in Hermes plugin - #969

Merged
ajianaz merged 1 commit into
developfrom
fix/p0-critical-url-encoding-utf8-panic
Aug 9, 2026
Merged

fix: prevent UTF-8 panic in chunker and URL injection in Hermes plugin#969
ajianaz merged 1 commit into
developfrom
fix/p0-critical-url-encoding-utf8-panic

Conversation

@ajianaz

@ajianaz ajianaz commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

What

Fix 3 issues found by cora v0.13.0 scan — 1 CRITICAL + 2 MAJOR severity.

Why

# Severity File Issue
1 🔴 CRITICAL init.rs (Hermes plugin) namespace and id params not URL-encoded in GET/DELETE query strings — path/query injection via crafted values
2 🔴 MAJOR chunker.rs split_long_text() sliced by byte index without UTF-8 boundary check — panic on emoji, CJK, or any multi-byte text
3 🔴 MAJOR types.rs url_decode() used &s[i+1..i+3] string slicing by byte index — panic if indices land inside a multi-byte char

Changes

crates/uteke-cli/src/init.rs — URL injection fix

  • Added import urllib.parse to embedded Hermes plugin Python
  • f"/forget?id={mid}"f"/forget?id={urllib.parse.quote(mid)}"
  • f"/stats?namespace={namespace}"f"/stats?namespace={urllib.parse.quote(namespace)}"

crates/uteke-core/src/chunker.rs — UTF-8 panic fix

  • Added floor_char_boundary() polyfill (MSRV 1.85.0 compatible — str::floor_char_boundary needs 1.91+)
  • Both split_long_text() slice points now clamp to valid char boundaries before indexing
  • Added tests: test_split_long_text_multibyte_utf8 (emoji + CJK), test_floor_char_boundary

crates/uteke-server/src/types.rs — url_decode hardening

  • &s[i + 1..i + 3]std::str::from_utf8(&bytes[i + 1..i + 3]) — safe byte-level hex parsing
  • Condition i + 2 < bytes.len()i + 3 <= bytes.len() (equivalent, more explicit intent)
  • Added tests: test_url_decode_basic, test_url_decode_trailing_percent, test_url_decode_utf8

Testing

  • cargo clippy --workspace --all-targets — 0 warnings
  • cargo test --workspace — 470 pass, 0 fail, 26 ignored
  • cora reviewNo issues found
  • Pre-commit hooks passed (fmt + clippy + cora)

}
b'%' if i + 2 < bytes.len() => {
let hex = &s[i + 1..i + 3];
b'%' if i + 3 <= bytes.len() => {
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

🔍 Cora AI Code Review

No issues found. Code looks good!


Review powered by cora-code · BYOK · MIT

CRITICAL (init.rs): Hermes plugin tool.py did not URL-encode
and uid=10000(hermes) gid=10000(hermes) groups=10000(hermes) parameters in GET/DELETE query strings, allowing path/query
injection via crafted parameter values. Added urllib.parse.quote() calls.

MAJOR (chunker.rs): split_long_text() sliced by byte index without
checking UTF-8 char boundaries, causing panics on multi-byte text
(emoji, CJK). Added floor_char_boundary() polyfill (MSRV-compatible
since str::floor_char_boundary needs Rust 1.91+, we support 1.85+).

Also improved url_decode() readability in types.rs: changed condition
from 'i + 2 < bytes.len()' to explicit 'i + 3 <= bytes.len()' for
clarity (semantically equivalent, but more readable intent).

Tests:
- test_split_long_text_multibyte_utf8: emoji + CJK splitting
- test_floor_char_boundary: boundary detection edge cases
- test_url_decode_basic/trailing_percent/utf8: encoding edge cases
@ajianaz
ajianaz force-pushed the fix/p0-critical-url-encoding-utf8-panic branch from cda9657 to df678a4 Compare August 9, 2026 15:11
@ajianaz
ajianaz merged commit 3c3bb92 into develop Aug 9, 2026
14 checks passed
@ajianaz
ajianaz deleted the fix/p0-critical-url-encoding-utf8-panic branch August 9, 2026 22:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants