From 5bf4d8599d144e2eef50143cf428ea0598561ba1 Mon Sep 17 00:00:00 2001 From: ankurjuneja Date: Sun, 28 Jun 2026 22:44:10 -0700 Subject: [PATCH 1/3] nextflow security fixes --- .../org/labkey/nextflow/NextFlowController.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/nextflow/src/org/labkey/nextflow/NextFlowController.java b/nextflow/src/org/labkey/nextflow/NextFlowController.java index f3adaef1..df55766a 100644 --- a/nextflow/src/org/labkey/nextflow/NextFlowController.java +++ b/nextflow/src/org/labkey/nextflow/NextFlowController.java @@ -223,6 +223,10 @@ public ModelAndView getView(EnabledForm form, boolean reshow, BindException erro @Override public boolean handlePost(EnabledForm form, BindException errors) { + if (!getUser().hasSiteAdminPermission()) + { + throw new UnauthorizedException(); + } NextFlowManager.get().saveEnabledState(getContainer(), form.getEnabled()); return true; } @@ -257,6 +261,10 @@ public void validateCommand(AnalyzeForm o, Errors errors) { errors.reject(ERROR_MSG, "NextFlow is not enabled"); } + else if (NextFlowManager.get().getConfiguration() == null) + { + errors.reject(ERROR_MSG, "NextFlow has not been configured"); + } } @Override @@ -278,7 +286,7 @@ public ModelAndView getView(AnalyzeForm o, boolean b, BindException errors) } NextFlowConfiguration config = NextFlowManager.get().getConfiguration(); - if (config.getNextFlowConfigFilePath() != null) + if (config != null && config.getNextFlowConfigFilePath() != null) { File configDir = new File(config.getNextFlowConfigFilePath()); if (configDir.isDirectory()) @@ -311,6 +319,11 @@ public boolean handlePost(AnalyzeForm form, BindException errors) throws Excepti } NextFlowConfiguration config = NextFlowManager.get().getConfiguration(); + if (config == null || config.getNextFlowConfigFilePath() == null) + { + errors.reject(ERROR_MSG, "NextFlow has not been configured"); + return false; + } File configDir = new File(config.getNextFlowConfigFilePath()); File configFile = FileUtil.appendPath(configDir, Path.parse(form.getConfigFile())); if (!configFile.exists()) From 5fd01ed63d143bc9b570ff52e2af6d1753068ed6 Mon Sep 17 00:00:00 2001 From: ankurjuneja Date: Sun, 28 Jun 2026 22:54:43 -0700 Subject: [PATCH 2/3] self code review comment --- .../src/org/labkey/nextflow/NextFlowController.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/nextflow/src/org/labkey/nextflow/NextFlowController.java b/nextflow/src/org/labkey/nextflow/NextFlowController.java index df55766a..6d1b377c 100644 --- a/nextflow/src/org/labkey/nextflow/NextFlowController.java +++ b/nextflow/src/org/labkey/nextflow/NextFlowController.java @@ -45,6 +45,7 @@ import org.springframework.web.servlet.ModelAndView; import java.io.File; +import java.nio.file.InvalidPathException; import java.util.Arrays; import java.util.List; @@ -325,7 +326,17 @@ public boolean handlePost(AnalyzeForm form, BindException errors) throws Excepti return false; } File configDir = new File(config.getNextFlowConfigFilePath()); - File configFile = FileUtil.appendPath(configDir, Path.parse(form.getConfigFile())); + File configFile; + try + { + // appendPath normalizes and enforces that the resolved path stays within configDir, rejecting traversal + configFile = FileUtil.appendPath(configDir, Path.parse(form.getConfigFile())); + } + catch (InvalidPathException e) + { + errors.reject(ERROR_MSG, "Invalid config file"); + return false; + } if (!configFile.exists()) { errors.reject(ERROR_MSG, "Config file does not exist"); From 271b14cb4ddf13f09be31c5f8b352dd9311fb59e Mon Sep 17 00:00:00 2001 From: ankurjuneja Date: Mon, 29 Jun 2026 13:18:53 -0700 Subject: [PATCH 3/3] code review suggestion: validate configfile is not blank --- nextflow/src/org/labkey/nextflow/NextFlowController.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nextflow/src/org/labkey/nextflow/NextFlowController.java b/nextflow/src/org/labkey/nextflow/NextFlowController.java index 6d1b377c..25075ab2 100644 --- a/nextflow/src/org/labkey/nextflow/NextFlowController.java +++ b/nextflow/src/org/labkey/nextflow/NextFlowController.java @@ -325,6 +325,11 @@ public boolean handlePost(AnalyzeForm form, BindException errors) throws Excepti errors.reject(ERROR_MSG, "NextFlow has not been configured"); return false; } + if (StringUtils.isBlank(form.getConfigFile())) + { + errors.reject(ERROR_MSG, "No config file specified"); + return false; + } File configDir = new File(config.getNextFlowConfigFilePath()); File configFile; try