VYPR
Moderate severityNVD Advisory· Published Nov 16, 2023· Updated Aug 29, 2024

Authenticated users can view job names and groups they do not have authorization to view in Rundeck

CVE-2023-47112

Description

Rundeck is an open source automation service with a web console, command line tools and a WebAPI. In affected versions access to two URLs used in both Rundeck Open Source and Process Automation products could allow authenticated users to access the URL path, which provides a list of job names and groups for any project, without the necessary authorization checks. The output of these endpoints only exposes the name of job groups and the jobs contained within the specified project. The output is read-only and the access does not allow changes to the information. This vulnerability has been patched in version 4.17.3. Users are advised to upgrade. Users unable to upgrade may block access to the two URLs used in either Rundeck Open Source or Process Automation products at a load balancer level.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.rundeck:rundeckappMaven
>= 4.17.0, < 4.17.34.17.3

Affected products

1

Patches

1
8992879036a1

Merge pull request from GHSA-xvmv-4rx6-x6jx

https://github.com/rundeck/rundeckGreg SchuelerNov 7, 2023via ghsa
2 files changed · +0 107
  • rundeckapp/grails-app/controllers/rundeckapp/UrlMappings.groovy+0 6 modified
    @@ -48,12 +48,6 @@ class UrlMappings {
             }
             "/api/$api_version/incubator/executions/$id"(controller: 'rdExecution', action: "listForJob")
     
    -        "/api/$api_version/incubator/job/$id?"(controller: 'rdJob') {
    -            action = [GET: 'get', POST: 'save', DELETE: 'delete']
    -        }
    -
    -        "/api/$api_version/incubator/jobs"(controller: 'rdJob', action: "query")
    -
             "/api/$api_version/job/$id"(controller: 'scheduledExecution') {
                 action = [GET: 'apiJobExport', DELETE: 'apiJobDelete']
             }
    
  • rundeckapp/grails-app/controllers/rundeck/controllers/RdJobController.groovy+0 101 removed
    @@ -1,101 +0,0 @@
    -package rundeck.controllers
    -
    -import com.dtolabs.rundeck.core.authorization.AuthContext
    -import com.fasterxml.jackson.annotation.JsonInclude
    -import com.fasterxml.jackson.databind.ObjectMapper
    -import com.fasterxml.jackson.databind.exc.InvalidFormatException
    -import groovy.transform.CompileStatic
    -import rundeck.data.validation.exception.DataValidationException
    -import org.rundeck.core.auth.AuthConstants
    -import org.rundeck.core.auth.access.UnauthorizedAccess
    -import org.rundeck.core.auth.app.RundeckAccess
    -import org.rundeck.core.auth.web.RdAuthorizeJob
    -import rundeck.data.job.RdJob
    -import rundeck.data.validation.ValidationResponse
    -import org.springframework.context.MessageSource
    -import rundeck.data.job.query.RdJobQueryInput
    -import rundeck.services.RdJobService
    -
    -import javax.persistence.EntityNotFoundException
    -import javax.security.auth.Subject
    -
    -class RdJobController extends ControllerBase {
    -
    -    MessageSource messageSource
    -    RdJobService rdJobService
    -    ObjectMapper mapper = new ObjectMapper()
    -
    -    RdJobController() {
    -        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)
    -    }
    -
    -    def editpage() {}
    -
    -    @RdAuthorizeJob(RundeckAccess.Job.AUTH_APP_READ_OR_VIEW)
    -    def get() {
    -        response.contentType = "application/json;utf-8"
    -        def job = rdJobService.getJobByIdOrUuid(params.id)
    -        if(job) {
    -            render mapper.writeValueAsString(job)
    -        } else {
    -            response.status = 404
    -        }
    -
    -    }
    -
    -    @CompileStatic
    -    def save() {
    -        response.contentType = "application/json;utf-8"
    -
    -        try {
    -            RdJob job = mapper.readValue(request.inputStream, RdJob)
    -            AuthContext authContext = rundeckAuthContextProcessor.getAuthContextForSubject((Subject)session.getAttribute("subject"))
    -            if (!rundeckAuthContextProcessor.authorizeProjectResourceAny(
    -                    authContext,
    -                    AuthConstants.RESOURCE_TYPE_JOB,
    -                    [AuthConstants.ACTION_CREATE, AuthConstants.ACTION_UPDATE, AuthConstants.ACTION_ADMIN, AuthConstants.ACTION_APP_ADMIN],
    -                    job.project
    -            )) {
    -                throw new UnauthorizedAccess("create or update", AuthConstants.TYPE_JOB, job.uuid)
    -            }
    -            render mapper.writeValueAsString(rdJobService.saveJob(job))
    -        } catch(InvalidFormatException ife) {
    -            response.status = 400
    -            render mapper.writeValueAsString([error: ife.message])
    -        } catch(DataValidationException dvex) {
    -            response.status = 400
    -            render mapper.writeValueAsString(new ValidationResponse().createFrom(messageSource, dvex.target))
    -        }
    -
    -    }
    -
    -    def delete() {
    -        response.contentType = "application/json;utf-8"
    -        def job = rdJobService.getJobByUuid(params.id)
    -        if(!job) {
    -            response.status = 404
    -            return
    -        }
    -        try {
    -            AuthContext authContext = rundeckAuthContextProcessor.getAuthContextForSubject((Subject)session.getAttribute("subject"))
    -            if (!rundeckAuthContextProcessor.authorizeProjectResourceAny(
    -                    authContext,
    -                    AuthConstants.RESOURCE_TYPE_JOB,
    -                    [AuthConstants.ACTION_DELETE, AuthConstants.ACTION_ADMIN, AuthConstants.ACTION_APP_ADMIN],
    -                    job.project
    -            )) {
    -                throw new UnauthorizedAccess(AuthConstants.ACTION_DELETE, AuthConstants.TYPE_JOB, job.uuid)
    -            }
    -            render mapper.writeValueAsString(rdJobService.delete(job.uuid))
    -        } catch(EntityNotFoundException ex) {
    -            response.status = 404
    -            render mapper.writeValueAsString(["err":ex.message])
    -        }
    -    }
    -
    -    def query(RdJobQueryInput qry) {
    -        response.contentType = "application/json;utf-8"
    -        qry.inputParamMap = params
    -        render mapper.writeValueAsString(rdJobService.listJobs(qry))
    -    }
    -}
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.