Skip to content

sec: fix token leak, shell injection, and add operation logging#28

Merged
tsavo-at-pieces merged 1 commit intomainfrom
fix/audit-security-logging
Feb 24, 2026
Merged

sec: fix token leak, shell injection, and add operation logging#28
tsavo-at-pieces merged 1 commit intomainfrom
fix/audit-security-logging

Conversation

@tsavo-at-pieces
Copy link
Contributor

Summary

  • CRITICAL: Redact tokens/secrets from verbose CLI logging (process_runner.dart) — prevents PATs, bearer tokens, and URL-embedded credentials from appearing in CI logs
  • CRITICAL: Eliminate shell injection vectors in sub_package_utils.dart and release_utils.dart by converting sh -c string-interpolated git commands to safe Process.runSync() with array args
  • BUG: Scope CI auto-format git add -Agit add lib/ in skeleton template to prevent staging unrelated workspace files
  • HIGH: Replace silent catch (_) with Logger.warn() in release_utils.dart and json_schemas.dart so errors are visible in CI logs instead of silently swallowed
  • Enhancement: Add operation logging for git config, git add, and pubspec writes in release commands

Files Changed (7)

File Change
lib/src/cli/utils/process_runner.dart Add _redact() with 5 secret patterns applied to all verbose logging
lib/src/cli/utils/sub_package_utils.dart Convert 2 CiProcessRunner.runSync() shell calls to safe Process.runSync() array args
lib/src/cli/utils/release_utils.dart Convert 2 shell calls to array args, add Logger.warn() for 2 silent catches, Dart-side email deduplication
lib/src/cli/commands/create_release_command.dart Add logging for git config, git add staging, and remote URL setup
lib/src/cli/manage_cicd.dart Add logging for git config and git add staging in legacy release flow
lib/src/triage/utils/json_schemas.dart Add logging to shared writeJson() and readJson() utilities
templates/github/workflows/ci.skeleton.yaml git add -Agit add lib/ in auto-format step

Test plan

  • dart analyze — no issues found
  • dart test — all 113 tests pass
  • Verify CI passes on this PR
  • Deploy to a consumer repo and run manage_cicd update --workflows to confirm regenerated CI uses git add lib/

Closes #25, closes #27, ref #26

🤖 Generated with Claude Code

- Redact tokens/secrets in verbose logging (process_runner.dart)
- Convert shell-interpolated git commands to safe Process.runSync
  array args in sub_package_utils.dart and release_utils.dart,
  eliminating shell injection via config-controlled path/tag values
- Replace silent `catch (_)` with Logger.warn() in release_utils.dart
  and json_schemas.dart so errors are visible in CI logs
- Scope CI auto-format `git add -A` to `git add lib/` in skeleton
  template to prevent staging unrelated files
- Add operation logging for git config, git add, and pubspec writes
  in create_release_command.dart and manage_cicd.dart

Closes #25, closes #27, ref #26

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 24, 2026 20:21
@cursor
Copy link

cursor bot commented Feb 24, 2026

PR Summary

Medium Risk
Touches release automation and git command execution paths; while changes are mostly hardening/logging, they can affect release commit/tag behavior and CI output if assumptions about git output or token formats differ.

Overview
Security hardening for CI/release tooling. Verbose CLI command logging now redacts likely secrets (GitHub PATs, bearer tokens, and credentialed URLs) via CiProcessRunner to prevent token leakage in CI logs.

Shell-injection risk reduction. Release and sub-package utilities replace sh -c/string-interpolated git commands with Process.runSync argument arrays, including Dart-side deduplication of contributor emails and safer commit-count computation.

Operational safety/observability tweaks. Release flows add explicit logging around git identity setup, artifact staging, and authenticated remote configuration; JSON read/write helpers now log failures instead of silently swallowing them; and the CI skeleton’s auto-format step stages only lib/ (not git add -A) to avoid committing unrelated workspace changes.

Written by Cursor Bugbot for commit 6de07e3. Configure here.

Copy link

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

This PR hardens the CLI/release tooling by reducing secret exposure in logs, removing shell-invoked string commands in favor of argument-array process execution, and adding more explicit operation logging for release-related mutations.

