Closed samwmarsh closed 2 months ago
It's not "broken", just enforcing a BytesIO object instead of a StringIO object to be passed in. Passing files to the API as StringIO objects creates a lot of potential issues depending on how the files are formatted (ASCII vs UTF-8, CR vs CR/LF, etc.). While we aren't enforcing anything specific between BytesIO vs StringIO, the underlying requests and urllib3 libraries started enforcing that a while ago, and was likely surfaced when we addressed a bug in how the files API was handled and refactored it to use the appropriate multi-part encoder:
https://github.com/tenable/pyTenable/blob/master/tenable/sc/files.py
I'd suggest the following changes (below). The example uses a package called typer to wrap the function into a command-line script as well, however isn't necessary.
I would also suggest that to move away from session auth and move toward API Keys for integrations, as token auth for API interactions with Security Center has been deprecated for some time and is only working thanks to some backwards compatibility with the current authentication mechanisms, however is no longer guaranteed.
import os
import typer
from pathlib import path
from tenable.sc import TenableSC
# You should use API Keys, not Username and password. The SDK will
# automatically use the following env vars:
# TSC_ACCESS_KEY=""
# TSC_SECRET_KEY=""
# TSC_URL="https://nessusmgr"
def update_credentials(public_key: Path,
private_key: Path,
cred_id: int,
username: str,
escalation_passwd: str,
) -> Dict:
"""
Updates the credentials with the specified details.
Args:
public_key (Path): The location of the public key file.
private_key (Path): The location of the private key file.
cred_id (int): The credential id to update.
username (str): The username of the credential.
escalation_passwd (str): The escalation password of the credential.
"""
tsc = TenableSC()
with public_key.open('rb') as pubkey, private_key.open('rb') as privkey:
resp = tsc.credentials.edit(cred_id,
private_key=privkey,
public_key=pubkey,
privilege_escalation='sudo',
escalation_password=escalation_passwd,
username=username
)
return resp
if __name__ == '__main__':
typer.run(update_credentials)
Thanks @SteveMcGrath, really good to know, will look to implement this
Describe the bug We've noticed one of our pipelines for editing a credential begin to fail. This works if we pin to 1.4.22 so must have been introduced in 1.5.0.
To Reproduce
This returns a 400,
It's possible to get this to not return a 400 error by adding
,'rb'
inside the open() for both key objects, however this wasn't the case prior to the 1.5.0 release.Expected behavior The credential should update with the new key pair and escalation password.