@@ -3,6 +3,7 @@ package cli
33import (
44 "fmt"
55 "os"
6+ "regexp"
67 "strings"
78
89 "github.com/jfrog/jfrog-cli-core/v2/common/cliutils"
@@ -229,15 +230,34 @@ func getFlagValueAsString(c *components.Context, flag components.Flag) string {
229230 if ! isFlagSetAndNotDefault (c , flag ) {
230231 return ""
231232 }
233+ flagName := flag .GetName ()
232234 if _ , ok := flag .(components.StringFlag ); ok {
233- return c .GetStringFlagValue (flag . GetName ( ))
235+ return MaskSensitiveData ( flagName , c .GetStringFlagValue (flagName ))
234236 }
235237 if _ , ok := flag .(components.BoolFlag ); ok {
236- return fmt .Sprintf ("%t" , c .GetBoolFlagValue (flag . GetName () ))
238+ return fmt .Sprintf ("%t" , c .GetBoolFlagValue (flagName ))
237239 }
238240 return ""
239241}
240242
243+ func MaskSensitiveData (flagName , flagValue string ) (masked string ) {
244+ // Mask url if required
245+ if strings .Contains (strings .ToLower (flagName ), "url" ) {
246+ // Regex to match credentials in URL: http(s)://username:password@host...
247+ re := regexp .MustCompile (`(https?://)([^:/\s]+):([^@/\s]+)@` )
248+ masked = re .ReplaceAllString (flagValue , `${1}${2}:****@` )
249+ return masked
250+ }
251+ // Mask password, token, key, passphrase flags
252+ lowerFlagName := strings .ToLower (flagName )
253+ if strings .Contains (lowerFlagName , "password" ) || strings .Contains (lowerFlagName , "passphrase" ) ||
254+ strings .Contains (lowerFlagName , "token" ) || strings .Contains (lowerFlagName , "key" ) {
255+ return "****"
256+ }
257+ // Return original input if no masking required
258+ return flagValue
259+ }
260+
241261func shouldIncludeSbom (c * components.Context , format outputFormat.OutputFormat ) bool {
242262 // Make sure include SBOM is only set if the output format supports it
243263 includeSbom := c .GetBoolFlagValue (flags .Sbom )
0 commit comments