Open ericwb opened 5 years ago
Nice idea. Would it give a generic example, or try to amend and suggest the flagged line of code from the project being scanned?
@lukehinds Yeah, I was thinking Bandit would output a new field of the suggested fix. But it could also have a command line option to actually make the changes in the file automatically. Similar to what ESLint offers.
I think this is a great idea. Maybe could be added on the Issue class a new optional field.
I investigated this some. The ast includes a NodeTransformer that enables rewriting the tree. And in Python 3.9 and later, ast can do an unparse in addition to parse. So in effect, you can create a suggested fix and even automatically fix the code.
However, Python's ast is not a CST (comcrete syntax tree) and therefore doesn't include things like trailing comments. The undesirable effect is that suggested code wouldn't retain these elements.
We could look at switching Bandit to use something like libcst. But this would be a major change to the base parsing mechanism of Bandit and adds another dependency.
Here's a short example using libcst to auto-correct a problem in code, all while preserving the comments.
import libcst as cst
code = '''
from paramiko import client
class foo:
def test(self):
if True:
ssh_client = client.SSHClient()
# test test test
ssh_client.set_missing_host_key_policy(client.AutoAddPolicy) # comment test
'''
class PolicyFix(cst.CSTTransformer):
def leave_Call(self, original_node: cst.Call, updated_node: cst.Call) -> cst.Call:
if (cst.ensure_type(original_node.func, cst.Attribute)
and original_node.func.attr.value == "set_missing_host_key_policy"
and original_node.args[0].value.attr.value == "AutoAddPolicy"
):
return updated_node.with_deep_changes(
old_node=updated_node.args[0].value,
attr=cst.Name("RejectPolicy")
)
else:
return original_node
tree = cst.parse_module(code)
new_tree = tree.visit(PolicyFix())
print(new_tree.code)
Is your feature request related to a problem? Please describe. It's nice that Bandit flags lines of code that require attention, but it would be even more valuable to suggest fixes for problem lines. Other linters such as ESLint provide a --fix command line option to automatically fix problems it finds.
See https://eslint.org/docs/user-guide/command-line-interface#options
Describe the solution you'd like A start might be that Bandit includes another field in the output data called suggested fix or something. It would include the modified line of code it found to be wrong with the proposed solution.
For example, if the yaml_load plugin found a case of
yaml.load()
, it would replace withyaml.load(Loader=yaml.SafeLoader)
.Each plugin would need to handle fixes it could address.
Describe alternatives you've considered n/a
Additional context https://developer.ibm.com/articles/auto-fix-and-format-your-javascript-with-eslint/