Changes:

  • Add token/secret redaction to verbose process command logging (CiProcessRunner).
  • Replace sh -c interpolated git commands with Process.runSync() using array arguments in release/sub-package utilities.
  • Add mutation/operation logging in release flows and scope CI auto-format staging to lib/.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
lib/src/cli/utils/process_runner.dart Adds _redact() and applies it to verbose command logging.
lib/src/cli/utils/sub_package_utils.dart Replaces shell-based git commands with array-arg Process.runSync(); adds warnings for previously silent failures.
lib/src/cli/utils/release_utils.dart Removes shell pipelines; adds warnings for previously silent errors; deduplicates emails in Dart.
lib/src/cli/commands/create_release_command.dart Adds operation logging around git config, staging, and remote URL setup.
lib/src/cli/manage_cicd.dart Adds operation logging around git config and staging in the legacy release path.
lib/src/triage/utils/json_schemas.dart Adds visibility logging for JSON read/write helpers.
templates/github/workflows/ci.skeleton.yaml Narrows auto-format staging from git add -A to git add lib/.
Comments suppressed due to low confidence (2)

lib/src/cli/utils/process_runner.dart:45

  • runSync() redacts the command string, but the verbose stdout logging (Logger.info(' $output')) is not redacted. If a command prints a secret (or prints a URL containing embedded credentials), it can still leak in --verbose mode. Consider applying _redact() to any logged stdout (and potentially stderr) before printing it.
    if (verbose) Logger.info('[CMD] ${_redact(command)}');
    final result = Process.runSync('sh', ['-c', command], workingDirectory: workingDirectory);
    final output = (result.stdout as String).trim();
    if (verbose && output.isNotEmpty) Logger.info('  $output');
    return output;

lib/src/cli/utils/process_runner.dart:55

  • exec() still logs result.stderr unredacted on failure. Some tools (notably git when a remote URL contains credentials) can echo the full URL/token in error messages, which would defeat the redaction added to the command line logging. Apply _redact() to result.stderr (and any other error output) before logging.
    if (verbose) Logger.info('  \$ ${_redact('$executable ${args.join(" ")}')}');
    final result = Process.runSync(executable, args, workingDirectory: cwd);
    if (result.exitCode != 0) {
      Logger.error('  Command failed (exit ${result.exitCode}): ${result.stderr}');
      if (fatal) exit(result.exitCode);
    }

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

Comment on lines +2019 to 2022
_info('Configuring git identity for release commit');
_exec('git', ['config', 'user.name', 'github-actions[bot]'], cwd: repoRoot);
_exec('git', ['config', 'user.email', 'github-actions[bot]@users.noreply.github.com'], cwd: repoRoot);

Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

This release flow uses _exec() (which prints args.join(" ") in verbose mode) elsewhere in the same function to run git remote set-url origin https://x-access-token:...@github.com/.... Without redaction in _exec(), enabling _verbose will still leak the token even though CiProcessRunner now redacts. Add a redaction step to _exec()'s verbose command log and its stderr logging (similar to CiProcessRunner._redact()).

Copilot uses AI. Check for mistakes.
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Comment @cursor review or bugbot run to trigger another review on this PR

final parts = l.split(' ');
if (parts.length < 2) return false;
return seenEmails.add(parts[1]); // returns false if already seen
});
Copy link

Choose a reason for hiding this comment

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

Fallback contributor list now contains duplicate entries

Medium Severity

The conversion from sh -c 'git log ... | sort -u -k2,2' to Process.runSync('git', [...]) with Dart-side deduplication introduces a subtle regression. The Dart dedup only applies to the lazy lines iterable via seenEmails, but the fallback path (when contributors.isEmpty) re-reads gitResult.stdout directly — which is no longer pre-deduplicated by sort -u. A contributor with multiple commits will now appear multiple times in the fallback contributor list.

Fix in Cursor Fix in Web

File(path).writeAsStringSync('${const JsonEncoder.withIndent(' ').convert(data)}\n');
final file = File(path);
final label = file.uri.pathSegments.last;
print('[triage] Writing $label (${data.length} keys)');
Copy link

Choose a reason for hiding this comment

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

Unconditional print in writeJson pollutes stdout output

Low Severity

