nextflow-io / nextflow-io/nextflow

Feature request: sanitizing user-provided params

Open
#4,878 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

lang/processes
Dominant language
Groovy
Stars
3.5k
Forks
811
Avg merge
2d 11h
Merged PRs (30d)
61

Description

Sanitizing user-provided params

In Nextflow as it currently stands, any param that is used in a process gets copied to .command.sh without validation. Although filenames are properly processed (eg spaces are correctly quoted by backslashes), string parameters are not; instead, they are inserted into process script verbatim. This can both break processes if parameters contain characters meaningful for Bash (even non-quoted spaces break processes written without proper precautions) and, more importantly, allow executing arbitrary code at the machine where Nextflow runs.

Issue demonstration

This POC pipeline is enough to demonstrate:

./main.nf:

  params.param1 = 'lorem ipsum'
  params.param2 = 'dolor sit amet'
  
  process PASS_UNSCREENED{
      output: stdout
      """
      echo "Not screened"
      ${moduleDir}/check_params.py -f ${params.param1} -o ${params.param2}
      """
  }
  
  process PASS_SCREENED{
      output: stdout
      """
      echo "Screened"
      ${moduleDir}/check_params.py -f '${params.param1}' -o '${params.param2}'
      """
  }
  
  workflow{
      PASS_UNSCREENED | view()
  
      PASS_SCREENED | view()
  }

check_params.py:

  #! /usr/bin/env python3
  from argparse import ArgumentParser
  parser = ArgumentParser()
  parser.add_argument('-f', nargs='*', type=str)
  parser.add_argument('-o', type=str)
  args = parser.parse_args()
  print('Multivalue param:')
  for i in args.f:
    print(i)
  print('Single value param:')
  print(args.o)

Unsurprisingly, wrapping ${params.param_name} calls in single quotes prevents Bash expansion and the most basic form of code injection:

inject

However, it is not enough to protect from intentionally created malicious input. Something as simple as --param1 "asd ' && echo $Path '" will successfully execute the payload. Since parameters are typically provided by end users (or upstream pipelines) and are out of Nextflow administrators' control, this presents a security risk.

Proposed solution

There could be an option for checking all user-provided parameters for whether they are safe to use with Bash. Something like nextflow run main.nf -params-file user_supplied.json -sanitize -replace-with '_' that would allow either exiting immediately if forbidden characters are encountered in params, or replacing all such characters with, for example, an underscore. Since it is possible that existing pipelines rely on using the now-forbidden characters in some of the parameters, this has to be optional.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the POC entry point in main.nf and the parameter handling exercised by the nextflow run main.nf -params-file command; check how values reach the generated .command.sh. Compare the unscreened and quoted examples using check_params.py, then define and test the optional reject-or-replace behavior for unsafe parameter characters without breaking existing pipelines.

Written by the indexing model from the issue text.

Assessment

Tech stack
bash, groovy, python
Domain
cli, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.