Impact
When submitting a Job to run via a Job Button, only the model-level extras.runjob permission is checked (i.e., does the user have permission to run Jobs in general?). Object-level permissions (i.e., does the user have permission to run this specific Job?) are not enforced by the URL/view used in this case (/extras/job-button/<uuid>/run/) The effect is that a user with permissions to run even a single Job can actually run all configured JobButton Jobs.
Not all Jobs can be configured as JobButtons; only those implemented as subclasses of JobButtonReceiver can be used in this way, so this vulnerability only applies specifically to JobButtonReceiver subclasses.
Additionally, although the documentation states that both extras.runjob permission and extras.runjobbutton permission must be granted to a user in order to run Jobs via JobButton, the extras.runjobbutton permission is not actually enforced by the view code, only by the UI by disabling the button from being clicked normally. Furthermore, the extras.runjobbutton permission never prevented invoking Jobs (including JobButtonReceiver subclasses) via the normal "Job Run" UI, so after some discussion, we've decided that the extras.runjobbutton permission is redundant, and as it never achieved its stated/documented purpose, the fixes below will remove the UI check for extras.runjobbutton and all other references to the extras.runjobbutton permission, rather than adding enforcement of this previously unenforced permission.
Patches Has the problem been patched? What versions should users upgrade to?
Fix will be available in Nautobot 1.6.8 (https://github.com/nautobot/nautobot/pull/4995) and 2.1.0 (https://github.com/nautobot/nautobot/pull/4993)
Workarounds Is there a way for users to fix or remediate the vulnerability without upgrading?
Partial mitigation can be achieved by auditing JobButtonReceiver subclasses defined in the system and restricting which users are permitted to create or edit JobButton records.
References
- https://github.com/nautobot/nautobot/issues/4988 - https://github.com/nautobot/nautobot/pull/4993 - https://github.com/nautobot/nautobot/pull/4995
Impact
In Nautobot 1.x and 2.0.x, the URLs /files/get/?name=... and /files/download/?name=... are used to provide admin access to files that have been uploaded as part of a run request for a Job that has FileVar inputs. Under normal operation these files are ephemeral and are deleted once the Job in question runs.
It was reported by @kircheneer that in the default implementation used in Nautobot, as provided by django-db-file-storage, these URLs do not by default require any user authentication to access; they should instead be restricted to only users who have permissions to view Nautobot's FileProxy model instances.
Note that no URL mechanism is provided for listing or traversal of the available file name values, so in practice an unauthenticated user would have to guess names to discover arbitrary files for download, but if a user knows the file name/path value, they can access it without authenticating, so we are considering this a vulnerability.
Patches
Fixes will be included in Nautobot 1.6.7 and Nautobot 2.0.6.
Workarounds
No workaround other than applying the patches included in https://github.com/nautobot/nautobot/pull/4959/files (2.0.x) or https://github.com/nautobot/nautobot/pull/4964/files (1.6.x)
References
- https://github.com/victor-o-silva/dbfilestorage/blob/master/dbfilestorage/views.py
Impact
All users of Nautobot versions earlier than 1.6.6 or 2.0.5 are potentially affected.
Due to incorrect usage of Django's marksafe() API when rendering certain types of user-authored content, including:
- custom links - job buttons - computed fields
it is possible that users with permission to create or edit these types of content could craft a malicious payload (such as JavaScript code) that would be executed when rendering pages containing this content.
Patches Has the problem been patched? What versions should users upgrade to?
We have fixed the incorrect uses of marksafe() (generally by replacing them with appropriate use of formathtml() instead) to prevent such malicious data from being executed.
Users on Nautobot 1.6.x LTM should upgrade to v1.6.6 and users on Nautobot 2.0.x should upgrade to v2.0.5.
Workarounds Is there a way for users to fix or remediate the vulnerability without upgrading?
Appropriate object permissions can and should be applied to restrict which users are permitted to create or edit the aforementioned types of user-authored content. Other than that, there is no direct fix available.
References Are there any links users can visit to find out more?
- https://github.com/nautobot/nautobot/pull/4832 - https://github.com/nautobot/nautobot/pull/4833 - https://docs.djangoproject.com/en/3.2/ref/utils/#django.utils.html.formathtml - https://docs.djangoproject.com/en/3.2/ref/utils/#django.utils.safestring.marksafe
Impact When credentials are provided while creating an OnboardingTask they may be visible via the Job Results view under the Additional Data tab as args for the Celery Task execution. This only applies to OnboardingTasks that are created with credentials specified while on v2.0.0-2.0.2 of Nautobot Device Onboarding. This advisory does not apply earlier version or when using NAPALMUSERNAME & NAPALMPASSWORD from nautobotconfig.py
Patches v3.0.0
Workarounds None
Recommendations Delete all Job Results for any onboarding task to remove clear text credentials from database entries that were run while on v2.0.X Upgrade to v3.0.0 Rotate any exposed credential
Impact
In Nautobot 2.0.x, certain REST API endpoints, in combination with the ?depth=<N> query parameter, can expose hashed user passwords as stored in the database to any authenticated user with access to these endpoints.
The passwords are not exposed in plaintext. Nautobot 1.x is not affected by this vulnerability.
Example:
GET /api/users/permissions/?depth=1
HTTP 200 OK API-Version: 2.0 Allow: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS Content-Type: application/json Vary: Accept
json { "count": 1, "next": null, "previous": null, "results": [ { "id": "28ea85e4-5039-4389-94f1-9a3e1c787149", "objecttype": "users.objectpermission", "display": "Run Job", "url": "http://localhost:8080/api/users/permissions/28ea85e4-5039-4389-94f1-9a3e1c787149/", "naturalslug": "run-job28ea", "objecttypes": [ "extras.job" ], "name": "Run Job", "description": "", "enabled": true, "actions": [ "run", "view" ], "constraints": null, "groups": [ { "id": 1, "objecttype": "auth.group", "display": "A Group", "url": "http://localhost:8080/api/users/groups/1/", "naturalslug": "a-group1", "name": "A Group" } ], "users": [ { "id": "e73288e2-1326-4bfb-8fea-041290dd7473", "objecttype": "users.user", "display": "admin", "url": "http://localhost:8080/api/users/users/e73288e2-1326-4bfb-8fea-041290dd7473/", "naturalslug": "admine732", "password": "pbkdf2sha256$260000$jQb7hA48HYJ0MLWQgOZiBl$b72+gz6SpZiRpxceRQfT5Zv/aUac0eJ4NdBTZ8ECOow=", "lastlogin": "2023-10-18T14:19:08.780857Z", "issuperuser": true, "username": "admin", "firstname": "", "lastname": "", "email": "", "isstaff": true, "isactive": true, "datejoined": "2023-10-18T14:18:55.854023Z", "configdata": {} } ] } ] }
Note the "password" field present in the nested "users" data.
This information is not exposed during direct access to the /api/users/users/ endpoint, but can be exposed through any endpoint which contains a nested reference to User object(s) when an appropriate ?depth=<N> query parameter is specified. Known impacted endpoints include:
- /api/dcim/rack-reservations/?depth=1(or any greater depth value) - /api/extras/job-results/?depth=1 (or any greater depth value) - /api/extras/notes/?depth=1 (or any greater depth value) - /api/extras/object-changes/?depth=1 (or any greater depth value) - /api/extras/scheduled-jobs/?depth=1 (or any greater depth value) - /api/users/permissions/?depth=1 (or any greater depth value)
but this is not necessarily an exhaustive list.
Plugin REST API endpoints for any models with a foreign key to the User model may also be impacted by this issue.
The patch identified below mitigates the issue for both Nautobot core REST APIs and plugin REST APIs; no code change in plugins is required to address this issue.
Patches
Refer to https://github.com/nautobot/nautobot/pull/4692 for the patch that resolved this issue.
Workarounds
Upgrading to v2.0.3 or later, or applying the above patch, is the preferred workaround for this issue; while it could also be partially mitigated by updating permissions to deny user access to the above list of impacted REST API endpoints, that is not recommended as other endpoints may also expose this issue until patched.
References
https://github.com/nautobot/nautobot/pull/4692
Impact What kind of vulnerability is it? Who is impacted?
All users of Nautobot versions earlier than 1.5.7 are impacted.
In Nautobot 1.5.7 we have enabled sandboxed environments for the Jinja2 template engine used internally for template rendering for the following objects:
- extras.ComputedField - extras.CustomLink - extras.ExportTemplate - extras.Secret - extras.Webhook
While we are not aware of any active exploits, we have made this change as a preventative measure to protect against any potential remote code execution attacks utilizing maliciously crafted template code.
This change forces the Jinja2 template engine to use a SandboxedEnvironment on all new installations of Nautobot.
This addresses any potential unsafe code execution everywhere the helper function nautobot.utilities.utils.renderjinja2 is called. Additionally, our documentation that was previously suggesting the direct use of jinja2.Template has been revised to utilize renderjinja2.
Patches Has the problem been patched? What versions should users upgrade to?
Yes. Users should upgrade to Nautobot 1.5.7 or newer.
Workarounds Is there a way for users to fix or remediate the vulnerability without upgrading?
Enabling Sandboxed Environments
For users that are unable to upgrade to the latest release of Nautobot, you may add the following setting to your nautobotconfig.py to apply the sandbox environment enforcement:
python TEMPLATES[1]["OPTIONS"]["environment"] = "jinja2.sandbox.SandboxedEnvironment"
After applying this change, you must restart all Nautobot services, including any Celery worker processes.
Note: Nautobot specifies two template engines by default, the first being “django” for the Django built-in template engine, and the second being “jinja” for the Jinja2 template engine. This recommended setting will update the second item in the list of template engines, which is the Jinja2 engine.
Restricting Jinja2 using Access Controls
For users that are unable to immediately update their configuration such as if a Nautobot service restart is too disruptive to operations, access to provide custom Jinja2 template values may be mitigated using permissions to restrict “change” (write) actions to the affected object types listed in the first section.
Note: This solution is intended to be stopgap until you can successfully update your nautobotconfig.py or upgrade your Nautobot instance to apply the sandboxed environment enforcement.
Updating Existing App or Job Code
For Nautobot App (formerly plugin) authors or Job authors, additionally we recommend that if you have any custom code that may for example be using jinaj2.Template that you no longer use that. Instead, please always use our nautobot.utilities.utils.renderjinja2 function which will make sure that the centrally-provided Jinja2 template engine with sandboxing enforced is being utilized.
Anywhere you’ve been using this pattern:
python from jinja2 import Template
mytemplate = Template(templatecode) config = mytemplate.render(context)
We recommend that you replace it with this pattern:
python from nautobot.utilities.utils import renderjinja2 config = renderjinja2(templatecode, context)
References Are there any links users can visit to find out more?
Please see the Nautobot 1.5.7 release notes.
https://docs.nautobot.com/projects/core/en/stable/release-notes/version-1.5/#v157-2023-01-04