Skip to content

feat: onboarding flutter-action - #1

Merged
Raj-StepSecurity merged 3 commits into
mainfrom
release
Oct 7, 2026
Merged

Raj-StepSecurity merged 3 commits into
mainfrom
release

Conversation

@Raj-StepSecurity

Copy link
Copy Markdown
Collaborator

No description provided.

@Raj-StepSecurity Raj-StepSecurity added the review-required Request Claude AI code review on the PR label Oct 7, 2026
Comment thread setup.sh
Comment thread setup.sh
Comment thread action.yaml
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown

PR Review

Action Type

Composite action — defined in action.yaml using runs: composite, orchestrating a shell script (setup.sh) across Linux, macOS, and Windows runners.


✅ Passed Checks

  • LICENSE present with copyright for both the original author (Alif Rachmawadi / subosito) and StepSecurity.
  • action.yaml present with author: 'step-security'.
  • SECURITY.md present with StepSecurity contact email.
  • FUNDING.yml is not present.
  • .github/workflows/auto_cherry_pick.yml is present.
  • .github/workflows/actions_release.yml is present.
  • renovate.json is not present.
  • PULL_REQUEST.md is not present.
  • ISSUE_TEMPLATE folder is not present.
  • CHANGELOG.md is not present.
  • .vscode folder is not present.
  • README.md banner — StepSecurity maintained action banner is present at the top of the README.
  • README version tags — all examples use step-security/flutter-action@v2 (major version only, no full semver tags).
  • Composite action pinning — external non-GitHub actions (step-security/action-shellcheck@v2, step-security/reusable-workflows/...@v1) are pinned to major version tags.
  • upstream variable in auto_cherry_pick.yml — correctly set to subosito/flutter-action (original-owner: "subosito", repo-name: "flutter-action").

❌ Failed Checks

  • Subscription check is missing — There is no call to https://agent.api.stepsecurity.io/v1/github/$GITHUB_REPOSITORY/actions/maintained-actions-subscription anywhere in setup.sh or action.yaml. This check must be added with the upstream value set to subosito/flutter-action.

⚠️ Warnings

  • curl missing --fail flag (setup.sh line 57) — HTTP error responses (4xx/5xx) are silently written to the archive file rather than aborting. See inline comment.
  • Unquoted CHANNEL output (action.yaml line 156) — The channel value is interpolated into the shell run: block without surrounding quotes. While the value originates from the Flutter release manifest (safe in practice), it should be quoted consistently with the other outputs. See inline comment.
  • actions/cache@v5 is used — correctly pinned to a major version. No issue here, but worth confirming compatibility with self-hosted runners (documented in README).

🔒 Security Findings

  1. [Critical] Checksum mismatch does not abort (setup.sh lines 64–68) — When the downloaded archive's SHA256 does not match the manifest value, the script prints only a Warning: message and continues to extract and install the potentially tampered archive. This completely defeats the integrity check and could allow a supply-chain attack. The script must exit 1 on mismatch. See inline comment.

  2. [Moderate] curl without --fail (setup.sh line 57) — If the CDN returns an HTTP error code, curl exits 0 and writes the error body to disk. Subsequent extraction will fail with a confusing error rather than a clear network/download failure. Add --fail to the curl invocation.

  3. [Low] Unquoted shell interpolation (action.yaml line 156) — ${{ steps.flutter-action.outputs.CHANNEL }} is unquoted in a run: block. Should be wrapped in single quotes like the other outputs on the same step.


Summary

The onboarding PR is largely well-structured — the composite action correctly references step-security, all required workflow files are present, and the README is properly updated. However, the subscription check is entirely absent (a required blocker), and there is a critical security flaw in setup.sh where a SHA256 checksum mismatch is treated as a non-fatal warning instead of aborting installation. Both must be fixed before merging.

@Raj-StepSecurity Raj-StepSecurity removed the review-required Request Claude AI code review on the PR label Oct 7, 2026
@Raj-StepSecurity Raj-StepSecurity added review-required Request Claude AI code review on the PR and removed review-required Request Claude AI code review on the PR labels Oct 7, 2026
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown

PR Review

Action Type

Composite Action - uses runs: using: composite in action.yaml with setup.sh as the core implementation.


Passed Checks

  • License: Present with copyright for both the original author (Alif Rachmawadi) and StepSecurity.
  • action.yaml: Present with author: step-security.
  • SECURITY.md: Present with security@stepsecurity.io.
  • FUNDING.yml: Not present (correct).
  • Workflow files: auto_cherry_pick.yml and actions_release.yml both present under .github/workflows/.
  • renovate.json: Not present (correct).
  • PULL_REQUEST.md: Not present (correct).
  • ISSUE_TEMPLATE folder: Not present (correct).
  • CHANGELOG.md: Not present (correct).
  • .vscode folder: Not present (correct).
  • README banner: StepSecurity maintained action banner present at top of README.
  • README version examples: All examples correctly use step-security/flutter-action@v2 (major version only).
  • auto_cherry_pick.yml upstream: Correctly set with original-owner: subosito and repo-name: flutter-action making upstream subosito/flutter-action.