The writeJson function now has an unconditional print() call on every invocation. This utility is called from at least 6 locations across triage phases. Unlike the error-path logging added to readJson, this fires on every successful write, producing noise on stdout with no way for callers to suppress it. Using raw print() also bypasses any structured logging, and stdout output could interfere with piped or machine-readable CLI output.

Fix in Cursor Fix in Web

@tsavo-at-pieces tsavo-at-pieces merged commit 5ad3279 into main Feb 24, 2026
15 checks passed
@tsavo-at-pieces tsavo-at-pieces deleted the fix/audit-security-logging branch February 24, 2026 20:49
tsavo-at-pieces pushed a commit that referenced this pull request Feb 24, 2026
## Changelog

## [0.14.1] - 2026-02-24

### Added
- Added operation logging for git config, git add, and pubspec writes (#28, fixes #26)

### Changed
- Converted shell-interpolated git commands to safe Process.runSync array args (#28)
- Replaced silent catch blocks with Logger.warn() to ensure errors are visible in CI logs (#28)
- Scoped CI auto-format `git add -A` to `git add lib/` in skeleton template to prevent staging unrelated files (#28)
- Regenerated CI workflow to use correct self-hosted runner names and bumped generated version stamp

### Fixed
- Fixed token and secrets leak in verbose logging by redacting matching patterns (#28)
- Fixed shell injection vulnerabilities by eliminating shell interpolation via config-controlled path and tag values (#28)
- Fixed template bug using `matrix.os` instead of `matrix.platform_id` for artifact naming
- Fixed staging issue related to unrelated files being added during format (#28, fixes #25, #26, #27)

### Security
- Redact GitHub PATs, generic auth tokens, and embedded credentials in URLs from verbose logging output (#28)
- Eliminate shell injection vulnerabilities by migrating git execution to safe Process.runSync with array arguments (#28)

## Files Modified

```
.../audit/v0.14.1/explore/breaking_changes.json    |  4 ++
 .../audit/v0.14.1/explore/commit_analysis.json     | 72 +++++++++++++++++++
 .runtime_ci/audit/v0.14.1/explore/pr_data.json     | 12 ++++
 .runtime_ci/audit/v0.14.1/meta.json                | 82 ++++++++++++++++++++++
 .../v0.14.1/version_analysis/version_bump.json     |  1 +
 .../version_analysis/version_bump_rationale.md     | 22 ++++++
 .../release_notes/v0.14.1/changelog_entry.md       | 20 ++++++
 .../release_notes/v0.14.1/contributors.json        |  5 ++
 .runtime_ci/release_notes/v0.14.1/highlights.md    |  4 ++
 .../release_notes/v0.14.1/linked_issues.json       | 27 +++++++
 .runtime_ci/release_notes/v0.14.1/release_notes.md | 35 +++++++++
 .../release_notes/v0.14.1/release_notes_body.md    | 35 +++++++++
 .runtime_ci/version_bumps/v0.14.1.md               | 22 ++++++
 CHANGELOG.md                                       | 22 ++++++
 README.md                                          |  7 +-
 pubspec.yaml                                       |  2 +-
 16 files changed, 368 insertions(+), 4 deletions(-)
```

## Version Bump Rationale

# Version Bump Rationale

**Decision**: patch
**Reasoning**: The commits since the last release tag (v0.14.0) consist entirely of bug fixes, security patches, and chore updates. There are no breaking changes to public APIs, nor are there any additive new features. According to semantic versioning principles, security patches and bug fixes dictate a patch release.

**Key Changes**:
- **Security**: Prevented token leaks by redacting GitHub PATs and secrets from verbose logs in `CiProcessRunner`.
- **Security**: Eliminated shell injection risks by converting shell-interpolated git commands to safe `Process.runSync` array arguments in release and sub-package utilities.
- **Bug Fix**: Regenerated the CI workflow template to use the correct self-hosted runner names (`runtime-ubuntu-24.04-x64-256gb-64core` and `runtime-windows-2025-x64-256gb-64core`).
- **Bug Fix**: Fixed a bug in the skeleton template for artifact naming (`matrix.os` replaced with `matrix.platform_id`).
- **Bug Fix**: Scoped...

## Contributors

- @tsavo-at-pieces

---
Automated release by CI/CD pipeline (Gemini CLI + GitHub Actions)
Commits since v0.14.0: 2
Generated: 2026-02-24T22:45:39.812077Z
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants