From c2ea9cc40319675766808d3136cb452c2b7f32d8 Mon Sep 17 00:00:00 2001 From: Madhur Jain <87946372+jmadhur87@users.noreply.github.com> Date: Mon, 24 Aug 2026 18:19:35 +0530 Subject: [PATCH 1/2] chore: Update int to Long_Int (#1081) --- .../cli/cmd/AbstractSSCIssueTemplateUpdateCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue_template/cli/cmd/AbstractSSCIssueTemplateUpdateCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue_template/cli/cmd/AbstractSSCIssueTemplateUpdateCommand.java index 1ec99fa9144..ac8a70ae2bb 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue_template/cli/cmd/AbstractSSCIssueTemplateUpdateCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue_template/cli/cmd/AbstractSSCIssueTemplateUpdateCommand.java @@ -16,7 +16,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.IntNode; +import com.fasterxml.jackson.databind.node.LongNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fortify.cli.common.json.JsonHelper; import com.fortify.cli.common.output.transform.IActionCommandResultSupplier; @@ -63,7 +63,7 @@ protected ArrayNode getCustomTagIds(UnirestInstance unirest, SSCIssueTemplateDes currentTags, addTagsMixin.getTagSpecs(), rmTagsMixin.getTagSpecs() - ).map(tag -> new IntNode(Integer.valueOf(tag.getId()))).collect(JsonHelper.arrayNodeCollector()); + ).map(tag -> new LongNode(Long.valueOf(tag.getId()))).collect(JsonHelper.arrayNodeCollector()); } @Override From 03ec032ad5ee87518ae2e6da2cb74ca770b42b6f Mon Sep 17 00:00:00 2001 From: mjain6 Date: Wed, 23 Sep 2026 10:34:00 +0530 Subject: [PATCH 2/2] Fix credential masking and add path traversal validation --- .../mixin/AviatorAdminPrivateKeyResolverMixin.java | 3 +++ .../cli/mixin/AviatorUserTokenResolverMixin.java | 2 +- .../token/cli/cmd/AviatorTokenDeleteCommand.java | 2 +- .../token/cli/cmd/AviatorTokenRevokeCommand.java | 2 +- .../_common/helper/ToolInstallationDescriptor.java | 12 ++++++++++++ 5 files changed, 18 insertions(+), 3 deletions(-) diff --git a/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/_common/config/admin/cli/mixin/AviatorAdminPrivateKeyResolverMixin.java b/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/_common/config/admin/cli/mixin/AviatorAdminPrivateKeyResolverMixin.java index 9abe21d0adc..24ca56d679c 100644 --- a/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/_common/config/admin/cli/mixin/AviatorAdminPrivateKeyResolverMixin.java +++ b/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/_common/config/admin/cli/mixin/AviatorAdminPrivateKeyResolverMixin.java @@ -16,6 +16,8 @@ import com.fortify.cli.common.cli.mixin.CommonOptionMixins.AbstractTextResolverMixin; import com.fortify.cli.common.exception.FcliSimpleException; +import com.fortify.cli.common.log.LogSensitivityLevel; +import com.fortify.cli.common.log.MaskValue; import lombok.Getter; import picocli.CommandLine.Option; @@ -23,6 +25,7 @@ /** * Mixin for resolving an Aviator admin private key from various sources (file, string, environment variable). */ +@MaskValue(sensitivity = LogSensitivityLevel.high, description = "AVIATOR ADMIN PRIVATE KEY") public class AviatorAdminPrivateKeyResolverMixin extends AbstractTextResolverMixin { @Option(names = {"--private-key", "-p"}, descriptionKey = "fcli.aviator.admin-config.create.private-key", paramLabel = "source", required = true, order = 3) @Getter private String privateKeySource; diff --git a/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/_common/session/user/cli/mixin/AviatorUserTokenResolverMixin.java b/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/_common/session/user/cli/mixin/AviatorUserTokenResolverMixin.java index f3770830812..093156cabed 100644 --- a/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/_common/session/user/cli/mixin/AviatorUserTokenResolverMixin.java +++ b/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/_common/session/user/cli/mixin/AviatorUserTokenResolverMixin.java @@ -24,9 +24,9 @@ /** * Mixin for resolving an Aviator user token from various sources (direct string, file, URL, environment variable). */ +@MaskValue(sensitivity = LogSensitivityLevel.high, description = "AVIATOR TOKEN") public class AviatorUserTokenResolverMixin extends AbstractTextResolverMixin { @Option(names = {"--token", "-t"}, descriptionKey = "fcli.aviator.session.login.token", paramLabel = "source", required = true, order = 1) - @MaskValue(sensitivity = LogSensitivityLevel.high, description = "AVIATOR TOKEN") private String textSource; @Override diff --git a/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/token/cli/cmd/AviatorTokenDeleteCommand.java b/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/token/cli/cmd/AviatorTokenDeleteCommand.java index 933911db070..aa2aa814b24 100644 --- a/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/token/cli/cmd/AviatorTokenDeleteCommand.java +++ b/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/token/cli/cmd/AviatorTokenDeleteCommand.java @@ -72,7 +72,7 @@ private JsonNode processDeleteResponse(DeleteTokenResponse response, String toke ObjectMapper objectMapper = new ObjectMapper(); ObjectNode deleteTokenNode = objectMapper.createObjectNode(); deleteTokenNode.put("message", "Token deleted successfully"); - LOG.info("Token '{}' deleted successfully for email: {}", tokenToDelete, email); + LOG.info("Token deleted successfully for email: {}", email); return deleteTokenNode; } diff --git a/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/token/cli/cmd/AviatorTokenRevokeCommand.java b/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/token/cli/cmd/AviatorTokenRevokeCommand.java index 62ba7a25cfa..e85fc311334 100644 --- a/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/token/cli/cmd/AviatorTokenRevokeCommand.java +++ b/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/token/cli/cmd/AviatorTokenRevokeCommand.java @@ -72,7 +72,7 @@ private JsonNode processRevokeResponse(RevokeTokenResponse response, String toke ObjectMapper objectMapper = new ObjectMapper(); ObjectNode revokeTokenNode = objectMapper.createObjectNode(); revokeTokenNode.put("message", "Token successfully revoked"); - LOG.info("Token '{}' revoked successfully for email: {}", tokenToRevoke, email); + LOG.info("Token revoked successfully for email: {}", email); return revokeTokenNode; } diff --git a/fcli-core/fcli-tool/src/main/java/com/fortify/cli/tool/_common/helper/ToolInstallationDescriptor.java b/fcli-core/fcli-tool/src/main/java/com/fortify/cli/tool/_common/helper/ToolInstallationDescriptor.java index 66630c310e5..f16322c7bd9 100644 --- a/fcli-core/fcli-tool/src/main/java/com/fortify/cli/tool/_common/helper/ToolInstallationDescriptor.java +++ b/fcli-core/fcli-tool/src/main/java/com/fortify/cli/tool/_common/helper/ToolInstallationDescriptor.java @@ -28,6 +28,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.formkiq.graalvm.annotations.Reflectable; +import com.fortify.cli.common.exception.FcliSimpleException; import com.fortify.cli.common.json.JsonHelper; import com.fortify.cli.common.tool.definitions.helper.ToolDefinitionVersionDescriptor; import com.fortify.cli.common.util.FcliDataHelper; @@ -172,7 +173,17 @@ private static final Path asPath(String dir) { return StringUtils.isNotBlank(dir) ? Paths.get(dir) : null; } + private static final void validateVersionString(String version) { + if (StringUtils.isBlank(version)) { + throw new FcliSimpleException("Version string cannot be blank"); + } + if (!version.matches("[A-Za-z0-9._+-]+")) { + throw new FcliSimpleException("Invalid version string: " + version + ". Version must contain only alphanumeric characters, dots, hyphens, underscores, or plus signs."); + } + } + private static final Path getInstallDescriptorPath(String toolName, String version) { + validateVersionString(version); return getInstallDescriptorsDirPath(toolName).resolve(version); } @@ -181,6 +192,7 @@ private static final Path getInstallDescriptorsDirPath(String toolName) { } private static final Path getInstallDescriptorToolCopyPath(Path installPath, String toolName, ToolDefinitionVersionDescriptor versionDescriptor) { + validateVersionString(versionDescriptor.getVersion()); return installPath.resolve("install-descriptor").resolve(toolName).resolve(versionDescriptor.getVersion()); }