Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/tool_usage_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ This repo is currently migrating all checks from a slower `tox`-based framework,
|`black`| Runs `black` checks. | `azpysdk black .` |
|`verifytypes`| Runs `verifytypes` checks. | `azpysdk verifytypes .` |
|`ruff`| Runs `ruff` checks. | `azpysdk ruff .` |
|`bandit`| Runs `bandit` checks, which detect common security issues. | `azpysdk bandit .` |
|`verifywhl`| Verifies that the root directory in whl is azure, and verifies manifest so that all directories in source are included in sdist. | `azpysdk verifywhl .` |
|`verifysdist`| Verify directories included in sdist and contents in manifest file. Also ensures that py.typed configuration is correct within the setup.py. | `azpysdk verifysdist .` |
|`verify_keywords`| Verify that the keyword 'azure sdk' is present in the targeted package's keywords. | `azpysdk verify_keywords .` |
Expand Down
80 changes: 80 additions & 0 deletions eng/tools/azure-sdk-tools/azpysdk/bandit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import argparse
import os
import sys
from typing import Optional, List
import subprocess
from subprocess import check_call, CalledProcessError

from .Check import Check
from ci_tools.environment_exclusions import is_check_enabled
from ci_tools.variables import in_ci, set_envvar_defaults
from ci_tools.logging import logger
from ci_tools.functions import install_into_venv, get_pip_command


class bandit(Check):
def __init__(self) -> None:
super().__init__()

def register(
self, subparsers: "argparse._SubParsersAction", parent_parsers: Optional[List[argparse.ArgumentParser]] = None
) -> None:
"""Register the bandit check. The bandit check installs bandit and runs bandit against the target package to find common security issues."""
parents = parent_parsers or []
p = subparsers.add_parser(
"bandit", parents=parents, help="Run the bandit check to find common security issues for a package"
)
p.set_defaults(func=self.run)

def run(self, args: argparse.Namespace) -> int:
"""Run the bandit check command."""
logger.info("Running bandit check...")

set_envvar_defaults()
targeted = self.get_targeted_directories(args)

results: List[int] = []

for parsed in targeted:
package_dir = parsed.folder
package_name = parsed.name
executable, staging_directory = self.get_executable(args.isolate, args.command, sys.executable, package_dir)
logger.info(f"Processing {package_name} for bandit check")

self.install_dev_reqs(executable, args, package_dir)

try:
install_into_venv(executable, ["bandit"], package_dir)
except CalledProcessError as e:
logger.error(f"Failed to install bandit: {e}")
return e.returncode

# debug a pip freeze result
cmd = get_pip_command(executable) + ["freeze"]
freeze_result = subprocess.run(
cmd, cwd=package_dir, check=False, text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
)
logger.debug(f"Running pip freeze with {cmd}")
logger.debug(freeze_result.stdout)

if in_ci():
if not is_check_enabled(package_dir, "bandit"):
logger.warning(f"Bandit is disabled for {package_name}. Skipping...")
continue

try:
check_call(
[
executable,
"-m",
"bandit",
"-r",
os.path.join(package_dir, "azure"),
"-ll",
]
)
except CalledProcessError as e:
logger.error(f"{package_name} exited with error {e.returncode}")
results.append(e.returncode)

return max(results) if results else 0
2 changes: 2 additions & 0 deletions eng/tools/azure-sdk-tools/azpysdk/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from .verifytypes import verifytypes
from .verify_whl import verify_whl
from .verify_sdist import verify_sdist
from .bandit import bandit
from .verify_keywords import verify_keywords

from ci_tools.logging import configure_logging, logger
Expand Down Expand Up @@ -86,6 +87,7 @@ def build_parser() -> argparse.ArgumentParser:
verifytypes().register(subparsers, [common])
verify_sdist().register(subparsers, [common])
verify_whl().register(subparsers, [common])
bandit().register(subparsers, [common])
verify_keywords().register(subparsers, [common])

return parser
Expand Down
Loading