-
Notifications
You must be signed in to change notification settings - Fork 51
Add immutable action check #2496
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
104 commits
Select commit
Hold shift + click to select a range
8daceb1
Merge pull request #1299 from Devils-Knight/fix-dependabot
ashishkurmi 7105c41
remediate files & packages
Devils-Knight b99b655
mod tidy
Devils-Knight f6256ca
add version comment to pinned actions
Devils-Knight ffdfe27
Merge pull request #1374 from Devils-Knight/comment
varunsh-coder 088800b
Merge branch 'int' into pr/1352
varunsh-coder 3da1738
Merge pull request #1352 from Devils-Knight/remediation
varunsh-coder 7bcb807
Update harden runner version
varunsh-coder cc5afdc
Merge pull request #1379 from step-security/update-harden-harden-int
varunsh-coder b994863
[UPDATE] Pin actions to vx.y.z format (#1469)
Devils-Knight e9482c1
Update test command
varunsh-coder 361b35a
Merge pull request #1476 from step-security/update-workflow-test-cmd
varunsh-coder 8e7b11c
Update test cases
varunsh-coder 4672343
Merge pull request #1477 from step-security/update-tests
varunsh-coder c096e5f
Merge branch 'main' into int
varunsh-coder 9c234e9
update pinning remediation
Devils-Knight a84a433
Return secret metadata
varunsh-coder 787f313
Merge pull request #1597 from step-security/return-secret-metadata
varunsh-coder 9372c3f
Update secrets.go
varunsh-coder ea1fb43
Merge pull request #1598 from step-security/return-secret-metadata
varunsh-coder 7906268
Merge pull request #1582 from Devils-Knight/pinIssue
varunsh-coder 0e48ac5
configuring dependabot to use INT for upggrading dependencies
ashishkurmi e7de507
Merge pull request #1618 from step-security/ak-dependabot-int
ashishkurmi b57f3f7
Merge branch 'main' into int
varunsh-coder 086252d
Merge branch 'main' into int
varunsh-coder 582a89d
[FEATURE] Added Template and addWorkflow function to generate Codeql …
Devils-Knight ee52f8f
fixed typo
Devils-Knight ad10892
Merge pull request #1643 from Devils-Knight/issue
varunsh-coder 23233ec
Update addworkflow.go
varunsh-coder 14cc00f
Merge pull request #1657 from step-security/update-workflow-env
varunsh-coder 1c68758
Update template
varunsh-coder 8fe562e
Merge pull request #1667 from step-security/fix-template
varunsh-coder 7903c6b
[FEATURE] Added template for Dependency-review and Scorecards (#1755)
Devils-Knight 559d233
Merge branch 'main' into int
varunsh-coder e0c7869
Update expected-codeql.yml
varunsh-coder 571b89a
Update reference from Secure-Workflow to Secure-Repo (#1905)
Devils-Knight 0a7ecc9
Merge branch 'main' into int
varunsh-coder a5395f3
Update scorecards.yml
varunsh-coder 8673c00
Update expected-scorecards.yml
varunsh-coder 09a145c
updated pinning docker image
Devils-Knight 6d49773
comment added
Devils-Knight abc34e3
update pin docker
Devils-Knight e4612f7
Merge pull request #1989 from Devils-Knight/bug2
varunsh-coder 97fa737
Merge pull request #1988 from Devils-Knight/bug
varunsh-coder acfa53b
fix pinning docker issue
Devils-Knight 01a8c09
Merge pull request #2006 from Devils-Knight/pinBug
varunsh-coder b9b32d3
Merge branch 'main' into int
varunsh-coder 7bc0089
Trim comments
arjundashrath 25f90b0
update docker action format
Devils-Knight 161b8b0
Merge pull request #2014 from Devils-Knight/issue-docker
varunsh-coder 4af0234
Merge pull request #2010 from arjundashrath/main
varunsh-coder ff05a33
update secureWorkflow
Devils-Knight 03f4760
Merge pull request #2044 from Devils-Knight/updateSecure
ashishkurmi adfb0fa
Merge branch 'main' into int
varunsh-coder 830739d
Fix sentence and remove existing action comments (#2067)
arjundashrath eadfcec
Revert "Fix sentence and remove existing action comments (#2067)"
varunsh-coder 22dbc7f
Change comment removal logic (#2092)
arjundashrath 6ecd88d
[UPDATE] Add pre-commit hooks to catch linting issues (#2098)
Devils-Knight 837e44e
adding a workflow for reviewing code using stepsecurity code reviewer
ashishkurmi f101b58
Merge pull request #2101 from step-security/ak-code-reviewer
ashishkurmi 953d1e1
adding permissions for code review workflow
ashishkurmi e62e8f4
Merge pull request #2102 from step-security/ak-code-review-permissions
ashishkurmi d81817d
Update code-review.yml
varunsh-coder 9512ea4
Merge pull request #2105 from step-security/ak-main-to-int-code-review
ashishkurmi 9da4543
updated getHooks
Devils-Knight cfc9d10
Merge pull request #2107 from Devils-Knight/upd
varunsh-coder 76518e2
adding id-token write permission for code review action
ashishkurmi 7dd4c19
Merge pull request #2111 from step-security/ak-updating-code-reviewer…
ashishkurmi 1e3d19f
using ai-codewise int for dogfooding
ashishkurmi ab6b1a0
Merge pull request #2129 from step-security/ak-codewise-int
ashishkurmi 0a314e6
adding int backend endpoint
ashishkurmi 287df91
Merge pull request #2131 from step-security/ak-code-review-int-endpoint
ashishkurmi 2c6acf6
updated precommit filePath
Devils-Knight d83b06a
Merge pull request #2135 from Devils-Knight/fixPrecommit
varunsh-coder 754651f
Merge branch 'main' into int
varunsh-coder 69f0820
Fix Dependabot config indentation issue (#2140)
varunsh-coder 6ad2893
Merge branch 'main' into int
varunsh-coder 32f4cc0
Update pre-commit logic
varunsh-coder a45e0e3
Merge pull request #2205 from step-security/pre-commit-line
varunsh-coder 0eb8144
Merge branch 'main' into int
varunsh-coder 92198fc
[StepSecurity] ci: Harden GitHub Actions
step-security-bot f1c6979
Merge pull request #2230 from step-security/ak-int-harden-runner
ashishkurmi cb9e08f
directory path test case added
Devils-Knight 630c1e2
Merge pull request #2257 from Devils-Knight/fix2
varunsh-coder 6423e32
update workflow templates to latest versions
shubham-stepsecurity 7a92f67
bump codeql version
shubham-stepsecurity 1e0ada6
updating harden-runner version in code review workflow
ashishkurmi 729990c
Merge pull request #2461 from step-security/ak-codewise-hr-upgrade
ashishkurmi 735c02a
Merge pull request #2460 from step-security/issue2120
ashishkurmi 197383b
removing knowledge base for tomwillis608/detect-secrets-action as it …
ashishkurmi 99b254c
Merge pull request #2464 from step-security/ak-remove-tomwillis608-de…
ashishkurmi fea221a
Do not set permissions for jobs with GITHUB_TOKEN in job level env
shubham-stepsecurity 95abd71
Merge pull request #2480 from step-security/issue2479
varunsh-coder 6f91094
Update KB and action tags
varunsh-coder 5259779
Merge pull request #2481 from step-security/fix-tests
varunsh-coder fa7c85b
add additional prms for scorecard template for private repos
shubham-stepsecurity 929021e
Merge pull request #2484 from step-security/issue2483
varunsh-coder 4b43059
add immutable action check
sailikhith-stepsecurity 93e48d5
fix test
sailikhith-stepsecurity 31acb70
update kb by moving remove-disabled-formulae to remove-disabled-pack…
sailikhith-stepsecurity 837f1d1
removing unwanted change
sailikhith-stepsecurity fe96d6f
mocking http server for unit tests
sailikhith-stepsecurity 1283961
updating pinnig logic to use immutable version instead of hash
sailikhith-stepsecurity 3a3a0b2
Merge branch 'int' of github.com:step-security/secure-repo into immut…
sailikhith-stepsecurity File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 0 additions & 2 deletions
2
knowledge-base/actions/homebrew/actions/remove-disabled-formulae/action-security.yml
This file was deleted.
Oops, something went wrong.
2 changes: 2 additions & 0 deletions
2
knowledge-base/actions/homebrew/actions/remove-disabled-packages/action-security.yml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
name: Remove disabled packages # Homebrew/actions/remove-disabled-packages | ||
# GITHUB_TOKEN not used |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package pin | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"regexp" | ||
"strings" | ||
|
||
"net/http" | ||
|
||
"github.com/google/go-containerregistry/pkg/name" | ||
"github.com/google/go-containerregistry/pkg/v1/remote" | ||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
var ( | ||
githubImmutableActionArtifactType = "application/vnd.github.actions.package.v1+json" | ||
semanticTagRegex = regexp.MustCompile(`v[0-9]+\.[0-9]+\.[0-9]+$`) | ||
) | ||
|
||
type ociManifest struct { | ||
ArtifactType string `json:"artifactType"` | ||
} | ||
|
||
// isImmutableAction checks if the action is an immutable action or not | ||
// It queries the OCI manifest for the action and checks if the artifact type is "application/vnd.github.actions.package.v1+json" | ||
// | ||
// Example usage: | ||
// | ||
// # Immutable action (returns true) | ||
// isImmutableAction("actions/[email protected]") | ||
// | ||
// # Non-Immutable action (returns false) | ||
// isImmutableAction("actions/[email protected]") | ||
// | ||
// REF - https://github.com/actions/publish-immutable-action/issues/216#issuecomment-2549914784 | ||
func IsImmutableAction(action string) bool { | ||
|
||
artifactType, err := getOCIImageArtifactTypeForGhAction(action) | ||
if err != nil { | ||
// log the error | ||
logrus.WithFields(logrus.Fields{"action": action}).WithError(err).Error("error in getting OCI manifest for image") | ||
return false | ||
} | ||
|
||
if artifactType == githubImmutableActionArtifactType { | ||
return true | ||
} | ||
return false | ||
|
||
} | ||
|
||
// getOCIImageArtifactTypeForGhAction retrieves the artifact type from a GitHub Action's OCI manifest. | ||
// This function is used to determine if an action is immutable by checking its artifact type. | ||
// | ||
// Example usage: | ||
// | ||
// # Immutable action (returns "application/vnd.github.actions.package.v1+json", nil) | ||
// artifactType, err := getOCIImageArtifactTypeForGhAction("actions/[email protected]") | ||
// | ||
// Returns: | ||
// - artifactType: The artifact type string from the OCI manifest | ||
// - error: An error if the action format is invalid or if there's a problem retrieving the manifest | ||
func getOCIImageArtifactTypeForGhAction(action string) (string, error) { | ||
|
||
// Split the action into parts (e.g., "actions/checkout@v2" -> ["actions/checkout", "v2"]) | ||
parts := strings.Split(action, "@") | ||
if len(parts) != 2 { | ||
return "", fmt.Errorf("invalid action format") | ||
} | ||
|
||
// convert v1.x.x to 1.x.x which is | ||
// use regexp to match tag version format and replace v in prefix | ||
// as immutable actions image tag is in format 1.x.x (without v prefix) | ||
// REF - https://github.com/actions/publish-immutable-action/issues/216#issuecomment-2549914784 | ||
if semanticTagRegex.MatchString(parts[1]) { | ||
// v1.x.x -> 1.x.x | ||
parts[1] = strings.TrimPrefix(parts[1], "v") | ||
} | ||
|
||
// Convert GitHub action to GHCR image reference using proper OCI reference format | ||
image := fmt.Sprintf("ghcr.io/%s:%s", parts[0], parts[1]) | ||
imageManifest, err := getOCIManifestForImage(image) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
var ociManifest ociManifest | ||
err = json.Unmarshal([]byte(imageManifest), &ociManifest) | ||
if err != nil { | ||
return "", err | ||
} | ||
return ociManifest.ArtifactType, nil | ||
} | ||
|
||
// getOCIManifestForImage retrieves the artifact type from the OCI image manifest | ||
func getOCIManifestForImage(imageRef string) (string, error) { | ||
|
||
// Parse the image reference | ||
ref, err := name.ParseReference(imageRef) | ||
if err != nil { | ||
return "", fmt.Errorf("error parsing reference: %v", err) | ||
} | ||
|
||
// Get the image manifest | ||
desc, err := remote.Get(ref, remote.WithTransport(http.DefaultTransport)) | ||
if err != nil { | ||
return "", fmt.Errorf("error getting manifest: %v", err) | ||
} | ||
|
||
return string(desc.Manifest), nil | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
package pin | ||
|
||
import ( | ||
"crypto/tls" | ||
"io/ioutil" | ||
"net/http" | ||
"net/http/httptest" | ||
"path/filepath" | ||
"strings" | ||
"testing" | ||
) | ||
|
||
type customTransport struct { | ||
base http.RoundTripper | ||
baseURL string | ||
} | ||
|
||
func (t *customTransport) RoundTrip(req *http.Request) (*http.Response, error) { | ||
if strings.Contains(req.URL.Host, "ghcr.io") { | ||
req2 := req.Clone(req.Context()) | ||
req2.URL.Scheme = "https" | ||
req2.URL.Host = strings.TrimPrefix(t.baseURL, "https://") | ||
return t.base.RoundTrip(req2) | ||
} | ||
return t.base.RoundTrip(req) | ||
} | ||
|
||
func createGhesTestServer(t *testing.T) *httptest.Server { | ||
return httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
|
||
w.Header().Set("Content-Type", "application/json") | ||
|
||
if !strings.Contains(r.Host, "ghcr.io") { | ||
w.WriteHeader(http.StatusNotFound) | ||
return | ||
} | ||
// Mock manifest endpoints | ||
switch r.URL.Path { | ||
|
||
case "/v2/": // simulate ping request | ||
w.WriteHeader(http.StatusOK) | ||
|
||
case "/token": | ||
// for immutable actions, since image will be present in registry...it returns 200 OK with token | ||
// otherwise it returns 403 Forbidden | ||
scope := r.URL.Query().Get("scope") | ||
switch scope { | ||
case "repository:actions/checkout:pull": | ||
fallthrough | ||
case "repository:step-security/wait-for-secrets:pull": | ||
|
||
w.WriteHeader(http.StatusOK) | ||
w.Write([]byte(`{"token": "test-token", "access_token": "test-token"}`)) | ||
default: | ||
w.WriteHeader(http.StatusForbidden) | ||
w.Write([]byte(`{"errors": [{"code": "DENIED", "message": "requested access to the resource is denied"}]}`)) | ||
} | ||
|
||
case "/v2/actions/checkout/manifests/4.2.2": | ||
fallthrough | ||
case "/v2/actions/checkout/manifests/1.2.0": | ||
fallthrough | ||
case "/v2/step-security/wait-for-secrets/manifests/1.2.0": | ||
w.Write(readHttpResponseForAction(t, r.URL.Path)) | ||
case "/v2/actions/checkout/manifests/1.2.3": // since this version doesn't exist | ||
fallthrough | ||
default: | ||
w.WriteHeader(http.StatusNotFound) | ||
w.Write(readHttpResponseForAction(t, "default")) | ||
} | ||
})) | ||
} | ||
|
||
func Test_isImmutableAction(t *testing.T) { | ||
// Create test server that mocks GitHub Container Registry | ||
server := createGhesTestServer(t) | ||
defer server.Close() | ||
|
||
// Create a custom client that redirects ghcr.io to our test server | ||
originalClient := http.DefaultClient | ||
http.DefaultClient = &http.Client{ | ||
Transport: &customTransport{ | ||
base: &http.Transport{ | ||
TLSClientConfig: &tls.Config{ | ||
InsecureSkipVerify: true, | ||
}, | ||
}, | ||
baseURL: server.URL, | ||
}, | ||
} | ||
|
||
// update default transport | ||
OriginalTransport := http.DefaultTransport | ||
http.DefaultTransport = http.DefaultClient.Transport | ||
|
||
defer func() { | ||
http.DefaultClient = originalClient | ||
http.DefaultTransport = OriginalTransport | ||
}() | ||
|
||
tests := []struct { | ||
name string | ||
action string | ||
want bool | ||
}{ | ||
{ | ||
name: "immutable action - 1", | ||
action: "actions/[email protected]", | ||
want: true, | ||
}, | ||
{ | ||
name: "immutable action - 2", | ||
action: "step-security/[email protected]", | ||
want: true, | ||
}, | ||
{ | ||
name: "non immutable action(valid action)", | ||
action: "sailikhith-stepsecurity/[email protected]", | ||
want: false, | ||
}, | ||
{ | ||
name: "non immutable action(invalid action)", | ||
action: "sailikhith-stepsecurity/[email protected]", | ||
want: false, | ||
}, | ||
{ | ||
name: " action with release tag doesn't exist", | ||
action: "actions/[email protected]", | ||
want: false, | ||
}, | ||
{ | ||
name: "invalid action format", | ||
action: "invalid-format", | ||
want: false, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
|
||
got := IsImmutableAction(tt.action) | ||
if got != tt.want { | ||
t.Errorf("isImmutableAction() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func readHttpResponseForAction(t *testing.T, actionPath string) []byte { | ||
// remove v2 prefix from action path | ||
actionPath = strings.TrimPrefix(actionPath, "/v2/") | ||
|
||
fileName := strings.ReplaceAll(actionPath, "/", "-") + ".json" | ||
testFilesDir := "../../../testfiles/pinactions/immutableActionResponses/" | ||
respFilePath := filepath.Join(testFilesDir, fileName) | ||
|
||
resp, err := ioutil.ReadFile(respFilePath) | ||
if err != nil { | ||
t.Fatalf("error reading test file:%v", err) | ||
} | ||
|
||
return resp | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.