diff --git a/.github/workflows/docker-security.yml b/.github/workflows/docker-security.yml index 7578fa8..4355aff 100644 --- a/.github/workflows/docker-security.yml +++ b/.github/workflows/docker-security.yml @@ -2,17 +2,8 @@ name: 🐳 Docker Security Scan on: push: - branches: [main] - paths: - - 'Dockerfile' - - 'entrypoint.sh' - - '.github/workflows/docker-security.yml' pull_request: branches: [main] - paths: - - 'Dockerfile' - - 'entrypoint.sh' - - '.github/workflows/docker-security.yml' schedule: # Run weekly on Sundays at 2 AM UTC - cron: '0 0 * * 0' diff --git a/lib/sanitize.sh b/lib/sanitize.sh index 3659050..829b262 100644 --- a/lib/sanitize.sh +++ b/lib/sanitize.sh @@ -11,7 +11,25 @@ sanitize_string() { sanitized=$(echo "$input" | tr -d '\0' | tr -d '\001-\037' | tr -d '\177-\377' | cut -c1-"$max_length") # Remove potentially dangerous patterns - sanitized=$(echo "$sanitized" | sed 's/[$(){}|;&<>]//g' | tr -d '`') + sanitized=$(echo "$sanitized" | sed 's/[$(){}|;&<>@]//g' | tr -d '`') + + echo "$sanitized" +} + +# Sanitize repository names (owner/repo format) +sanitize_repository() { + local repo="$1" + + # Repository should only contain alphanumeric, hyphens, underscores, dots, and forward slash + local sanitized + sanitized=$(echo "$repo" | sed 's/[^a-zA-Z0-9._/-]//g') + + # Validate format: should be owner/repo + if [[ ! "$sanitized" =~ ^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$ ]]; then + log_error "Invalid repository format: $repo" + log_error "Repository must be in 'owner/repo' format with alphanumeric characters, dots, hyphens, and underscores only" + exit 1 + fi echo "$sanitized" } @@ -20,11 +38,11 @@ sanitize_string() { sanitize_inputs() { log_info "Sanitizing input parameters..." - # # GitHub inputs - # if [[ -n "${REPOSITORY:-}" ]]; then - # REPOSITORY=$(sanitize_repository "$REPOSITORY") - # log_debug "Sanitized REPOSITORY: $REPOSITORY" - # fi + # GitHub inputs + if [[ -n "${REPOSITORY:-}" ]]; then + REPOSITORY=$(sanitize_repository "$REPOSITORY") + log_debug "Sanitized REPOSITORY: $REPOSITORY" + fi # # Mend inputs # if [[ -n "${MEND_EMAIL:-}" ]]; then diff --git a/license-mappings.json b/license-mappings.json index 91280f8..8cfff77 100644 --- a/license-mappings.json +++ b/license-mappings.json @@ -1,4 +1,16 @@ { + "@clickhouse/client": "Apache-2.0", + "@clickhouse/client-common": "Apache-2.0", + "@faker-js/faker": "MIT", + "@istanbuljs/nyc-config-typescript": "ISC", + "@types/jasmine": "MIT", + "@types/jsonwebtoken": "MIT", + "@types/node": "MIT", + "@types/sinon": "MIT", + "@types/split2": "MIT", + "@types/uuid": "MIT", + "@typescript-eslint/eslint-plugin": "MIT", + "@typescript-eslint/parser": "MIT", "4d63.com/gocheckcompilerdirectives": "MIT", "4d63.com/gochecknoglobals": "MIT", "actions/cache": "MIT", @@ -9,10 +21,19 @@ "actions/setup-go": "MIT", "actions/setup-node": "MIT", "actions/setup-python": "MIT", + "actions/upload-artifact": "MIT", + "apache-arrow": "Apache-2.0", + "avsc": "MIT", "aws-actions/configure-aws-credentials": "MIT", "actions/create-github-app-token": "MIT", + "codecov/codecov-action": "MIT", + "com.github.ClickHouse/clickhouse-js": "Apache-2.0", "CycloneDX/gh-gomod-generate-sbom": "Apache-2.0", "dario.cat/mergo": "BSD-3-Clause", + "eslint": "MIT", + "eslint-config-prettier": "MIT", + "eslint-plugin-expect-types": "Apache-2.0", + "eslint-plugin-prettier": "MIT", "github.com/andybalholm/brotli": "MIT", "github.com/Azure/go-ansiterm": "MIT", "github.com/cenkalti/backoff/v4": "MIT", @@ -70,6 +91,7 @@ "github/codeql-action/analyze": "MIT", "github/codeql-action/autobuild": "MIT", "github/codeql-action/init": "MIT", + "github/codeql-action/upload-sarif": "MIT", "go.opentelemetry.io/auto/sdk": "Apache-2.0", "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp": "Apache-2.0", "go.opentelemetry.io/otel": "Apache-2.0", @@ -81,5 +103,36 @@ "golang.org/x/net": "BSD-3-Clause", "golang.org/x/sys": "BSD-3-Clause", "gopkg.in/yaml.v3": "MIT", - "RoryCrispin/gh-action-bump-version": "MIT" + "husky": "MIT", + "isbang/compose-action": "MIT", + "jasmine": "MIT", + "jasmine-core": "MIT", + "jasmine-expect": "MIT", + "jsonwebtoken": "MIT", + "karma": "MIT", + "karma-chrome-launcher": "MIT", + "karma-firefox-launcher": "MIT", + "karma-jasmine": "MIT", + "karma-mocha-reporter": "MIT", + "karma-sourcemap-loader": "MIT", + "karma-typescript": "MIT", + "karma-webpack": "MIT", + "lint-staged": "MIT", + "nyc": "ISC", + "ossf/scorecard-action": "Apache-2.0", + "set-interval-async": "MIT", + "sinon": "BSD-3-Clause", + "source-map-support": "MIT", + "split2": "ISC", + "RoryCrispin/gh-action-bump-version": "MIT", + "terser-webpack-plugin": "MIT", + "ts-loader": "MIT", + "ts-node": "MIT", + "tsconfig-paths": "MIT", + "tsconfig-paths-webpack-plugin": "MIT", + "typescript": "Apache-2.0", + "uuid": "MIT", + "webpack": "MIT", + "webpack-cli": "MIT", + "webpack-merge": "MIT" } diff --git a/test/simple.bats b/test/simple.bats index e16aa3f..b4d74c1 100644 --- a/test/simple.bats +++ b/test/simple.bats @@ -304,4 +304,88 @@ EOF run sanitize_string "test\$command\`echo hello\`" [ "$status" -eq 0 ] [[ "$output" == "testcommandecho hello" ]] +} + +# Test 23: sanitize_string removes null bytes and control characters +@test "sanitize_string removes control characters" { + # Test string with null byte, control characters + local test_string=$(printf "test\000string\001\002\003") + run sanitize_string "$test_string" + [ "$status" -eq 0 ] + [[ "$output" == "teststring" ]] +} + +# Test 24: sanitize_string limits length +@test "sanitize_string respects length limit" { + local long_string=$(printf 'a%.0s' {1..2000}) + run sanitize_string "$long_string" 100 + [ "$status" -eq 0 ] + [ "${#output}" -eq 100 ] +} + +# Test 25: sanitize_string removes shell metacharacters +@test "sanitize_string removes shell metacharacters" { + run sanitize_string "test|command;rm -rf /&" + [ "$status" -eq 0 ] + [[ "$output" == "testcommandrm -rf /" ]] +} + +# Test 26: sanitize_string preserves safe characters +@test "sanitize_string preserves safe characters" { + run sanitize_string "test-string_with.safe@characters123" + [ "$status" -eq 0 ] + [[ "$output" == "test-string_with.safecharacters123" ]] +} + +# Test 27: sanitize_repository valid input +@test "sanitize_repository accepts valid repository format" { + run sanitize_repository "owner/repo" + [ "$status" -eq 0 ] + [[ "$output" == "owner/repo" ]] +} + +# Test 28: sanitize_repository accepts repository with hyphens and underscores +@test "sanitize_repository accepts repository with hyphens and underscores" { + run sanitize_repository "my-org/my_repo-name" + [ "$status" -eq 0 ] + [[ "$output" == "my-org/my_repo-name" ]] +} + +# Test 29: sanitize_repository accepts repository with dots +@test "sanitize_repository accepts repository with dots" { + run sanitize_repository "my.org/repo.name" + [ "$status" -eq 0 ] + [[ "$output" == "my.org/repo.name" ]] +} + +# Test 30: sanitize_repository removes dangerous characters +@test "sanitize_repository removes dangerous characters" { + run sanitize_repository "owner\$bad/repo;rm" + [ "$status" -eq 0 ] + [[ "$output" == "ownerbad/reporm" ]] +} + +# Test 31: sanitize_repository rejects invalid format - special characters +@test "sanitize_repository rejects invalid format - no slash" { + run sanitize_repository "invalidrepo" + [ "$status" -eq 1 ] + [[ "$output" == *"Invalid repository format"* ]] +} + +# Test 32: sanitize_repository rejects invalid format - multiple slashes +@test "sanitize_repository rejects invalid format - multiple slashes" { + run sanitize_repository "owner/repo/extra" + [ "$status" -eq 1 ] + [[ "$output" == *"Invalid repository format"* ]] +} + +# Test 33: sanitize_repository rejects invalid format - empty owner or repo +@test "sanitize_repository rejects empty owner or repo" { + run sanitize_repository "/repo" + [ "$status" -eq 1 ] + [[ "$output" == *"Invalid repository format"* ]] + + run sanitize_repository "owner/" + [ "$status" -eq 1 ] + [[ "$output" == *"Invalid repository format"* ]] } \ No newline at end of file