Skip to content

fix(validate): reject dangerous Unicode characters in input validation#484

Open
abhiram304 wants to merge 3 commits intogoogleworkspace:mainfrom
abhiram304:fix/validate-unicode-security
Open

fix(validate): reject dangerous Unicode characters in input validation#484
abhiram304 wants to merge 3 commits intogoogleworkspace:mainfrom
abhiram304:fix/validate-unicode-security

Conversation

@abhiram304
Copy link
Contributor

Summary

  • reject_control_chars() used a byte-level ASCII check (b < 0x20 || b == 0x7F) that silently passed all multi-byte Unicode — zero-width chars, bidi overrides, and Unicode line/paragraph separators could slip through unchecked
  • validate_resource_name() used c.is_control() (Unicode "Cc" only), missing "Cf" (format) and "Zl"/"Zp" (separator) categories — the same dangerous chars
  • Adds a REJECTED_UNICODE_CHARS constant covering U+200B–U+200D, U+FEFF, U+202A–U+202E, U+2028–U+2029, and U+2066–U+2069; both validators now check against it

Test plan

  • cargo test validate — all 20 new Unicode tests pass alongside existing suite
  • validate_resource_name("foo\u{200B}bar") returns Err
  • validate_resource_name("foo\u{202E}bar") returns Err (RTL override)
  • validate_resource_name("日本語") still returns Ok (normal Unicode unaffected)
  • validate_safe_output_dir("foo\u{2028}bar") returns Err

🤖 Generated with Claude Code

@changeset-bot
Copy link

changeset-bot bot commented Mar 14, 2026

🦋 Changeset detected

Latest commit: f6b959b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@googleworkspace/cli Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@googleworkspace-bot googleworkspace-bot added the area: core Core CLI parsing, commands, error handling, utilities label Mar 14, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the security and robustness of input validation by extending checks to cover a broader range of dangerous Unicode characters. It closes potential loopholes where characters like zero-width spaces or bidirectional overrides could bypass existing ASCII-only or limited Unicode control character checks, thereby preventing potential injection attacks or misinterpretations in resource names and other inputs.

Highlights

  • Enhanced Unicode Validation: The reject_control_chars() function was updated to correctly identify and reject dangerous multi-byte Unicode characters, addressing a previous oversight where only ASCII control characters were checked.
  • Expanded Resource Name Validation: The validate_resource_name() function now includes checks for Unicode "Cf" (format), "Zl" (line separator), and "Zp" (paragraph separator) categories, which were previously missed.
  • Introduction of REJECTED_UNICODE_CHARS: A new constant, REJECTED_UNICODE_CHARS, was introduced to centralize the list of dangerous Unicode characters, including zero-width characters, bidirectional overrides, and line/paragraph separators, which are now checked by both reject_control_chars() and validate_resource_name().
Changelog
  • .changeset/validate-unicode-security.md
    • Added a new changeset entry detailing the Unicode validation improvements.
  • src/validate.rs
    • Introduced REJECTED_UNICODE_CHARS constant for dangerous Unicode characters.
    • Modified reject_control_chars to check for REJECTED_UNICODE_CHARS.
    • Modified validate_resource_name to check for REJECTED_UNICODE_CHARS.
    • Added extensive unit tests for Unicode character rejection in validation functions.
Activity
  • The pull request was generated using Claude Code.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Generative AI Prohibited Use Policy, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively addresses a security vulnerability by extending input validation to reject dangerous Unicode characters that were previously missed. The approach of using a shared constant for the rejected characters is sound. My review focuses on improving the performance and structure of this new validation logic, which is crucial for security-sensitive code, by suggesting a more efficient implementation using Rust's matches! macro. The accompanying tests are thorough and provide good coverage for the new checks.

Extend reject_control_chars() and validate_resource_name() to reject
zero-width chars (U+200B, U+200C, U+200D, U+FEFF), bidi overrides
(U+202A-U+202E), Unicode line/paragraph separators (U+2028, U+2029),
and directional isolates (U+2066-U+2069). These multi-byte codepoints
were silently passing the previous ASCII-range byte check, creating
a potential injection vector when the CLI is driven by LLM agents.
Adds 20 new tests covering all rejected categories plus documented
intentional pass-throughs (homoglyphs, overlong names).
… using matches!

Switch from a REJECTED_UNICODE_CHARS &[char] constant + .contains() (O(M)
linear scan per character) to an is_rejected_unicode(c: char) -> bool helper
that uses the matches! macro with char ranges. This gives O(1) per character
and reads more clearly at call sites via .any(is_rejected_unicode).
@abhiram304 abhiram304 force-pushed the fix/validate-unicode-security branch from 11f4e15 to 100d0ea Compare March 14, 2026 05:40
@googleworkspace-bot
Copy link
Collaborator

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request enhances input validation by rejecting a range of dangerous Unicode characters, which is a great security improvement. My review identifies a recurring performance issue where the new checks introduce a second iteration over the input string. I've recommended combining these checks into a single pass for improved performance and efficiency.

Address review feedback: replace the two-iteration approach (one byte
scan + one char scan) in reject_control_chars with a single char loop,
and merge the separate is_control / is_rejected_unicode guards in
validate_resource_name into one any() call. Avoids iterating the input
string twice, closing the O(N*M) concern raised by the reviewer.
@googleworkspace-bot
Copy link
Collaborator

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request enhances input validation by rejecting a range of dangerous Unicode characters, such as zero-width spaces, bidirectional overrides, and line/paragraph separators. The changes correctly move from a byte-based check to a character-based one to handle multi-byte Unicode characters properly. The new validation is applied to both directory paths and resource names. The addition of comprehensive tests for the new Unicode checks is also a great improvement. I have one suggestion to improve code clarity in one of the validation functions.

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

Labels

area: core Core CLI parsing, commands, error handling, utilities

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants