Skip to content

fix: harden URL and path construction across helper modules#133

Open
NeekChaw wants to merge 1 commit intogoogleworkspace:mainfrom
NeekChaw:fix/harden-url-path-construction
Open

fix: harden URL and path construction across helper modules#133
NeekChaw wants to merge 1 commit intogoogleworkspace:mainfrom
NeekChaw:fix/harden-url-path-construction

Conversation

@NeekChaw
Copy link

@NeekChaw NeekChaw commented Mar 5, 2026

Closes #87

Summary

Audit of helper modules found several places where user-provided values are interpolated into URLs or file paths via format! without going through encode_path_segment() or validate_resource_name().

Changes

src/discovery.rs

  • Add validate_discovery_id() — only allows [a-zA-Z0-9._-] for service names/versions. Prevents path traversal in the local cache file path and injection in Discovery Document endpoint URLs.
  • Validate service and version at entry to fetch_discovery_document().
  • Move version query parameter in the alt-URL code path to reqwest .query() instead of string interpolation.

src/helpers/modelarmor.rs

  • Call validate_resource_name() on --template in handle_sanitize() and build_sanitize_request_data() before building URLs.
  • Validate --project, --location, --template-id in parse_create_template_args().
  • Use encode_path_segment() for templateId in build_create_template_url().

src/helpers/gmail/watch.rs

  • Extract message-URL building to build_message_url() using encode_path_segment() on the message ID.
  • Switch msg_format to reqwest .query() builder instead of string interpolation.

Testing

Added 15 new unit tests (happy-path + error-path) covering each fix:

  • 6 tests for validate_discovery_id in discovery.rs
  • 5 tests for resource name/template validation in modelarmor.rs
  • 4 tests for build_message_url in watch.rs

@NeekChaw NeekChaw requested a review from jpoehnelt as a code owner March 5, 2026 07:15
@changeset-bot
Copy link

changeset-bot bot commented Mar 5, 2026

🦋 Changeset detected

Latest commit: 4ecdc98

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

@gemini-code-assist
Copy link
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@google-cla
Copy link

google-cla bot commented Mar 5, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@NeekChaw
Copy link
Author

NeekChaw commented Mar 5, 2026

@googlebot I signed it!

@jpoehnelt jpoehnelt added area: http cla: no This human has *not* signed the Contributor License Agreement. complexity: medium Moderate change, some review needed labels Mar 5, 2026
@jpoehnelt
Copy link
Member

please fix the conflicts

@jpoehnelt
Copy link
Member

/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 does a great job of hardening URL and path construction across several modules by introducing validation and proper encoding for user-provided inputs. The changes significantly improve the security posture of the application against path traversal and injection attacks. I've found one area in the new validation logic in discovery.rs where the check can be made more robust to cover additional edge cases for invalid identifiers. My specific feedback is in the comment below.

@NeekChaw NeekChaw force-pushed the fix/harden-url-path-construction branch from ee3609f to 8bf9b14 Compare March 6, 2026 01:03
@googleworkspace-bot googleworkspace-bot added area: discovery area: core Core CLI parsing, commands, error handling, utilities and removed area: http labels Mar 6, 2026
@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 introduces important security hardening by validating user-provided values used in URL and file path construction, which helps prevent path traversal and injection attacks. The changes are well-implemented across the discovery, gmail, and modelarmor modules. I've identified a couple of instances of redundant validation in src/helpers/modelarmor.rs that should be removed to improve code clarity and maintainability.

@NeekChaw NeekChaw force-pushed the fix/harden-url-path-construction branch from 8bf9b14 to 4ecdc98 Compare March 6, 2026 02:06
…oogleworkspace#87)

Audit of helper modules found several places where user-provided values are
interpolated into URLs or file paths via format! without going through
encode_path_segment() or validate_resource_name().

Changes:

src/discovery.rs
- Add validate_discovery_id() that allows only [a-zA-Z0-9._-] for service
  names and version strings, preventing path traversal in the cache directory
  and injection in Discovery Document endpoint URLs.
- Validate service and version at the entry point of fetch_discovery_document.
- Move the version query parameter in the alt-URL code path to reqwest .query().

src/helpers/modelarmor.rs
- Call validate_resource_name() on --template before embedding it in URLs
  in handle_sanitize() and build_sanitize_request_data().
- Validate --project, --location, --template-id in parse_create_template_args().
- Use encode_path_segment() for templateId in build_create_template_url().

src/helpers/gmail/watch.rs
- Extract message-URL building to build_message_url() using encode_path_segment
  on the message ID (prevents path/query injection from API-supplied IDs).
- Switch msg_format to reqwest .query() builder instead of string interpolation.

Adds 15 new unit tests (happy-path + error-path) for each fix.
@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 does a great job of hardening URL and path construction across several modules, which is a significant security improvement. The introduction of validation for user-provided values and the use of safer URL-building APIs effectively reduce the risk of injection and path traversal vulnerabilities. However, I've identified a critical issue in src/helpers/modelarmor.rs where project and location IDs are being over-encoded, which will likely cause API calls to fail. Please see my detailed comment.

Comment on lines 377 to 379
format!(
"{base}/{parent}/templates?templateId={}",
crate::validate::encode_path_segment(&config.template_id)
"{base}/{parent}/templates?templateId={template_id_encoded}"
)
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

The parent variable used in this format! macro is constructed on line 373 using project and location values that have been overly-encoded on lines 371-372. Using encode_path_segment on them incorrectly escapes valid characters like hyphens (e.g., us-central1 becomes us%2Dcentral1), which will likely cause the API call to fail. Since these values are validated in parse_create_template_args, they should be safe to be used directly in the URL path. Please remove the encode_path_segment calls for project and location.

@jpoehnelt
Copy link
Member

can you check the latest pr comment

@codecov
Copy link

codecov bot commented Mar 7, 2026

Codecov Report

❌ Patch coverage is 91.89189% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.86%. Comparing base (f07dd2b) to head (4ecdc98).
⚠️ Report is 9 commits behind head on main.

Files with missing lines Patch % Lines
src/validate.rs 40.00% 3 Missing ⚠️
src/discovery.rs 0.00% 2 Missing ⚠️
src/helpers/gmail/watch.rs 95.65% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #133      +/-   ##
==========================================
+ Coverage   57.69%   57.86%   +0.16%     
==========================================
  Files          38       38              
  Lines       14328    14392      +64     
==========================================
+ Hits         8267     8328      +61     
- Misses       6061     6064       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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 area: discovery cla: no This human has *not* signed the Contributor License Agreement. complexity: medium Moderate change, some review needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Harden URL and path construction across helper modules

3 participants