diff --git a/.github/workflows/test_docker_image_sanitize_input.yml b/.github/workflows/test_docker_image_sanitize_input.yml new file mode 100644 index 0000000..08c8099 --- /dev/null +++ b/.github/workflows/test_docker_image_sanitize_input.yml @@ -0,0 +1,75 @@ +name: test_docker_image_sanitize_input + +on: + push: + branches: [ main ] + paths: + - '.github/actions/sanitize-docker-input/**' + pull_request: + paths: + - '.github/actions/sanitize-docker-input/**' + workflow_dispatch: + +jobs: + # Test cases that are supposed to succeed + test-valid-inputs: + runs-on: ubuntu-24.04 + strategy: + matrix: + image: + - 'ubuntu:latest' + - 'nginx:1.25.2' + - 'my-registry.com/my-project/node:18-alpine' + - 'gcr.io/google-containers/pause:3.9' + - 'custom_image.name:v1.0.0-beta' + steps: + - name: Checkout Code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + + # We expect all of these to finish with an exit code of 0 + - name: Test Valid Input (${{ matrix.image }}) + id: test_action + uses: sanitize-docker-input + with: + image_string: ${{ matrix.image }} + + - name: Verify Output Match + run: | + if [ "${{ steps.test_action.outputs.sanitized_image }}" != "${{ matrix.image }}" ]; then + echo "Error: Output string did not match input!" + exit 1 + fi + + # Test cases that are supposed to fail (malicious or invalid format) + test-invalid-inputs: + runs-on: ubuntu-24.04 + strategy: + matrix: + image: + - 'ubuntu' # Naked image + - 'ubuntu:' # Missing tag definition + - 'ubuntu:latest; rm -rf /' # Command injection attempt + - 'nginx:latest && echo hacked' # Command injection attempt + - 'registry.com/image:INVALID_TAG_!!!!' # Violates regex character limits + steps: + - name: Checkout Code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + + # This step forces the workflow to continue even if the action fails, + # allowing us to assert that it DID fail properly. + - name: Test Invalid Input (${{ matrix.image }}) + id: test_action + continue-on-error: true + uses: sanitize-docker-input + with: + image_string: ${{ matrix.image }} + + # Assert that the step outcome was a failure. If it succeeded, the test fails. + - name: Verify Action Failed Properly + run: | + if [ "${{ steps.test_action.outcome }}" == "success" ]; then + echo "CRITICAL SECURITY FAILURE: The input '${{ matrix.image }}' bypassed validation!" + exit 1 + else + echo "Success: Action safely caught and rejected the invalid input." + fi \ No newline at end of file diff --git a/docker_image_sanitize_input/action.yml b/docker_image_sanitize_input/action.yml new file mode 100644 index 0000000..b850001 --- /dev/null +++ b/docker_image_sanitize_input/action.yml @@ -0,0 +1,42 @@ +--- +name: 'Sanitize and Validate Docker Image' +description: 'Validates a Docker image string against a strict regex and ensures it is tagged.' +inputs: + image_string: + description: 'The raw docker image string to validate' + required: true + +outputs: + sanitized_image: + description: 'The validated and safe docker image string' + value: ${{ steps.validator.outputs.validated_image }} + +runs: + using: "composite" + steps: + - name: Validate Input + id: validator + shell: bash + # Pass the raw input as an environment variable to prevent Command Injection + env: + RAW_IMAGE: ${{ inputs.image_string }} + # Your exact custom regex provided: + DOCKER_REGEX: '^(?:[a-zA-Z0-9.-]+(?::[0-9]+)?\/)?(?:[a-z0-9]+(?:[._-][a-z0-9]+)*\/)*[a-z0-9]+(?:[._-][a-z0-9]+)*:[A-Za-z0-9][A-Za-z0-9._-]{0,127}$' + run: | + echo "Checking image string format..." + + # 1. Reject if it is exactly 'ubuntu' or lacks a tag/digest delimiter + if [[ "$RAW_IMAGE" == "ubuntu" ]] || [[ "$RAW_IMAGE" != *":"* && "$RAW_IMAGE" != *"@"* ]]; then + echo "::error::Invalid Input! Raw image names like 'ubuntu' without a specific version tag are strictly banned." + exit 1 + fi + + # 2. Match against your custom regex + if [[ "$RAW_IMAGE" =~ $DOCKER_REGEX ]]; then + echo "Success: Image format is valid and secure." + # Export the safely validated string to outputs + echo "validated_image=$RAW_IMAGE" >> $GITHUB_OUTPUT + else + echo "::error::Invalid Input! The string '$RAW_IMAGE' does not match the allowed Docker image format rules." + exit 1 + fi \ No newline at end of file diff --git a/docs-firecrawl-llm/package-lock.json b/docs-firecrawl-llm/package-lock.json index bb8b0ad..2629309 100644 --- a/docs-firecrawl-llm/package-lock.json +++ b/docs-firecrawl-llm/package-lock.json @@ -13,9 +13,9 @@ } }, "node_modules/@mendable/firecrawl-js": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@mendable/firecrawl-js/-/firecrawl-js-4.24.2.tgz", - "integrity": "sha512-WGFCCkWEgVVTMCpukk/pPHgZE+6N2yR+JWeYve+DfLp+8SrCQB7pjvotN9J/8sAh9THd3daI8C5pb2BBBXJq1Q==", + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@mendable/firecrawl-js/-/firecrawl-js-4.25.0.tgz", + "integrity": "sha512-Dxk85bNe/IEVPvND0w3Peenvg08TgLuaN8fYHi3ShDdivc0jJpXEB8rgczOD8gKsz18CzaV/YnPnj6TL/SCQdw==", "license": "MIT", "dependencies": { "axios": "1.15.2", diff --git a/secure_github_binary_download/action.yml b/secure_github_binary_download/action.yml new file mode 100644 index 0000000..b0c3aae --- /dev/null +++ b/secure_github_binary_download/action.yml @@ -0,0 +1,41 @@ +--- +name: 'Secure GitHub Binary Downloader' +description: 'Downloads a release binary from GitHub and verifies its SHA-256 checksum automatically.' +inputs: + version: + description: 'The version of the tool to download (e.g., 1.18.3)' + required: true + repo: + description: 'The GitHub owner/repository (e.g., kurtosis-tech/kurtosis-cli-release-artifacts)' + required: true + tarball_name: + description: 'The exact name of the asset file (e.g., kurtosis-cli_1.18.3_linux_amd64.tar.gz)' + required: true + binary_name: + description: 'The name of the compiled binary inside the archive (e.g., kurtosis)' + required: true + +runs: + using: "composite" + steps: + - name: Download Asset and Checksums + shell: bash + run: | + echo "Downloading ${{ inputs.tarball_name }} from ${{ inputs.repo }}..." + curl -fsSL -O "https://github.com/${{ inputs.repo }}/releases/download/${{ inputs.version }}/${{ inputs.tarball_name }}" + curl -fsSL -O "https://github.com/${{ inputs.repo }}/releases/download/${{ inputs.version }}/checksums.txt" + + - name: Verify SHA-256 Checksum + shell: bash + run: | + echo "Verifying checksum..." + grep "${{ inputs.tarball_name }}" checksums.txt | sha256sum --check + + - name: Extract and Install Binary + shell: bash + run: | + tar -xvf "${{ inputs.tarball_name }}" + sudo mv "${{ inputs.binary_name }}" /usr/local/bin/ + + # Cleanup workspace archives so they don't bloat later steps + rm "${{ inputs.tarball_name }}" checksums.txt \ No newline at end of file