Authenticated users can view job names and groups they do not have authorization to view in Rundeck
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.
| Package | Affected versions | Patched versions |
|---|---|---|
org.rundeck:rundeckappMaven | >= 4.17.0, < 4.17.3 | 4.17.3 |
Affected products
1Patches
18992879036a1Merge pull request from GHSA-xvmv-4rx6-x6jx
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- github.com/advisories/GHSA-xvmv-4rx6-x6jxghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-47112ghsaADVISORY
- github.com/rundeck/rundeck/commit/8992879036a1ddacfca78559d823be0424796e7eghsaWEB
- github.com/rundeck/rundeck/security/advisories/GHSA-xvmv-4rx6-x6jxghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.