diff --git a/Dockerfile b/Dockerfile index 1d9acc07..0b6c483c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ # and "Missing User Instruction" since 2ms container is stopped after scan # Builder image -FROM checkmarx/go:1.25.3-r0-b47cbbc1194cd0@sha256:b47cbbc1194cd0d801fe7739fca12091d610117b0d30c32b52fc900217a0821a AS builder +FROM checkmarx/go:1.25.7-r0-b270bc965b34b4@sha256:b270bc965b34b4ffec624413bc1f1830c58c0abb142580ca76d42116b3b06764 AS builder WORKDIR /app @@ -20,7 +20,7 @@ COPY . . RUN GOOS=linux GOARCH=amd64 go build -buildvcs=false -ldflags="-s -w" -a -o /app/2ms . # Runtime image -FROM checkmarx/git:2.49.0-r2-d7ebbe7c56dc47@sha256:d7ebbe7c56dc478c08aba611c35b30689090d28605d83130ce4d1e15a84f0389 +FROM checkmarx/git:2.53.0-r0-dadf19ec31d471@sha256:dadf19ec31d4711eeace2763e89511693b36ba0ea5c9e12a763978b4b29ddba0 WORKDIR /app diff --git a/README.md b/README.md index f80975ee..4d2087b2 100644 --- a/README.md +++ b/README.md @@ -372,7 +372,10 @@ Other fields are optional and can be seen in the example bellow of a file with a allowLists: # allowed values to ignore if matched - description: Allowlist for Custom Rule matchCondition: OR # Can be AND or OR. determines whether all criteria in the allowList must match. Defaults to OR if not specified - regexTarget: match - # Can be match or line. Determines whether the regexes in allowList are tested against the rule.Regex match or the full line being scanned. Defaults to "match" if not specified + regexTarget: match # Specifies what to test allowList regexes against. Options: 'match', 'line', or empty/omitted. + # - 'match': test against the full rule.Regex match + # - 'line': test against the entire line where the secret was found + # - empty/omitted: test against the secret itself (which is the first capture group from rule.Regex, or the group specified by rule.secretGroup if defined) regexes: # allowed regex patterns - (?i)(?:access(?:ibility|or)|access[_.-]?id|random[_.-]?access|api[_.-]?(?:id|name|version)|rapid|capital|[a-z0-9-]*?api[a-z0-9-]*?:jar:|author|X-MS-Exchange-Organization-Auth|Authentication-Results|(?:credentials?[_.-]?id|withCredentials)|(?:25[0-5]|2[0-4]\d|1?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|1?\d?\d)){3}|(?:bucket|foreign|hot|idx|natural|primary|pub(?:lic)?|schema|sequence)[_.-]?key|(?:turkey)|key[_.-]?(?:alias|board|code|frame|id|length|mesh|name|pair|press(?:ed)?|ring|selector|signature|size|stone|storetype|word|up|down|left|right)|KeyVault(?:[A-Za-z]*?(?:Administrator|Reader|Contributor|Owner|Operator|User|Officer))\s*[:=]\s*['"]?[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}['"]?|key[_.-]?vault[_.-]?(?:id|name)|keyVaultToStoreSecrets|key(?:store|tab)[_.-]?(?:file|path)|issuerkeyhash|(?-i:[DdMm]onkey|[DM]ONKEY)|keying|(?:secret)[_.-]?(?:length|name|size)|UserSecretsId|(?:csrf)[_.-]?token|(?:io\.jsonwebtoken[ \t]?:[ diff --git a/engine/validation/alibaba.go b/engine/validation/alibaba.go index 228a00e6..a44a7f2f 100644 --- a/engine/validation/alibaba.go +++ b/engine/validation/alibaba.go @@ -69,6 +69,7 @@ func alibabaRequest(accessKey, secretKey string) (secrets.ValidationResult, erro req.URL.RawQuery = params.Encode() client := &http.Client{} + // #nosec G704 -- URL is hardcoded to Alibaba API, only query params contain credentials being validated resp, err := client.Do(req) if err != nil { return secrets.UnknownResult, err diff --git a/engine/validation/client.go b/engine/validation/client.go index cb479115..839bfbdd 100644 --- a/engine/validation/client.go +++ b/engine/validation/client.go @@ -14,6 +14,7 @@ func sendValidationRequest(endpoint, authorization string) (*http.Response, erro // TODO: do not recreate this client for each request client := &http.Client{} + // #nosec G704 -- URL is hardcoded in both github and gitlab uses, only query params contain credentials being validated resp, err := client.Do(req) if err != nil { return nil, err diff --git a/engine/validation/gcp.go b/engine/validation/gcp.go index 891090fc..53298da5 100644 --- a/engine/validation/gcp.go +++ b/engine/validation/gcp.go @@ -31,8 +31,8 @@ func validateGCP(s *secrets.Secret) (secrets.ValidationResult, string) { log.Warn().Err(err).Msg("Failed to validate secret") return secrets.UnknownResult, "" } - client := &http.Client{} + // #nosec G704 -- URL is hardcoded to GCP API, only query params contain credentials being validated resp, err := client.Do(req) if err != nil { log.Warn().Err(err).Msg("Failed to validate secret") diff --git a/go.mod b/go.mod index 79253d05..eabb5604 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/checkmarx/2ms/v5 -go 1.25.6 +go 1.25.7 replace ( golang.org/x/oauth2 => golang.org/x/oauth2 v0.30.0 diff --git a/lib/utils/http.go b/lib/utils/http.go index a7d7a256..2c1e51e4 100644 --- a/lib/utils/http.go +++ b/lib/utils/http.go @@ -40,6 +40,7 @@ func HttpRequest(method, url string, authorization IAuthorizationHeader, retry R // TODO: do not recreate this client for each request client := &http.Client{} + // #nosec G704 -- URL is intentionally user-provided for plugin API calls to external services response, err := client.Do(request) if err != nil { return nil, response, fmt.Errorf("unable to send http request %w", err) diff --git a/plugins/confluence_client.go b/plugins/confluence_client.go index 71fe9847..e9c4c017 100644 --- a/plugins/confluence_client.go +++ b/plugins/confluence_client.go @@ -190,6 +190,7 @@ func (c *httpConfluenceClient) discoverCloudID(ctx context.Context) (string, err if err != nil { return "", fmt.Errorf("build tenant_info request: %w", err) } + // #nosec G704 -- URL is intentionally user-provided for plugin API calls to external services resp, err := c.httpClient.Do(req) if err != nil { return "", ErrBaseURLInvalidOrUnreachable @@ -475,6 +476,7 @@ func (c *httpConfluenceClient) getJSON(ctx context.Context, reqURL string) ([]by } req.Header.Set("Accept", "application/json") + // #nosec G704 -- URL is intentionally user-provided for plugin API calls to external services resp, err := c.httpClient.Do(req) if err != nil { return nil, nil, fmt.Errorf("http get: %w", err) @@ -525,7 +527,7 @@ func (c *httpConfluenceClient) getJSONStream(ctx context.Context, reqURL string) req.SetBasicAuth(c.username, c.token) } req.Header.Set("Accept", "application/json") - + // #nosec G704 -- URL is intentionally user-provided for plugin API calls to external services resp, err := c.httpClient.Do(req) if err != nil { return nil, nil, fmt.Errorf("http get: %w", err)