A flaw was found in the Ansible Automation Platform automation-controller system-job dispatcher. SystemJobTemplateLaunch.post (awx/api/views/init.py:3802-3805) calls createunifiedjob with the request's extravars directly and never invokes acceptorignorejobkwargs, so the "days" integer validator in SystemJobTemplate.acceptorignorevariables (awx/main/models/jobs.py: 1234-1245) is not applied on the launch path; createunifiedjob (awx/main/models/unifiedjobs.py: 369-400) copies the extravars dict onto the SystemJob verbatim after checking only key names. RunSystemJob.buildargs (awx/main/tasks/jobs.py:2113-2134) then appends str(days) to the awx-manage argument list without integer coercion, and RunSystemJob.writeargsfile (jobs.py: 2136-2137) writes ' '.join(args) to the ansible-runner args file, which ansible-runner re-tokenizes with shlex.split. A "days" value such as "5 --pythonpath /path" therefore splits into extra awx-manage arguments. RunSystemJob.buildexecutionenvironmentparams returns {} (jobs.py:2110-2111) and the dispatcher runs ansiblerunner.interface.run() in-process for SystemJob instances (jobs.py:773-781) — system jobs are the only unified-job class executed without receptor/podman isolation — so the injected arguments reach an uncontainerized control-plane awx-manage process running as the awx user with access to SECRETKEY, database credentials, and the receptor control socket. Django's handledefaultoptions parses global options such as --pythonpath from the argument vector and inserts the attacker-supplied directory at the front of sys.path. Only a superuser can trigger this (SystemJobTemplateAccess.canstart is decorated @checksuperuser, awx/main/access.py:1770-1773). Full code execution additionally requires a top-level module imported for the first time after handledefaultoptions; no such import exists in the current cleanupjobs / cleanupactivitystream import graph, so the issue is confirmed as argument injection with control of the process argument vector and sys.path[0], with code execution unproven.
Upstream: https://github.com/ansible/tower (awx) Affected file: awx/main/tasks/jobs.py:2136-2137 (RunSystemJob.writeargsfile — ' '.join(args), root cause); jobs.py:2113-2134 (buildargs, no int() coercion); jobs.py: 2110-2111 + 773-781 (uncontainerized in-process execution);
A flaw was found in the Ansible Automation Platform automation-controller workflow subsystem. WorkflowJobNode.ancestorartifacts (awx/main/models/workflow.py:262-266) is a JSONBlob column that the workflow task-manager fills with the raw merged setstats artifacts of every upstream node's job (geteffectiveartifacts) and, for child workflows, with the parent workflow's aggregated artifacts (seedrootancestorartifacts, workflow.py:743-753). The field is deliberately omitted from WorkflowJobNodeSerializer and Ansible's ansiblenolog flag is honored only after the raw dict has been persisted: in getjobkwargs (workflow.py:352-370) the aggregated artifacts are assigned and saved at lines 360-361, and only afterwards (lines 363-370) are the nolog keys copied into the child job's surveypasswords mask, leaving the ancestorartifacts column itself unredacted. Because the field is not wrapped in preventsearch(), the django-ansible-base FieldLookupBackend admits arbitrary contains/regex/startswith lookups against it. A principal with readrole on the WorkflowJob can issue GET /api/controller/v2/workflowjobnodes/?id=<n>&ancestorartifactscontains=<probe> and use the response count as a boolean oracle to recover the full JSON of the hidden column, including values protected with setstats nolog. In addition, because the credential-types list endpoint is readable by any authenticated user (CredentialTypeAccess.filteredqueryset returns all objects), and because a regular-expression lookup bypasses the JSONField cross-relation guard that rejects icontains, a user with no roles can reach the same column across all organizations via GET /api/controller/v2/credentialtypes/?credentialsworkflowjobnodesancestorartifacts regex=<probe> whenever a workflow node carries a prompted credential. This defeats both the serializer-level omission of the field and Ansible's nolog artifact-masking control, and enables cross-tenant recovery of secrets passed between workflow stages via setstats. This is a variant, on a previously unreported adjacent field, of the earlier Job/JobEvent artifact and stdout preventsearch gaps.
An authorization-bypass information-disclosure flaw was found in the automation-controller notification subsystem. A NotificationTemplate's notificationconfiguration field, which holds the notification's secret parameters, is correctly protected by preventsearch so it cannot be used as a target of the API's relational filter backend. However, each time a notification is sent, the controller copies the recipient parameter from the configuration verbatim into the recipients column of a new Notification row, and the Notification model's recipients, subject, and error columns are plain text fields with no preventsearch protection. For the notification backends whose recipient is itself a secret — PagerDuty (the Events-API service key), and Mattermost, RocketChat, and generic Webhook backends (incoming-webhook URLs that embed a bearer token) — the copied value is stored in clear text because those parameters are not encrypted password fields. Because the credential-types API endpoint is listable by any authenticated user regardless of roles, and the filter backend traverses object relations without enforcing per-hop access control, a user with no privileges and no organization membership can construct a filter that walks from credential types through credentials, organizations, notification templates, and notifications to the unprotected recipients field, and use the returned result count as a boolean oracle. Using case-insensitive, case-sensitive, and regular-expression match operators, the attacker recovers the exact secret value one character at a time, for organizations they have no access to. The same relation chain also exposes each notification's subject and error text. The result is cross-tenant disclosure of live notification credentials to an unprivileged user. The root cause is that a value stripped of search protection at the source is copied into a sink that lacks the same protection; the deeper contributing weakness is that the filter backend performs relation traversal without per-hop authorization.
A flaw was found in automation-controller. RunAdHocCommand.buildargs() appends the limit field as a bare positional argument instead of using the -l flag prefix as RunJob does. An attacker can set the limit field to a value beginning with a dash, which is then parsed as an ansible CLI option. The impact is currently limited to short-circuit flags such as --version and --help because the injected element displaces the required pattern positional argument.
A flaw was found in automation-controller. RunAdHocCommand.buildargs() appends the limit field as a bare positional argument instead of using the -l flag prefix as RunJob does. An attacker can set the limit field to a value beginning with a dash, which is then parsed as an ansible CLI option. The impact is currently limited to short-circuit flags such as --version and --help because the injected element displaces the required pattern positional argument.
A flaw was found in automation-controller. The LaunchConfigurationBaseSerializer used by Schedule and WorkflowJobTemplateNode does not implement ▎ validatescmbranch() to reject leading-dash values, unlike the Project, JobTemplate, and JobLaunch serializers. An attacker can set scmbranch to a value such as --upload-pack=/bin/id via the schedule or workflow node API. The injection is currently blocked by a runtime ValueError check in the task layer, but the API validation gap creates a latent risk if that defense-in-depth guard is ever refactored away.
A flaw was found in automation-controller. The LaunchConfigurationBaseSerializer used by Schedule and WorkflowJobTemplateNode does not implement ▎ validatescmbranch() to reject leading-dash values, unlike the Project, JobTemplate, and JobLaunch serializers. An attacker can set scmbranch to a value such as --upload-pack=/bin/id via the schedule or workflow node API. The injection is currently blocked by a runtime ValueError check in the task layer, but the API validation gap creates a latent risk if that defense-in-depth guard is ever refactored away.
A flaw was found in automation-controller. The notification template Jinja whitelist only inspects static Getattr AST nodes. An attacker with notification template admin privileges can bypass the whitelist using dynamic subscript expressions or conditional gating on runtime values that differ from the test-render stub. Exceptions raised during notification rendering write full Python tracebacks into the notification body, which is sent to the attacker-controlled webhook URL, leaking install paths, Python version, and source file line numbers.
A flaw was found in automation-controller. The CUSTOMVENVPATHS setting field calls os.path.exists() on user-supplied paths without restriction. A superuser can ▎ determine the existence of arbitrary absolute filesystem paths on the controller-web pod by observing 200 vs 400 responses, enabling discovery of sensitive paths such as secret key files, Kubernetes service-account tokens, and receptor sockets. This is primarily impactful in managed AAP deployments where the tenant superuser is not the infrastructure operator.
A flaw was found in automation-controller. The /api/v2/config/ endpoint returns licenseinfo including Red Hat account number, subscription ID, pool ID, SKU, support level, and instance counts to any authenticated user. The existing superuser/auditor gate only restricts projectbasedir, projectlocalpaths, and customvirtualenvs, but does not cover the licenseinfo block.
Red Hat Ansible Automation Platform provides an enterprise framework for building, deploying and managing IT automation at scale. IT Managers can provide top-down guidelines on how automation is applied to individual teams, while automation developers retain the freedom to write tasks that leverage existing knowledge without the overhead. Ansible Automation Platform makes it possible for users across an organization to share, vet, and manage automation content by means of a simple, powerful, and agentless language.Updates and fixes: automation-controller has been updated to 4.4.5 (AAP-16474) galaxy-importer has been updated to 0.4.13 (AAP-16551) fix ansible-compat dependency with ansible-lint (AAP-16393) update amazon.aws collection to 6.4.0 in ee-supported (AAP-15138)