diff --git a/.changelog/2033.internal.md b/.changelog/2033.internal.md new file mode 100644 index 0000000000..a5c26b92bc --- /dev/null +++ b/.changelog/2033.internal.md @@ -0,0 +1 @@ +Harden github workflow against injection diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 669a7b01bc..8198d36d42 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -50,11 +50,11 @@ jobs: - name: Sync Capacitor for Android run: yarn cap sync android - name: Accept SDK licenses - run: yes | $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --licenses + run: yes | "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" --licenses # Capacitor v6 sets a deployment target of Android 14 (SDK 34) - name: Install SDK components run: | - $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager "platform-tools" "platforms;android-34" "build-tools;34.0.0" + "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" "platform-tools" "platforms;android-34" "build-tools;34.0.0" - name: Build Android App Bundle (AAB) if: github.event_name == 'push' run: ./gradlew bundleRelease @@ -64,18 +64,18 @@ jobs: working-directory: android - name: Decode and Save Keystore File run: | - echo "${{ secrets.KEYSTORE_FILE }}" | base64 --decode > android/release.jks + echo "${{ secrets.KEYSTORE_FILE }}" | base64 --decode > "android/release.jks" - name: Sign AAB using jarsigner if: github.event_name == 'push' run: | - jarsigner -verbose -keystore android/release.jks -storepass ${{ secrets.KEYSTORE_PASSWORD }} -keypass ${{ secrets.KEYSTORE_PASSWORD }} -signedjar android/app/build/outputs/bundle/release/app-release-signed.aab android/app/build/outputs/bundle/release/app-release.aab ${{ secrets.KEY_ALIAS }} + jarsigner -verbose -keystore "android/release.jks" -storepass "${{ secrets.KEYSTORE_PASSWORD }}" -keypass "${{ secrets.KEYSTORE_PASSWORD }}" -signedjar "android/app/build/outputs/bundle/release/app-release-signed.aab" "android/app/build/outputs/bundle/release/app-release.aab" "${{ secrets.KEY_ALIAS }}" # Targeting version 30 and above we need to align the APK so that all uncompressed data starts on a 4-byte boundary - name: Zipalign APK run: | - $ANDROID_SDK_ROOT/build-tools/31.0.0/zipalign -v 4 android/app/build/outputs/apk/release/app-release-unsigned.apk android/app/build/outputs/apk/release/app-release-aligned.apk + "$ANDROID_SDK_ROOT/build-tools/31.0.0/zipalign" -v 4 "android/app/build/outputs/apk/release/app-release-unsigned.apk" "android/app/build/outputs/apk/release/app-release-aligned.apk" - name: Sign APK using apksigner run: | - $ANDROID_SDK_ROOT/build-tools/31.0.0/apksigner sign --ks android/release.jks --ks-pass pass:${{ secrets.KEYSTORE_PASSWORD }} --key-pass pass:${{ secrets.KEYSTORE_PASSWORD }} --ks-key-alias ${{ secrets.KEY_ALIAS }} android/app/build/outputs/apk/release/app-release-aligned.apk + "$ANDROID_SDK_ROOT/build-tools/31.0.0/apksigner" sign --ks "android/release.jks" --ks-pass "pass:${{ secrets.KEYSTORE_PASSWORD }}" --key-pass "pass:${{ secrets.KEYSTORE_PASSWORD }}" --ks-key-alias "${{ secrets.KEY_ALIAS }}" "android/app/build/outputs/apk/release/app-release-aligned.apk" - name: Upload Android AAB build artifacts if: github.event_name == 'push' uses: actions/upload-artifact@v4 diff --git a/.github/workflows/ci-renovate.yml b/.github/workflows/ci-renovate.yml index 74603d2edc..4d190940af 100644 --- a/.github/workflows/ci-renovate.yml +++ b/.github/workflows/ci-renovate.yml @@ -29,20 +29,21 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} # Needed to enable checks re-run. token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} - - name: Set workflow variables - # Id is needed to access output in a next step. - id: vars - run: | - echo "FILE_NAME=.changelog/${{ github.event.pull_request.number }}.internal.md" >> $GITHUB_OUTPUT - name: Create and commit Change Log fragment if it does not exist + env: + # There's no support for escaping this for use in a shell command. + # GitHub's recommendation is to pass it through the environment. + # https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable + FILE_NAME: .changelog/${{ github.event.pull_request.number }}.internal.md + HEAD_REF: ${{ github.head_ref }} run: | - if [[ ! -f "${{ steps.vars.outputs.FILE_NAME }}" ]]; then - echo "Update dependencies" > ${{ steps.vars.outputs.FILE_NAME }} + if [[ ! -f "$FILE_NAME" ]]; then + echo "Update dependencies" > "$FILE_NAME" # Set git user email and name to match author of the last commit. git config --local user.email "$(git log --pretty='%ae' -1)" git config --local user.name "$(git log --pretty=format:'%an' -1)" - git add ${{ steps.vars.outputs.FILE_NAME }} + git add "$FILE_NAME" git commit --amend --no-edit - git push --force-with-lease origin HEAD:refs/heads/${{ github.head_ref }} - echo "FILE_EXISTS=false" >> $GITHUB_OUTPUT + git push --force-with-lease origin "HEAD:refs/heads/$HEAD_REF" + echo "FILE_EXISTS=false" >> "$GITHUB_OUTPUT" fi diff --git a/.github/workflows/dump-validators.yml b/.github/workflows/dump-validators.yml index 944cbfbc4d..9154343275 100644 --- a/.github/workflows/dump-validators.yml +++ b/.github/workflows/dump-validators.yml @@ -17,7 +17,10 @@ jobs: steps: - uses: actions/checkout@v4 - run: bash ./.github/dump_validators.sh - - run: echo "Update dumped validators" > ".changelog/${{ github.event.pull_request.number }}.internal.md" + - name: Create Change Log fragment + env: + FILE_NAME: .changelog/${{ github.event.pull_request.number }}.internal.md + run: echo "Update dumped validators" > "$FILE_NAME" - name: Create Pull Request with updated dumped validators # https://github.com/peter-evans/create-pull-request uses: peter-evans/create-pull-request@v5 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 29830fa2bd..02d9d0bddf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,11 +43,11 @@ jobs: - name: Sync Capacitor for Android run: yarn cap sync android - name: Accept SDK licenses - run: yes | $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --licenses + run: yes | "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" --licenses # Capacitor v6 sets a deployment target of Android 14 (SDK 34) - name: Install SDK components run: | - $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager "platform-tools" "platforms;android-34" "build-tools;34.0.0" + "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" "platform-tools" "platforms;android-34" "build-tools;34.0.0" - name: Build Android ROSE Wallet run: ./gradlew bundleRelease working-directory: android @@ -56,25 +56,37 @@ jobs: echo "${{ secrets.KEYSTORE_FILE }}" | base64 --decode > android/release.jks - name: Sign Android bundle run: | - jarsigner -verbose -keystore android/release.jks -storepass ${{ secrets.KEYSTORE_PASSWORD }} -keypass ${{ secrets.KEYSTORE_PASSWORD }} -signedjar android/app/build/outputs/bundle/release/app-release-signed.aab android/app/build/outputs/bundle/release/app-release.aab ${{ secrets.KEY_ALIAS }} + jarsigner -verbose -keystore "android/release.jks" -storepass "${{ secrets.KEYSTORE_PASSWORD }}" -keypass "${{ secrets.KEYSTORE_PASSWORD }}" -signedjar "android/app/build/outputs/bundle/release/app-release-signed.aab" "android/app/build/outputs/bundle/release/app-release.aab" "${{ secrets.KEY_ALIAS }}" - name: Set workflow variables # Id is needed to access output in a next step. id: vars + env: + # There's no support for escaping this for use in a shell command. + # GitHub's recommendation is to pass it through the environment. + # https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable + REF_NAME: ${{ github.ref_name }} # We want to show version without the leading 'v' # and use short SHA of the commit for file name. run: | - echo "VERSION=$(echo ${{ github.ref_name }} | sed 's/^v//')" >> "$GITHUB_OUTPUT" + echo "VERSION=$(echo "$REF_NAME" | sed 's/^v//')" >> "$GITHUB_OUTPUT" - name: Copy and rename Android bundle + env: + # Need to escape again + VERSION: ${{ steps.vars.outputs.VERSION }} run: | - cp android/app/build/outputs/bundle/release/app-release-signed.aab rose-wallet-android-${{ steps.vars.outputs.VERSION }}.aab + cp "android/app/build/outputs/bundle/release/app-release-signed.aab" "rose-wallet-android-$VERSION.aab" - name: Create web ROSE Wallet zip file + env: + VERSION: ${{ steps.vars.outputs.VERSION }} run: | cd build/ - zip -r ../rose-wallet-web-${{ steps.vars.outputs.VERSION }}.zip . + zip -r "../rose-wallet-web-$VERSION.zip" . - name: Create extension ROSE Wallet zip file + env: + VERSION: ${{ steps.vars.outputs.VERSION }} run: | cd build-ext/ - zip -r ../rose-wallet-ext-${{ steps.vars.outputs.VERSION }}.zip . + zip -r "../rose-wallet-ext-$VERSION.zip" . - name: Parse CHANGELOG.md file and extract changes for the given version uses: buberdds/extract-changelog-action@v1 id: changelog