Failed Checks

  • Subscription check is missing: No call to https://agent.api.stepsecurity.io/v1/github/$GITHUB_REPOSITORY/actions/maintained-actions-subscription in setup.sh or action.yaml. This is required for all StepSecurity maintained actions.

  • GIT_SOURCE output is always empty: action.yaml declares GIT_SOURCE as an output (lines 80-82) but setup.sh never writes it to $GITHUB_OUTPUT. Consumers will always receive an empty string.

  • Shell injection in action.yaml line 156: ${{ steps.flutter-action.outputs.CHANNEL }} is used unquoted in a bash run block. All other arguments on the same command are single-quoted; this one is not, enabling injection if CHANNEL contains shell metacharacters.


Warnings

  • step-security/action-shellcheck@v2 in workflow.yaml is a third-party action pinned only to @v2 (mutable tag). Non-official actions should be pinned to a full commit SHA.
  • actions/cache@v5 and actions/checkout@v7 use mutable major-version tags. SHA pinning is recommended for supply-chain hardening.
  • Typo in workflow.yaml (lines 219 and 246): "sepcify" should be "specify".

Security Findings

  1. Shell injection - action.yaml line 156 (High): ${{ steps.flutter-action.outputs.CHANNEL }} is unquoted in a shell run block. Wrap in single quotes to match the other arguments.

  2. Non-fatal SHA256 verification - setup.sh (Medium): In download_archive, a checksum mismatch only prints a warning and execution continues, silently installing a potentially tampered Flutter SDK. This should be a hard exit 1. Combined with the user-controllable FLUTTER_STORAGE_BASE_URL (finding 3), this forms a complete exploit chain.

  3. User-controlled FLUTTER_STORAGE_BASE_URL (Low): The manifest and archive base URL comes from this environment variable (setup.sh line 16). A malicious workflow could redirect it to an attacker-controlled server; since SHA256 failures are only warnings, a tampered SDK would install silently.


Summary

The onboarding structure is solid - licensing, branding, and workflow scaffolding all pass. However, the mandatory subscription check is absent, there is a shell injection vulnerability in action.yaml line 156, a non-fatal SHA256 integrity check in setup.sh that can be exploited, and the GIT_SOURCE output is never populated despite being declared. All four must be resolved before merge.

Comment thread action.yaml
Comment thread action.yaml
Comment thread setup.sh
Comment thread setup.sh
ai analysis addressed

feat: subscription check added
@Raj-StepSecurity Raj-StepSecurity added the review-required Request Claude AI code review on the PR label Oct 7, 2026
Comment thread setup.sh
Comment thread action.yaml
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown

PR Review

Action Type

Composite Action — action.yaml uses runs: using: composite with a shell script (setup.sh) as the primary implementation.


✅ Passed Checks

  • License present with both original author copyright (Alif Rachmawadi / subosito, 2019) and StepSecurity copyright (2026).
  • action.yaml present with author: 'step-security'.
  • SECURITY.md is present.
  • FUNDING.yml is not present.
  • .github/workflows/ contains both required files: auto_cherry_pick.yml and actions_release.yml.
  • renovate.json is not present.
  • PULL_REQUEST.md is not present.
  • ISSUE_TEMPLATE folder is not present.
  • CHANGELOG.md is not present.
  • .vscode folder is not present.
  • README.md action references correctly use major version only (e.g. step-security/flutter-action@v2) — no full semver tags in usage examples.
  • README.md StepSecurity banner is present and correct.
  • Subscription check is present in action.yaml and calls the correct URL: https://agent.api.stepsecurity.io/v1/github/$GITHUB_REPOSITORY/actions/maintained-actions-subscription.
  • UPSTREAM variable is "subosito/flutter-action", correctly matching original-owner: "subosito" and repo-name: "flutter-action" from auto_cherry_pick.yml.
  • Composite action steps only use actions/cache@v5 (official GitHub action) — no unpinned third-party actions in the composite runs block.

❌ Failed Checks

No required checklist items failed.


⚠️ Warnings

  • step-security/action-shellcheck@v2 in workflow.yaml is not pinned to a full commit SHA. Using a mutable tag like @v2 means the workflow is vulnerable to tag-moving supply chain attacks. Pin it to a SHA.
  • actions/checkout@v7 in workflow.yaml is not pinned to a commit SHA. Best practice for CI workflows is to pin all action references to immutable SHAs.
  • step-security/reusable-workflows is referenced at @v1 in both auto_cherry_pick.yml and actions_release.yml — these should ideally be pinned to commit SHAs.

🔒 Security Findings

  1. [HIGH] Checksum mismatch is a warning, not an error — setup.sh lines 65–66
    When a downloaded Flutter SDK archive's SHA256 does not match the manifest value, the script prints a warning but continues execution, unpacking and using the potentially tampered archive. This silently allows a supply chain attack (e.g. a compromised storage artifact) to succeed undetected. The check should exit 1 on mismatch.

  2. [MEDIUM] Unquoted step output injected into shell — action.yaml line 200
    In the "Run setup script" step, ${{ steps.flutter-action.outputs.CHANNEL }} is interpolated directly into the run: block without quoting. If the CHANNEL output ever contains shell metacharacters, it would be executed as a shell command. It should be passed via an environment variable.


Summary

The onboarding is complete and all required structural checks pass. Two security issues need to be addressed before merging: the non-fatal checksum mismatch in setup.sh (which could allow a tampered Flutter SDK to be used silently) and the unquoted shell injection point in action.yaml's "Run setup script" step.

@Raj-StepSecurity
Raj-StepSecurity merged commit a47cbd9 into main Oct 7, 2026
71 checks passed
@Raj-StepSecurity
Raj-StepSecurity deleted the release branch October 7, 2026 11:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review-required Request Claude AI code review on the PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants