diff --git a/docker/Dockerfile b/docker/Dockerfile index ef29059e89..9504e7a059 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,5 +1,5 @@ FROM amazoncorretto:25-al2023 -RUN yum install -y procps-ng shadow-utils which +RUN yum install -y procps-ng shadow-utils which util-linux ENV NXF_HOME=/.nextflow ARG TARGETPLATFORM=linux/amd64 diff --git a/docker/entry.sh b/docker/entry.sh index 1dd22e734f..1921628f20 100755 --- a/docker/entry.sh +++ b/docker/entry.sh @@ -25,8 +25,8 @@ # with such ID and adds it to the `docker` group, then assigns the docker # socket file ownership to that user. # -# Finally it switches the `nextflow` user using the `su` command and -# executes the original target command line. +# Finally it switches to the `nextflow` user and executes the original +# target command line. # # authors: # Paolo Di Tommaso @@ -36,9 +36,6 @@ # enable debugging [[ "$NXF_DEBUG_ENTRY" ]] && set -x -# wrap cli args with single quote to avoid wildcard expansion -cli=''; for x in "$@"; do cli+="'$x' "; done - # the NXF_USRMAP hold the user ID in the host environment if [[ "$NXF_USRMAP" ]]; then # create a `nextflow` user with the provided ID @@ -50,13 +47,10 @@ useradd -u "$NXF_USRMAP" -G docker -s /bin/bash nextflow chown nextflow /var/run/docker.sock chown -R nextflow /.nextflow -# finally run the target command with `nextflow` user -su nextflow << EOF -[[ "$NXF_DEBUG_ENTRY" ]] && set -x -exec bash -c "$cli" -EOF +# run the target command as `nextflow`, passing argv through (no shell) +exec runuser -u nextflow -- "$@" # otherwise just execute the command else -exec bash -c "$cli" +exec "$@" fi diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a9db11550c..dbe66e1d66 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionSha256Sum=9c0f7faeeb306cb14e4279a3e084ca6b596894089a0638e68a07c945a32c9e14 distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip networkTimeout=10000 retries=0 diff --git a/modules/nextflow/src/main/groovy/nextflow/util/RemoteSession.groovy b/modules/nextflow/src/main/groovy/nextflow/util/RemoteSession.groovy index 4cd4fcccd6..56c4d31234 100644 --- a/modules/nextflow/src/main/groovy/nextflow/util/RemoteSession.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/util/RemoteSession.groovy @@ -149,6 +149,8 @@ class RemoteSession implements Serializable, Closeable { while( (entry=zip.getNextEntry()) != null ) { def file = target.resolve(entry.getName()); + if( !file.normalize().startsWith(target.normalize()) ) + throw new IllegalArgumentException("Unsafe zip entry path: ${entry.getName()}") if(entry.isDirectory()) { continue } diff --git a/plugins/nf-tower/src/main/io/seqera/tower/plugin/TowerXAuth.groovy b/plugins/nf-tower/src/main/io/seqera/tower/plugin/TowerXAuth.groovy index fcac0ae45d..500fa8385f 100644 --- a/plugins/nf-tower/src/main/io/seqera/tower/plugin/TowerXAuth.groovy +++ b/plugins/nf-tower/src/main/io/seqera/tower/plugin/TowerXAuth.groovy @@ -27,6 +27,7 @@ import groovy.util.logging.Slf4j import io.seqera.http.HxProxyConfig import nextflow.file.http.XAuthProvider import nextflow.util.ProxyConfig +import nextflow.util.StringUtils /** * Implements Tower authentication strategy for resources accessed @@ -96,16 +97,18 @@ class TowerXAuth implements XAuthProvider { .build() final resp = httpClient.send(req, HttpResponse.BodyHandlers.ofString()) - log.debug "Refresh cookie response: [${resp.statusCode()}] ${resp.body()}" - if( resp.statusCode() != 200 ) + if( resp.statusCode() != 200 ) { + log.debug "Refresh cookie response: [${resp.statusCode()}] ${resp.body()}" return false + } + log.debug "Refresh cookie response: [${resp.statusCode()}]" final authCookie = getCookie('JWT') final refreshCookie = getCookie('JWT_REFRESH_TOKEN') // set the new bearer token in the current client session if( authCookie?.value ) { - log.trace "Updating http client bearer token=$authCookie.value" + log.trace "Updating http client bearer token=${StringUtils.redact(authCookie.value)}" accessToken = authCookie.value } else { @@ -114,7 +117,7 @@ class TowerXAuth implements XAuthProvider { // set the new refresh token if( refreshCookie?.value ) { - log.trace "Updating http client refresh token=$refreshCookie.value" + log.trace "Updating http client refresh token=${StringUtils.redact(refreshCookie.value)}" refreshToken = refreshCookie.value } else {