├── .bandit ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── documentation-issue-report.md │ └── feature_request.md ├── dependabot.yml └── workflows │ ├── bandit.yml │ ├── black.yml │ ├── build.yml │ ├── docs-build.yml │ ├── docs-deploy.yml │ ├── mypy.yml │ ├── publish.yml │ └── test.yml ├── .gitignore ├── .pre-commit-config.yaml ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── SECURITY.md ├── docs ├── Makefile ├── README.md ├── docs │ ├── CNAME │ ├── about-us.md │ ├── faq.md │ ├── getting-started │ │ ├── cli.md │ │ ├── cloud-services │ │ │ ├── azure-ml-notebooks.md │ │ │ ├── images │ │ │ │ ├── azure-jle-1.png │ │ │ │ ├── azure-jle-3.png │ │ │ │ ├── azure-jle-4.png │ │ │ │ ├── azure-jle-5.png │ │ │ │ ├── sm-notebook-1.png │ │ │ │ ├── sm-notebook-2.png │ │ │ │ ├── sm-notebook-3.png │ │ │ │ ├── sm-notebook-4.png │ │ │ │ ├── sm-notebook-5.png │ │ │ │ └── studio-lab-screenshot.png │ │ │ ├── index.md │ │ │ ├── sage-maker-notebook-instances.md │ │ │ ├── sage-maker-studio-lab.md │ │ │ └── sage-maker-studio.md │ │ ├── index.md │ │ └── jupyter-lab-extension.md │ ├── imgs │ │ ├── cli-help-message.png │ │ ├── focus-cell-from-issue.mp4 │ │ ├── html-scan-report.png │ │ ├── html-scan-with-errors.png │ │ ├── jle-initial-setup.png │ │ ├── jupyter-extension-example.mp4 │ │ ├── jupyter-settings.mp4 │ │ ├── open-nb-defense-panel.mp4 │ │ ├── run-scan-from-toolbar.mp4 │ │ ├── show-contextual-help-toggle.mp4 │ │ ├── show-dropdowns-toggle.mp4 │ │ └── side-panel-with-results.png │ ├── index.md │ ├── robots.txt │ ├── scan-settings │ │ ├── cli-flags.md │ │ ├── cli-settings.md │ │ ├── index.md │ │ └── jupyterlab-settings.md │ └── supported-scans │ │ ├── detecting-CVEs.md │ │ ├── detecting-PII.md │ │ ├── detecting-licenses.md │ │ ├── detecting-secrets.md │ │ └── images │ │ ├── nbd-cli-cve-results.png │ │ ├── nbd-cli-license-results.png │ │ ├── nbd-jle-cve-results.png │ │ ├── nbd-jle-license-results.png │ │ └── nbd-jle-scan-pii-found.png ├── mkdocs.yml ├── overrides │ ├── .icons │ │ ├── social-discussion.svg │ │ ├── social-github.svg │ │ ├── social-linkedin.svg │ │ └── social-slack.svg │ ├── assets │ │ ├── css │ │ │ ├── extra.css │ │ │ └── landing.css │ │ ├── fonts │ │ │ ├── SF-Pro-Display-Bold.woff │ │ │ ├── lg.svg │ │ │ ├── lg.ttf │ │ │ ├── lg.woff │ │ │ ├── sf-pro-text-bold.woff │ │ │ └── sf-pro-text-regular.woff │ │ ├── imgs │ │ │ ├── background.png │ │ │ ├── branch-bottom.svg │ │ │ ├── circle-arrow.svg │ │ │ ├── favicon.svg │ │ │ ├── feature-image-customizable.svg │ │ │ ├── feature-image-cve.svg │ │ │ ├── feature-image-jle.svg │ │ │ ├── feature-image-repository-scan.svg │ │ │ ├── footer-logo.svg │ │ │ ├── git-contributors.svg │ │ │ ├── git-created.svg │ │ │ ├── git-updated.svg │ │ │ ├── header-image.svg │ │ │ ├── loading.gif │ │ │ ├── top-logo.svg │ │ │ ├── vulnerability-cve.svg │ │ │ ├── vulnerability-pii.svg │ │ │ ├── vulnerability-secrets.svg │ │ │ ├── vulnerability-third-party.svg │ │ │ └── world-back.svg │ │ └── js │ │ │ └── timeago_mkdocs.js │ ├── home.html │ ├── main.html │ └── partials │ │ ├── content.html │ │ ├── copyright.html │ │ ├── footer.html │ │ ├── header.html │ │ ├── logo.html │ │ └── source-file.html ├── poetry.lock └── pyproject.toml ├── nbdefense ├── __init__.py ├── _version.py ├── cli.py ├── codebase.py ├── constants.py ├── dependencies.py ├── errors.py ├── issues.py ├── nbdefense.py ├── notebook.py ├── plugins │ ├── __init__.py │ ├── cve │ │ ├── cve_dependency_file_plugin.py │ │ ├── cve_notebooks_plugin.py │ │ └── cve_plugin.py │ ├── licenses │ │ ├── license_plugin.py │ │ ├── license_plugin_settings.py │ │ ├── licenses_dependency_file_plugin.py │ │ └── licenses_notebooks_plugin.py │ ├── pii.py │ ├── plugin.py │ └── secrets.py ├── reports.py ├── settings.py ├── templates │ ├── errors.html │ ├── files-scanned-dialog.html │ ├── footer.html │ ├── header.html │ ├── icons │ │ ├── alert-icon-critical.svg │ │ ├── alert-icon-high.svg │ │ ├── alert-icon-low.svg │ │ ├── alert-icon-medium.svg │ │ ├── header-github.svg │ │ └── x.svg │ ├── issue-codes │ │ ├── dependency-file.html │ │ ├── license-not-found-dep-file.html │ │ ├── pii-found.html │ │ ├── secrets.html │ │ ├── unapproved-license-dep-file.html │ │ └── vulnerable-dependency-dep-file.html │ ├── issue.html │ ├── issues.html │ ├── navbar.html │ ├── no-issues.html │ ├── report.html │ ├── scripts.html │ └── summary-card.html ├── templating.py ├── tools.py └── utils.py ├── poetry.lock ├── pyproject.toml └── tests ├── __init__.py ├── conftest.py ├── default_settings.py ├── mock_notebooks ├── fixtures.py └── mock_notebook.py ├── plugin_tests ├── cve │ ├── fixtures.py │ ├── mock_files │ │ └── test-cve.ipynb │ ├── test_cve_dependency_file_plugin.py │ └── test_cve_notebook_plugin.py ├── licenses │ ├── fixtures.py │ ├── mock_files │ │ └── test-license.ipynb │ ├── test_license_dependency_file_plugin.py │ ├── test_license_notebook_plugin.py │ └── test_license_plugin.py ├── test_pii.py └── test_secrets.py ├── test_codebase.py ├── test_issues.py └── test_notebook.py /.bandit: -------------------------------------------------------------------------------- 1 | # FILE: .bandit 2 | [bandit] 3 | exclude = ./tests/ -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[A Few Words Describing the Bug]" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation-issue-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Documentation issue report 3 | about: Create a report to help us improve our documentation 4 | title: "[A Few Words Describing the Issue]" 5 | labels: bug, documentation 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the issue** 11 | A clear and concise description of what the issue is. 12 | 13 | **Relevant page** 14 | Link the page that should be addressed 15 | 16 | **Expected behavior/text** 17 | A clear and concise description of what you expected to see in the documentation. 18 | 19 | **Screenshots** 20 | If applicable, add screenshots to help explain your problem. 21 | 22 | **Desktop (please complete the following information):** 23 | - OS: [e.g. iOS] 24 | - Browser [e.g. chrome, safari] 25 | - Version [e.g. 22] 26 | 27 | **Smartphone (please complete the following information):** 28 | - Device: [e.g. iPhone6] 29 | - OS: [e.g. iOS8.1] 30 | - Browser [e.g. stock browser, safari] 31 | - Version [e.g. 22] 32 | 33 | **Additional context** 34 | Add any other context about the problem here. 35 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for NB Defense 4 | title: "[A Few Words Describing the Feature]" 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: / 5 | schedule: 6 | interval: weekly 7 | -------------------------------------------------------------------------------- /.github/workflows/bandit.yml: -------------------------------------------------------------------------------- 1 | name: Bandit 2 | 3 | on: 4 | push: 5 | branches: main 6 | pull_request: 7 | branches: "*" 8 | 9 | jobs: 10 | bandit: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: actions/setup-python@v5 15 | with: 16 | python-version: "3.8" 17 | - uses: snok/install-poetry@v1 18 | with: 19 | version: 1.8.0 20 | virtualenvs-create: true 21 | virtualenvs-in-project: true 22 | installer-parallel: true 23 | - name: Load cached venv 24 | id: cached-poetry-dependencies 25 | uses: actions/cache@v4 26 | with: 27 | path: .venv 28 | key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} 29 | - name: Install Dependencies 30 | if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' 31 | run: | 32 | poetry install --with test --no-root 33 | - name: Run Bandit 34 | run: poetry run bandit -c pyproject.toml -r $(git ls-files '*.py') 35 | -------------------------------------------------------------------------------- /.github/workflows/black.yml: -------------------------------------------------------------------------------- 1 | name: Lint with Black 2 | 3 | on: 4 | push: 5 | branches: main 6 | pull_request: 7 | branches: '*' 8 | 9 | jobs: 10 | lint: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: psf/black@stable 15 | with: 16 | version: "22.8.0" 17 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: main 6 | pull_request: 7 | branches: '*' 8 | 9 | permissions: 10 | id-token: write 11 | contents: read 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 0 # Necessary to get tags 20 | - uses: actions/setup-python@v5 21 | with: 22 | python-version: "3.8" 23 | - uses: snok/install-poetry@v1 24 | with: 25 | version: 1.8.0 26 | virtualenvs-create: true 27 | virtualenvs-in-project: true 28 | installer-parallel: true 29 | - name: Load cached venv 30 | id: cached-poetry-dependencies 31 | uses: actions/cache@v4 32 | with: 33 | path: .venv 34 | key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} 35 | - uses: mtkennerly/dunamai-action@v1 36 | with: 37 | env-var: NBD_VERSION 38 | args: --style pep440 --format "{base}.dev{distance}+{commit}" 39 | - name: Install Dependencies 40 | if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' 41 | run: | 42 | make install-prod 43 | - name: Build Package 44 | run: | 45 | make build-prod 46 | - name: PYPI Publish Dry Run 47 | run: | 48 | poetry publish --dry-run 49 | -------------------------------------------------------------------------------- /.github/workflows/docs-build.yml: -------------------------------------------------------------------------------- 1 | name: Build Docs 2 | on: 3 | push: 4 | paths: 5 | - docs/** 6 | branches: 7 | - main 8 | pull_request: 9 | branches: '*' 10 | permissions: 11 | contents: write 12 | jobs: 13 | docs-build: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | - uses: actions/setup-python@v5 18 | with: 19 | python-version: "3.8" 20 | - uses: snok/install-poetry@v1 21 | with: 22 | version: 1.8.0 23 | virtualenvs-create: true 24 | virtualenvs-in-project: true 25 | installer-parallel: true 26 | - name: Load cached venv 27 | id: cached-poetry-dependencies 28 | uses: actions/cache@v4 29 | with: 30 | path: .venv 31 | key: venv-doc-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/docs/poetry.lock') }} 32 | - name: Install Dependencies 33 | if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' 34 | run: | 35 | cd docs 36 | poetry install --no-interaction 37 | - name: Build 38 | run: | 39 | cd docs 40 | poetry run mkdocs build -------------------------------------------------------------------------------- /.github/workflows/docs-deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Docs to Github Pages 2 | on: 3 | push: 4 | paths: 5 | - docs/** 6 | branches: 7 | - main 8 | permissions: 9 | contents: write 10 | jobs: 11 | docs-deploy: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | with: 16 | fetch-depth: 0 # Necessary to get tags 17 | - uses: actions/setup-python@v5 18 | with: 19 | python-version: "3.8" 20 | - uses: snok/install-poetry@v1 21 | with: 22 | version: 1.8.0 23 | virtualenvs-create: true 24 | virtualenvs-in-project: true 25 | installer-parallel: true 26 | - name: Load cached venv 27 | id: cached-poetry-dependencies 28 | uses: actions/cache@v4 29 | with: 30 | path: .venv 31 | key: venv-doc-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/docs/poetry.lock') }} 32 | - name: Install Dependencies 33 | if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' 34 | run: | 35 | cd docs 36 | poetry install --no-interaction 37 | - name: Deploy to Github 38 | run: | 39 | cd docs 40 | poetry run mkdocs gh-deploy -------------------------------------------------------------------------------- /.github/workflows/mypy.yml: -------------------------------------------------------------------------------- 1 | name: MYPY 2 | 3 | on: 4 | push: 5 | branches: main 6 | pull_request: 7 | branches: '*' 8 | 9 | jobs: 10 | mypy: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: actions/setup-python@v5 15 | with: 16 | python-version: "3.8" 17 | - uses: snok/install-poetry@v1 18 | with: 19 | version: 1.8.0 20 | virtualenvs-create: true 21 | virtualenvs-in-project: true 22 | installer-parallel: true 23 | - name: Load cached venv 24 | id: cached-poetry-dependencies 25 | uses: actions/cache@v4 26 | with: 27 | path: .venv 28 | key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} 29 | - name: Install Dependencies 30 | if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' 31 | run: | 32 | poetry install --with test --no-root 33 | - name: Run MYPY 34 | run: | 35 | poetry run mypy --ignore-missing-imports --strict --check-untyped-defs $(git ls-files '*.py') 36 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Build and Publish Release to PYPI 2 | 3 | on: 4 | push: 5 | tags: 6 | - v* 7 | 8 | jobs: 9 | publish-nbdefense: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: write 13 | pull-requests: write 14 | 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 0 # Necessary to get tags 20 | - uses: actions/setup-python@v5 21 | with: 22 | python-version: "3.8" 23 | - uses: snok/install-poetry@v1 24 | with: 25 | version: 1.8.0 26 | virtualenvs-create: true 27 | virtualenvs-in-project: true 28 | installer-parallel: true 29 | - name: Get Release Version 30 | uses: mtkennerly/dunamai-action@v1 31 | with: 32 | env-var: NBD_VERSION 33 | args: --style semver --format "{base}" 34 | - name: Set Package Version 35 | run: | 36 | echo "__version__ = '$NBD_VERSION'" > nbdefense/_version.py 37 | poetry version $NBD_VERSION 38 | - name: Build Package 39 | run: | 40 | poetry build 41 | - name: Publish Package to PYPI 42 | run: | 43 | poetry config pypi-token.pypi ${{ secrets.NBDEFENSE_PYPI_API_TOKEN }} 44 | poetry publish -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: main 6 | pull_request: 7 | branches: '*' 8 | 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | python-version: ["3.8", "3.9", "3.10"] 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: Set up Python ${{ matrix.python-version }} 19 | uses: actions/setup-python@v5 20 | with: 21 | python-version: ${{ matrix.python-version }} 22 | - uses: snok/install-poetry@v1 23 | with: 24 | version: 1.8.0 25 | virtualenvs-create: true 26 | virtualenvs-in-project: true 27 | installer-parallel: true 28 | - name: Load cached venv 29 | id: cached-poetry-dependencies 30 | uses: actions/cache@v4 31 | with: 32 | path: .venv 33 | key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} 34 | - name: Install Dependencies 35 | if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' 36 | run: | 37 | poetry install --with test 38 | - name: Run Tests 39 | run: | 40 | make test 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | 162 | .DS_Store 163 | 164 | .vscode/ 165 | 166 | # Temp directory we use for converted Python files 167 | .tmp/ 168 | 169 | # Local config directory 170 | .nbdefense/ 171 | 172 | nbdefense/trivy 173 | 174 | # settings files for scan 175 | settings.toml 176 | 177 | # Mkdocs build 178 | /docs/site 179 | 180 | # Files Generated By Tests 181 | tests/plugin_tests/cve/mock_files/requirements.txt 182 | tests/plugin_tests/licenses/mock_files/requirements.txt -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/psf/black 3 | rev: 22.8.0 4 | hooks: 5 | - id: black 6 | - repo: https://github.com/PyCQA/bandit 7 | rev: '1.7.5' 8 | hooks: 9 | - id: bandit 10 | args: ["-c", "pyproject.toml"] 11 | additional_dependencies: ["bandit[toml]"] 12 | - repo: https://github.com/python-poetry/poetry 13 | rev: '1.4.0' 14 | hooks: 15 | - id: poetry-check # Makes sure poetry config is valid 16 | - id: poetry-lock # Makes sure lock file is up to date 17 | args: ["--check"] 18 | - repo: https://github.com/pre-commit/mirrors-mypy 19 | rev: "v1.1.1" 20 | hooks: 21 | - id: mypy 22 | args: ["--ignore-missing-imports", "--strict", "--check-untyped-defs"] 23 | additional_dependencies: [ 24 | "types-requests==2.28.11.15", 25 | "types-tqdm==4.65.0.0", 26 | "pytest==7.1.3", 27 | "types-setuptools==67.6.0.5", 28 | "click==8.1.3", 29 | "nbformat==5.6.1", 30 | "tomlkit==0.11.6", 31 | "jinja2==3.1.2" 32 | ] 33 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # 👩💻 CONTRIBUTING 2 | 3 | Welcome! We're glad to have you. If you would like to report a bug, request a new feature or enhancement, follow [this link](https://nbdefense.ai/faq) for more help. 4 | 5 | If you're looking for documentation on how to use NB Defense, you can find that [here](https://nbdefense.ai). 6 | 7 | ## ❗️ Requirements 8 | 9 | 1. Python 10 | 11 | NB Defense requires python version greater than `3.8` and less than `3.11` 12 | 13 | 2. Poetry 14 | 15 | The following install commands require [Poetry](https://python-poetry.org/). To install Poetry you can follow [this installation guide](https://python-poetry.org/docs/#installation). Poetry can also be installed with brew using the command `brew install poetry`. 16 | 17 | ## 💪 Developing with NB Defense 18 | 19 | 1. Clone the repo 20 | 21 | ```bash 22 | git clone git@github.com:protectai/nbdefense.git 23 | ``` 24 | 25 | 2. To install development dependencies to your environment and set up the cli for live updates, run the following command in the root of the `nbdefense` directory: 26 | 27 | ```bash 28 | make install-dev 29 | ``` 30 | 31 | 3. You are now ready to start developing! 32 | 33 | Run a scan with the cli with the following command: 34 | 35 | ```bash 36 | nbdefense scan -s 37 | ``` 38 | 39 | ## 📝 Submitting Changes 40 | 41 | Thanks for contributing! In order to open a PR into the NB Defense project, you'll have to follow these steps: 42 | 43 | 1. Fork the repo and clone your fork locally 44 | 2. Run `make install-dev` from the root of your forked repo to setup your environment 45 | 3. Make your changes 46 | 4. Submit a pull request 47 | 48 | After these steps have been completed, someone on our team at Protect AI will review the code and help merge in your changes! 49 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | VERSION ?= $(shell dunamai from git --style pep440 --format "{base}.dev{distance}+{commit}") 2 | 3 | install-dev: 4 | poetry install --with dev 5 | pre-commit install 6 | 7 | install: 8 | poetry install 9 | 10 | install-prod: 11 | poetry install --with prod 12 | 13 | clean: 14 | pip uninstall nbdefense 15 | pip freeze | xargs -n1 pip uninstall -y 16 | rm -f dist/* 17 | 18 | test: 19 | poetry run pytest 20 | 21 | test-watch: 22 | ptw --ignore ./.tmp 23 | 24 | build: 25 | poetry build 26 | 27 | build-prod: version 28 | poetry build 29 | 30 | version: 31 | echo "__version__ = '$(VERSION)'" > nbdefense/_version.py 32 | poetry version $(VERSION) 33 | 34 | lint: bandit mypy 35 | 36 | bandit: 37 | poetry run bandit -c pyproject.toml -r . 38 | 39 | mypy: 40 | poetry run mypy --ignore-missing-imports --strict --check-untyped-defs . 41 | 42 | format: 43 | black . 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🛡️ NB Defense 2 | 3 | [](https://github.com/protectai/nbdefense/actions/workflows/bandit.yml) 4 | [](https://github.com/protectai/nbdefense/actions/workflows/build.yml) 5 | [](https://github.com/protectai/nbdefense/actions/workflows/black.yml) 6 | [](https://github.com/protectai/nbdefense/actions/workflows/mypy.yml) 7 | [](https://github.com/protectai/nbdefense/actions/workflows/test.yml) 8 | [](https://opensource.org/license/apache-2-0/) 9 | 10 | ## 🏃♀️ Quick Start 11 | 12 | ```bash 13 | pip install nbdefense 14 | ``` 15 | 16 | ## 🙋♂️ What is NB Defense? 17 | 18 | Brought to you by Protect AI, NB Defense is a CLI tool and SDK that encourages you to think about security throughout every step of your machine learning development process. You can use nbdefense to scan for [Secrets](https://github.com/protectai/nbdefense/blob/main/docs/docs/supported-scans/detecting-secrets.md), [Personally Identifiable Information (PII)](https://github.com/protectai/nbdefense/blob/main/docs/docs/supported-scans/detecting-PII.md), [Common Vulnerabilities and Exposures(CVE)](https://github.com/protectai/nbdefense/blob/main/docs/docs/supported-scans/detecting-CVEs.md), and [Licenses](https://github.com/protectai/nbdefense/blob/main/docs/docs/supported-scans/detecting-licenses.md) in your notebook and dependency files. 19 | 20 | NB Defense also acts as a SDK for our [Jupyter Lab Extension](https://github.com/protectai/nbdefense-jupyter). Visit our [documentation](https://github.com/protectai/nbdefense/tree/main/docs/docs), or the repository below to learn more. 21 | 22 | - [Jupyter Lab Extension Repository](https://github.com/protectai/nbdefense-jupyter) 23 | 24 | ## 📄 Documentation 25 | 26 | For more details and [documentation](https://github.com/protectai/nbdefense/tree/main/docs/docs) visit these links: 27 | 28 | - [Documentation](https://github.com/protectai/nbdefense/tree/main/docs/docs) 29 | 30 | - [Getting Started on a Local Machine](https://github.com/protectai/nbdefense/blob/main/docs/docs/getting-started/cli.md) 31 | 32 | ## 💪 Contributing 33 | 34 | Welcome to the team! We are open to contributions and working with the community to make notebooks safer for everyone. 35 | 36 | If you would like to contribute, please visit [CONTRIBUTING.md](https://github.com/protectai/nbdefense/blob/main/CONTRIBUTING.md) to get started as a developer, or to suggest bug fixes, improvements, or new features follow [this link](https://github.com/protectai/nbdefense/blob/main/docs/docs/faq.md) to our FAQ page. 37 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | | Version | Supported | 6 | | ------- | ------------------ | 7 | | 1.x | :white_check_mark: | 8 | 9 | ## Reporting a Vulnerability 10 | 11 | If you find a vulnerability in NB Defense, perform the following steps: 12 | 13 | 1. [Open an issue](https://github.com/protectai/nbdefense/issues/new?assignees=&labels=bug&template=bug_report.md&title=[BUG]%20Security%20Vulnerability) in the nbdefense repo. Use `[BUG] Security Vulnerability` as the title and do not include any vulnerability details in the issue description. 14 | 2. Send us an email at `security@protectai.com` with the following: 15 | - The link to the issue you created above. 16 | - Your GitHub handle. 17 | - Details about the vulnerability including: 18 | - A description of what the vulnerability is. 19 | - Evidence of the issue happening or references to the relevant lines of code. 20 | - Instructions to reproduce the issue. 21 | 22 | After we have reproduced the issue we will reply to the issue and [open a draft security advisory](https://docs.github.com/en/code-security/security-advisories/creating-a-security-advisory) and will discuss the details there. 23 | 24 | Once we've released a fix we will use the Security Advisory to announce the findings. 25 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | install: 2 | poetry install 3 | 4 | start-dev: 5 | mkdocs serve --dirtyreload 6 | 7 | build: 8 | mkdocs build 9 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # 📖 NBDefense Documentation 2 | 3 | ## ❗️ Requirements 4 | 5 | 1. Python 6 | 7 | NB Defense requires python version greater than `3.8` and less than `3.11` 8 | 9 | 2. Poetry 10 | 11 | The following install commands require [Poetry](https://python-poetry.org/). To install Poetry you can follow [this installation guide](https://python-poetry.org/docs/#installation). Poetry can also be installed with brew using the command `brew install poetry`. 12 | 13 | ## 💻 Local Install 14 | 15 | 1. Run `make install` to install the pip dependencies to the current python environment 16 | 17 | 2. Run `make start-dev` to run a development server locally 18 | 19 | 3. Go to `http://127.0.0.1:8000/` to view the docs 20 | 21 | ## 📚 References 22 | 23 | We are using the following libraries for our documentation: 24 | 25 | - [Live Documentation](https://nbdefense.ai) 26 | - This is where the production build is hosted 27 | - [MkDocs](https://www.mkdocs.org/) 28 | - This is the static site generator we're using 29 | - [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/) 30 | - This is the theme we're using for MkDocs 31 | -------------------------------------------------------------------------------- /docs/docs/CNAME: -------------------------------------------------------------------------------- 1 | nbdefense.ai -------------------------------------------------------------------------------- /docs/docs/about-us.md: -------------------------------------------------------------------------------- 1 | --- 2 | hide: 3 | - navigation 4 | --- 5 | 6 | At Protect AI we're building a safer AI Powered World by empowering a community of ML security researchers, finding unique exploits, and providing tools that to reduce risk inherent in MLOps pipelines. 7 | 8 | Learn more about us at [protectai.com](https://protectai.com/) and check out our [GitHub](https://github.com/protectai)! 9 | -------------------------------------------------------------------------------- /docs/docs/faq.md: -------------------------------------------------------------------------------- 1 | --- 2 | hide: 3 | - navigation 4 | --- 5 | 6 | Thank you for your interest in NB Defense. We want to make tools with the community that data scientist and engineers can use and enjoy. Welcome to the community! 7 | 8 | ## Common Questions 9 | 10 | ### Why should I use NB Defense as a data scientist? 11 | 12 | We know that JupyterLab is where many data scientist experiement and prove out their ideas. The NB Defense [JupyterLab Extension](./getting-started/jupyter-lab-extension.md) and [CLI](./getting-started/cli.md) allows you to check for vulnerabilities and security issues before the code leaves your environment. You can use NB Defense to check for personally identifiable information, secrets, common exposures and vulnerabilites, and non permissive licenses with the click of the button. We wanted to create a way for data scientists to reduce exposure to security issues and save time later on, by integrating good security practices into the development process. 13 | 14 | ### Can I run NB Defense in my CI pipeline? 15 | 16 | Yes, you can run NB Defense in your CI pipline using the [NB Defense CLI](./getting-started/cli.md)! Use the CLI in your CI pipelines to scan repositories, or multiple notebooks at a time. 17 | 18 | ### What is special about NB Defense when many security tools offer similar functionality? 19 | 20 | NB Defense is special because it allows you to scan Jupyter Notebooks. We provide both a [JupyterLab Extension](./getting-started/jupyter-lab-extension.md) that you can use to scan notebooks while you're working, and a [CLI](./getting-started/cli.md) that you can use to scan groups of notebooks or repositories. Using both of these tools, you can scan your notebooks for personally identifiable information (PII), secrets, common exposures and vulnerabilities (CVEs), and non permissive licenses. 21 | 22 | ### Does NB Defense JupyterLab Extension run in my kernel? 23 | 24 | We recommend that you isolate NB Defense from the kernel that you are using for your notebook. If you have installed NB Defense into a separate python environment, it will not run in your kernel. We do use your active kernels python path to determine which third party dependencies are installed, so we can scan them for CVEs and licenses. 25 | 26 | ## Found A Bug? 🐞 27 | 28 | Found an issue with the NB Defense CLI or JupyterLab Extension? Lets get that fixed. Let us know what you've found by opening an issue using the following links: 29 | 30 | - [NB Defense Bug (SDK and CLI)](https://github.com/protectai/nbdefense/issues/new?labels=bug&template=bug_report.md&title=%5BA+Few+Words+Describing+the+Bug%5D) 31 | 32 | - [NB Defense Jupyter Bug (JupyterLab Extension)](https://github.com/protectai/nbdefense-jupyter/issues/new?labels=bug&template=bug_report.md&title=%5BA+Few+Words+Describing+the+Bug%5D) 33 | 34 | ## Found An Issue With Our Documentation? 📄 35 | 36 | We want to be clear, correct, and concise. Let us know where we can improve: 37 | 38 | - [NB Defense Documentation Issue (SDK, CLI and JupyterLab Extension)](https://github.com/protectai/nbdefense/issues/new?labels=bug%2C+documentation&template=documentation-issue-report.md&title=%5BA+Few+Words+Describing+the+Issue%5D) 39 | 40 | ## Have An Idea For A New Feature? 💡 41 | 42 | We'd love to hear about it. Tell us more by creating an issue below: 43 | 44 | - [NB Defense Feature Request (SDK and CLI)](https://github.com/protectai/nbdefense/issues/new?labels=enhancement&template=feature_request.md&title=%5BA+Few+Words+Describing+the+Feature%5D) 45 | 46 | - [NB Defense Jupyter Feature Request (JupyterLab Extension)](https://github.com/protectai/nbdefense/issues/new?labels=enhancement&template=feature_request.md&title=%5BA+Few+Words+Describing+the+Feature%5D) 47 | 48 | ## Have A Question? ❓ 49 | 50 | Feel free to ask questions using github discussions by following the links below: 51 | 52 | - [NB Defense Discussions (SDK and CLI)](https://github.com/protectai/nbdefense/discussions) 53 | 54 | - [NB Defense Jupyter Discussions (JupyterLab Extension)](https://github.com/protectai/nbdefense-jupyter/discussions) 55 | -------------------------------------------------------------------------------- /docs/docs/getting-started/cloud-services/azure-ml-notebooks.md: -------------------------------------------------------------------------------- 1 | # Configuring NB Defense for Azure ML Notebooks 2 | 3 | This section outlines the steps for installation of NB Defense in [Azure Machine Learning Studio](https://azure.microsoft.com/en-us/products/machine-learning/). 4 | 5 | 1. Open the notebook you want to scan in JupyterLab by accessing the Editor menu as shown below: 6 | 7 | |  | 8 | | :------------------------------------------------------------------------: | 9 | | _Open jupyter notebook in JupyterLab using Azure Machine Learning Studio._ | 10 | 11 | 2. From JupyterLab, open a new terminal. 12 | 13 | 3. Activate `jupyter_env` environment using the following command: 14 | 15 | ``` 16 | conda activate jupyter_env 17 | ``` 18 | 19 | 4. The JLE can now be installed using the following command: 20 | 21 | ``` 22 | pip install nbdefense_jupyter 23 | ``` 24 | 25 | 5. Once NB Defense is installed, enable the extension using the following command: 26 | 27 | ``` 28 | jupyter server extension enable nbdefense_jupyter 29 | ``` 30 | 31 | 6. Optionally you can also run: 32 | 33 | ``` 34 | jupyter lab extension list 35 | ``` 36 | 37 | to ensure the extension is enlisted. The above two commands should give an output similar to the one below: both commands list **nbdefense_jupyter**. 38 | 39 | |  | 40 | | :-----------------------------------------------------------------------------------: | 41 | | _Enabling the NBDefense JupyterLab Extension (JLE) in Azure Machine Learning Studio._ | 42 | 43 | 7. Restart the jupyter server using: 44 | 45 | ``` 46 | sudo systemctl restart jupyter 47 | ``` 48 | 49 | and refresh the browser. This should show the NB Defense widget installed in the left menu: 50 | 51 | 8. Refresh the JupyterLab webpage (CMD+R on a Mac or CTRL+R on a Windows machine). You should now be able to see the NBDefense JLE widget on the left hand side of the JupyterLab UI. 52 | 53 | |  | 54 | | :--------------------------------------------------------------------------------------------------: | 55 | | _Successful installation of NB Defense JupyterLab Extension (JLE) in Azure Machine Learning Studio._ | 56 | 57 | That is it! You can now log in, and press the scan button and see if there are any issues in your notebook as outlined by the NB Defense scan. For example, in the notebook below NB Defense scan has found some personally identifiable information (PII) (note the PII is fake). 58 | 59 | |  | 60 | | :----------------------------------------------------------------------------------------: | 61 | | _NB Defense Jupyter Lab Extension (JLE) scan results using Azure Machine Learning Studio._ | 62 | 63 | Please note that [plugin specific settings](../../scan-settings/jupyterlab-settings.md) may not work on notebooks running in Azure Machine Learning Studio. 64 | -------------------------------------------------------------------------------- /docs/docs/getting-started/cloud-services/images/azure-jle-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/getting-started/cloud-services/images/azure-jle-1.png -------------------------------------------------------------------------------- /docs/docs/getting-started/cloud-services/images/azure-jle-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/getting-started/cloud-services/images/azure-jle-3.png -------------------------------------------------------------------------------- /docs/docs/getting-started/cloud-services/images/azure-jle-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/getting-started/cloud-services/images/azure-jle-4.png -------------------------------------------------------------------------------- /docs/docs/getting-started/cloud-services/images/azure-jle-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/getting-started/cloud-services/images/azure-jle-5.png -------------------------------------------------------------------------------- /docs/docs/getting-started/cloud-services/images/sm-notebook-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/getting-started/cloud-services/images/sm-notebook-1.png -------------------------------------------------------------------------------- /docs/docs/getting-started/cloud-services/images/sm-notebook-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/getting-started/cloud-services/images/sm-notebook-2.png -------------------------------------------------------------------------------- /docs/docs/getting-started/cloud-services/images/sm-notebook-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/getting-started/cloud-services/images/sm-notebook-3.png -------------------------------------------------------------------------------- /docs/docs/getting-started/cloud-services/images/sm-notebook-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/getting-started/cloud-services/images/sm-notebook-4.png -------------------------------------------------------------------------------- /docs/docs/getting-started/cloud-services/images/sm-notebook-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/getting-started/cloud-services/images/sm-notebook-5.png -------------------------------------------------------------------------------- /docs/docs/getting-started/cloud-services/images/studio-lab-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/getting-started/cloud-services/images/studio-lab-screenshot.png -------------------------------------------------------------------------------- /docs/docs/getting-started/cloud-services/index.md: -------------------------------------------------------------------------------- 1 | # JupyterLab Extension on Cloud Services 2 | 3 | This page gives an overall account of installing NB Defense JupyterLab Extension (JLE) on different cloud platforms. Overall, the following four steps outline the installation of the JLE: 4 | 5 | 1. Choose the conda environment in which JLE is to be installed. 6 | 7 | ```bash 8 | conda activate ENVIRONMENT_NAME 9 | ``` 10 | 11 | 2. Install the JLE using pip install command: 12 | 13 | ```bash 14 | pip install nbdefense_jupyter 15 | ``` 16 | 17 | 3. Enable the JLE using: 18 | 19 | ```bash 20 | jupyter server extension enable nbdefense_jupyter 21 | ``` 22 | 23 | 4. Restart the JupyterLab server with the platform specific restart command/sequence. 24 | 25 | Please note that step 2 and step 3 will be the same on all cloud platforms, whereas step 1 and step 4 will change depending on the cloud platform. 26 | 27 | Please follow the links for the following cloud platforms to learn more about their specific JLE installation steps: 28 | 29 | [SageMaker Notebooks](./sage-maker-notebook-instances.md){ .md-button .md-button--primary } 30 | 31 | [SageMaker Studio Labs](./sage-maker-studio-lab.md){ .md-button .md-button--primary } 32 | 33 | [Azure Machine Learning Studio](./azure-ml-notebooks.md){ .md-button .md-button--primary } 34 | 35 | ## Unsupported Cloud Platforms: 36 | 37 | The NB Defense JLE will not work on the following cloud platforms: 38 | 39 | 1. Oracle Cloud Infrastructure (OCI): The Jupyter version running on OCI is `2.2.10` whereas the NB Defense JLE works on Jupyter version 3. 40 | 41 | 2. Google Cloud Platform (GCP): The GCP does not support third party JupyterLab extensions for both [managed notebooks](https://cloud.google.com/vertex-ai/docs/workbench/managed/introduction), and [user-managed notebooks](https://cloud.google.com/vertex-ai/docs/workbench/user-managed/introduction). 42 | 43 | 44 | ## Other Cloud Platforms? 45 | 46 | If you are trying to install NB Defense JLE on a cloud platform for which the installation instructions are not listed, you are welcome to open a ticket, or a PR [here](https://github.com/protectai/nbdefense/issues). 47 | -------------------------------------------------------------------------------- /docs/docs/getting-started/cloud-services/sage-maker-studio-lab.md: -------------------------------------------------------------------------------- 1 | # Configuring NB Defense for SageMaker Studio Lab 2 | 3 | This section covers the installation of NB Defense on [SageMaker Studio Lab](https://studiolab.sagemaker.aws/) 4 | 5 | 1. Open a terminal session within SageMaker Studio Lab 6 | 7 | 2. Activate the studiolab environment by running: 8 | 9 | ```shell 10 | conda activate studiolab 11 | ``` 12 | 13 | 3. Install the extension with pip (please ensure to replace your license key with {LICENSE_KEY} or get your pre-filled link from the [NB Defense web portal](https://nbdefense.protectai.com/)): 14 | 15 | ```shell 16 | pip install nbdefense_jupyter 17 | ``` 18 | 19 | 4. Enable the server extension with 20 | 21 | ```shell 22 | jupyter server extension enable nbdefense_jupyter 23 | ``` 24 | 25 | 5. Go to the Studio Lab project overview page. 26 | 27 |  28 | 29 | 6. Select Stop runtime. 30 | 7. Select Start runtime. 31 | 8. Reopen the JupyterLab session with the "Open project" button and the NB Defense extension should be there. 32 | 33 | ## Need more help? 34 | 35 | More details about how to manage your SageMaker Studio Lab environment can be found in [the official documentation](https://docs.aws.amazon.com/sagemaker/latest/dg/studio-lab-use-manage.html#studio-lab-use-manage-conda-jupyter) 36 | -------------------------------------------------------------------------------- /docs/docs/getting-started/cloud-services/sage-maker-studio.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: NB Defense for SageMaker Studio will be coming soon. 3 | --- 4 | 5 | # Configuring NB Defense on SageMaker Studio 6 | 7 | ## Coming Soon 🚧 8 | -------------------------------------------------------------------------------- /docs/docs/getting-started/index.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | NB Defense is an open source tool for detecting security issues in Jupyter Notebooks. These issues can range from detecting leaked PII in your notebook output to detecting vulnerable versions of installed dependencies. There are currently two tools that you can use to scan your notebooks with NB Defense. 4 | 5 | ## Choose the tool for you 6 | 7 | ### [The JupyterLab Extension](jupyter-lab-extension.md) 8 | 9 | Using the JupyterLab Extension is ideal for correcting issues directly within the JupyterLab environment. You can quickly scan and re-scan a single notebook in order to correct any potential security issues within your environment. 10 | 11 | 14 | 15 | [Try it out!](jupyter-lab-extension.md){ .md-button .md-button--primary } 16 | 17 | ### [The CLI](cli.md) 18 | 19 | The CLI is a better option if you have a lot of notebooks that you would like to scan simultaneously or if you would like to automatically scan notebooks that are going into a central repository. It can also help you set a baseline for correcting individual notebooks with the JupyterLab Extension at a later time. 20 | 21 |  22 | 23 | [Try it out!](cli.md){ .md-button .md-button--primary } 24 | -------------------------------------------------------------------------------- /docs/docs/getting-started/jupyter-lab-extension.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Using the NB Defense JupyterLab extension. 3 | --- 4 | 5 | ## Installation 6 | 7 | !!! info "Running NB Defense on JupyterLab in the cloud" 8 | 9 | The following instructions are for a local installation of JupyterLab. If you are interested in running the JupyterLab Extension on a cloud platform, please visit the [JupyterLab Extension on Cloud Services](./cloud-services/index.md) page for instructions for each platform. 10 | 11 | 1. Activate the Python environment that you use to run JupyterLab. 12 | 13 | !!! warning "Supported JupyterLab Versions" 14 | 15 | The NB Defense JupyterLab extension works with versions of JupyterLab >=3 and <4. 16 | 17 | 2. Install the extension with pip: 18 | 19 | ```bash 20 | pip install nbdefense_jupyter 21 | ``` 22 | 23 | 3. (Optional) Install the Spacy model for PII detection with: 24 | 25 | ```bash 26 | python -m spacy download en_core_web_trf 27 | ``` 28 | 29 | !!! warning "Spacy model download" 30 | 31 | This is required for the PII plugin to operate. If you do not install the `en_core_web_trf` model, then you will get the following error message in the scan output with the PII plugin activated: 32 | ``` 33 | Error occurred in the scan portion of the PII Plugin plugin. 34 | Message: [E050] Can't find model 'en_core_web_trf'. 35 | It doesn't seem to be a Python package or a valid path to a data directory. 36 | ``` 37 | 38 | 4. Activate the server extension with: 39 | 40 | ```bash 41 | jupyter server extension enable nbdefense_jupyter 42 | ``` 43 | 44 | 5. Start (or restart) the JupyterLab session and the NB Defense extension should be ready to go! You will know the extension has been installed successfully if you are able to see the new NB Defense tab and the `Scan with NB Defense` button in the toolbar. 45 | ```bash 46 | jupyter lab 47 | ``` 48 |  49 | 50 | ## Usage 51 | 52 | Once the extension has been installed, you can now start scanning your notebooks within the JupyterLab environment. 53 | 54 | Installing the NB Defense JupyterLab Extension (JLE) will add a tab with an NB icon to your side bar. Clicking this will take you to the NB Defense JLE panel. From there you can run a scan or view scan results for the currently focused notebook. 55 | 56 | 59 | 60 | You can also run a scan by clicking the `Scan with NB Defense` button in the notebook toolbar. 61 | 62 | 65 | 66 | ## Interpreting Scan Results 67 | 68 | Within the side panel we display a list of issues detected during the scan. The information on the side bar includes the "Issue type", a short description of the issue, and which cell index the issue was found in. 69 | 70 | {: style="height:600px"} 71 | 72 | Clicking on one of the issues here will focus the relevant cell. From here you can see that the characters that triggered the scan will be underlined in the editor. Additionally, all of the cells that contain issues will have a red background. 73 | 74 | 77 | 78 | ## Adjusting Scan Settings 79 | 80 | You can change and update settings for your scan from the JupyterLab settings menu. More info is available on the [Scan Settings](../scan-settings/index.md) page. 81 | -------------------------------------------------------------------------------- /docs/docs/imgs/cli-help-message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/imgs/cli-help-message.png -------------------------------------------------------------------------------- /docs/docs/imgs/focus-cell-from-issue.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/imgs/focus-cell-from-issue.mp4 -------------------------------------------------------------------------------- /docs/docs/imgs/html-scan-report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/imgs/html-scan-report.png -------------------------------------------------------------------------------- /docs/docs/imgs/html-scan-with-errors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/imgs/html-scan-with-errors.png -------------------------------------------------------------------------------- /docs/docs/imgs/jle-initial-setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/imgs/jle-initial-setup.png -------------------------------------------------------------------------------- /docs/docs/imgs/jupyter-extension-example.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/imgs/jupyter-extension-example.mp4 -------------------------------------------------------------------------------- /docs/docs/imgs/jupyter-settings.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/imgs/jupyter-settings.mp4 -------------------------------------------------------------------------------- /docs/docs/imgs/open-nb-defense-panel.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/imgs/open-nb-defense-panel.mp4 -------------------------------------------------------------------------------- /docs/docs/imgs/run-scan-from-toolbar.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/imgs/run-scan-from-toolbar.mp4 -------------------------------------------------------------------------------- /docs/docs/imgs/show-contextual-help-toggle.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/imgs/show-contextual-help-toggle.mp4 -------------------------------------------------------------------------------- /docs/docs/imgs/show-dropdowns-toggle.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/imgs/show-dropdowns-toggle.mp4 -------------------------------------------------------------------------------- /docs/docs/imgs/side-panel-with-results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/imgs/side-panel-with-results.png -------------------------------------------------------------------------------- /docs/docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: home.html 3 | hide: 4 | - navigation 5 | - toc 6 | - content 7 | - md-main 8 | --- 9 | -------------------------------------------------------------------------------- /docs/docs/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | 4 | Sitemap: https://nbdefense.ai/sitemap.xml -------------------------------------------------------------------------------- /docs/docs/scan-settings/cli-flags.md: -------------------------------------------------------------------------------- 1 | There are various flags that can change the behavior of the CLI. Information about these flags can be found using the `nbdefense scan --help` command. 2 | 3 | ``` 4 | nbdefense scan --help 5 | Usage: nbdefense scan [OPTIONS] [PATH] 6 | 7 | Scan [PATH] for .ipynb files for potential issues. 8 | 9 | Options: 10 | -r, --recursive Scan all nested directories for .ipynb 11 | files. 12 | -s, --serve Run an HTTP Server to view the report 13 | instead of persisting the report as an html 14 | file. 15 | -q, --quiet Suppress all output. 16 | -d, --dependency-file PATH Specify a requirements.txt file to scan for 17 | CVEs and license compatibility. 18 | -f, --output-file FILE Specify an output filename for the report. 19 | -o, --output-format [json|html] 20 | The output format for the report. 21 | -y, --yes Bypass all prompts with an affirmative 22 | response. 23 | --settings-file FILE Specify a settings file to use for the scan. 24 | Defaults to [PATH]/settings.toml. 25 | --no-progress-bars Hide progress bars, but keep other logging 26 | active. 27 | --help Show this message and exit. 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/docs/scan-settings/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: This section covers how to configure the settings for NBDefense. 3 | --- 4 | 5 | # Scan Settings 6 | 7 | Settings for scans can be adjusted for both the [JupyterLab Extension](./jupyterlab-settings.md) and the [CLI](./cli-settings.md). 8 | 9 | ## Adjustable Settings 10 | 11 | Each of the four NB Defense plugins (secrets, PII, licences, CVE) can be switched on or off. That is, if only the PII plugin is disabled and the remaining three plugins are enabled, the NB Defense scan will scan for the three enabled plugins but will not scan for PII. 12 | 13 | In addition to enable/disable the available plugins for NB Defense scan, there is a global adjustable setting of `redact_secret` for presenting sensitive information in scan reports. Moreover, NB Defense also allows for individual settings for each of the four plugins. The global and individual plugin settings are described below: 14 | 15 | ### Global Settings 16 | 17 | #### `redact_secret` 18 | 19 | The `redact_secret` setting determines how sensitive information is presented in NB Defense scan reports. The possible values of `redact_secret` are `PARTIAL`, `ALL`, and `HASH`. `PARTIAL` will show only leading and trailing characters. `ALL` will shadow the full secret. `HASH` will replace the full secret with its hashed value (as shown in the table below as well). 20 | 21 | | Redacted Secret Option | Redacted Secret | 22 | | :--------------------- | :-------------- | 23 | | PARTIAL | 4aed\*\*\*\*78$ | 24 | | ALL | ****\*\*\***** | 25 | | HASH | h3hb54i109k | 26 | 27 | ### Secrets Plugin Settings 28 | 29 | #### `secrets_plugins` 30 | 31 | The `secrets_plugins` has the same modules as in the [detect-secrets](https://github.com/Yelp/detect-secrets) package. Each of the secret modules can be enable or disabled. 32 | 33 | More details on which of the secret modules are enabled by default, and what they detect can be found on the [secrets scan details page](../supported-scans/detecting-secrets.md#supported-detect-secrets-plugins). 34 | 35 | ### PII Plugin Settings 36 | 37 | #### `confidence_threshold` 38 | 39 | The `confidence_threshold` indicates the level of uncertainty allowed when flagging text as PII i.e., a confidence threshold set at `0.8` would only allow that text marked as PII when NB Defense's PII scan is at least `80%` confident that the text is PII. For any other text where the confidence of the NB Defense's PII scan is less than `80%` the text will not be marked as PII. The default value of `confidence_threshold` is set at `0.8` with a minimum allowed value of `0.0` and a maximum allowed value of `1.0`. 40 | 41 | Also, NB Defense PII scan allows for separate setting of `confidence_threshold` for each of the PII entities. In this way, by adjusting the values of `confidence_threshold` for each PII entity separately, the users of NB Defense can set the uncertainty in PII scan results for each of the PII entities independently. 42 | 43 | #### `entities` 44 | 45 | The PII entities to be scanned for can be toggled on and off in the scan settings. A list of PII entities with their brief description can be found on the [PII scan details page](../supported-scans/detecting-PII.md). 46 | 47 | ### License Plugin Settings 48 | 49 | #### `accepted_licenses` 50 | 51 | The licenses added to `accepted_licenses` setting will not be flagged in the NB Defense scan report. So, for example, if the following licenses are added to the `accepted_licences`, and they appear in the text, NB Defense License plugin will not flag it. 52 | 53 | ``` 54 | accepted_licenses = ["Apache License 2.0", "BSD-3-Clause", "MIT License"] 55 | ``` 56 | 57 | ### CVE Plugin Settings 58 | 59 | There are no settings specific to the CVE plugin. 60 | -------------------------------------------------------------------------------- /docs/docs/scan-settings/jupyterlab-settings.md: -------------------------------------------------------------------------------- 1 | The settings for the JupyterLab Extension can be found in the JupyterLab Advanced Settings Editor alongside the settings for other JupyterLab extensions. 2 | 3 | You can open the JupyterLab settings pane by clicking on the Settings tab in the menu bar, then clicking on the Advanced Settings Editor button. 4 | 5 | 8 | 9 | ### JupyterLab Specific Settings 10 | 11 | There are two settings specific to the JupyterLab Environment. These are also editable through the toggle buttons on the Notebook. 12 | 13 | #### Show Contextual Help 14 | 15 | This toggles the underlining of found issues in the editor as well as the highlighting of certain cell elements. 16 | 17 | 20 | 21 | #### Show Dropdowns 22 | 23 | This toggles the dropdowns that appear on hover of cells that have issues. 24 | 25 | 28 | -------------------------------------------------------------------------------- /docs/docs/supported-scans/detecting-CVEs.md: -------------------------------------------------------------------------------- 1 | # CVE Detection 2 | 3 | NB Defense scans for common vulnerabilities and exposures (CVEs) associated with the dependencies in your project's `requirements.txt` file and your python environment. We evaluate your dependencies with Aqua's [Trivy](https://github.com/aquasecurity/trivy) tool to detect any known vulnerabilities. 4 | 5 | ## CVE Detection with the JupyterLab Extension (JLE) 6 | 7 | The NB Defense JupyterLab Extension tracks your notebooks currently configured kernel to scan imported third party dependencies for CVEs. 8 | 9 | !!! warning 10 | 11 | Before you begin, please configure a kernel for the notebook you plan to scan, and install all the third party dependencies neccessary to execute your notebook into the kernel. If the notebooks dependencies are not installed in the kernel and are not imported by the notebook, they will not be scanned. You can check that all dependencies are correctly installed by running the python code in your notebook; if your python code is valid and executes without any errors, all related dependencies should be installed correctly. 12 | 13 | Before scanning, verify that the kernel in the NB Defense panel matches the kernel that you have configured. When you press scan, NB Defense will gather imported modules from your notebook and link them to third party packages installed in your kernel. The installed version of the package associated with the imported modules will then be scanned for known CVEs. 14 | 15 | ### JLE Settings 16 | 17 | You can enable or disable cve scanning in the [JupyterLab extensions settings](../scan-settings/jupyterlab-settings.md). 18 | 19 | ### JLE Scan Results 20 | 21 | Once a scan completes, any imported modules with associated CVEs will be added to the report and you will be provided with information about each CVE. The report below includes the CVE ID, the package and version with the issue, along with the fixed version, description, and a url to learn more. 22 | 23 | |  | 24 | | :------------------------------------------------------------------: | 25 | | _NBDefense JupyterLab Extension (JLE) scan report with CVEs found._ | 26 | 27 | ## CVE Detection with the CLI 28 | 29 | The NBDefense CLI currently supports scanning for CVEs with a python `requirements.txt` file. A dependency will only be scanned for CVEs if the version is pinned to a specific version number (ei. `numpy==1.0.0` and not `numpy>=1.0.0`). 30 | 31 | ### CLI Settings 32 | 33 | Using your [settings.toml file](../scan-settings/cli-settings.md) you can enable or disable the CVE plugin. 34 | 35 | !!! note "Example Settings" 36 | 37 | ```toml 38 | [plugins."nbdefense.plugins.CVEDependencyFilePlugin"] 39 | enabled = true 40 | ``` 41 | 42 | ### CLI Scan Results 43 | 44 | The results will provide you with information on what packages have issues, along with information on how to fix the issue. 45 | 46 | |  | 47 | | :------------------------------------------: | 48 | | _NBDefense CLI scan report with CVEs found._ | 49 | -------------------------------------------------------------------------------- /docs/docs/supported-scans/detecting-PII.md: -------------------------------------------------------------------------------- 1 | # Personally Identifiable Information (PII) 2 | The NB Defense scans for any information that can be used to identify a person i.e., personally identifiable information (PII). It can be their name, location, bank information etc. 3 | 4 | NB Defense supports both global entities (such as names, email addresses) as well as country-specific entities (such as UK National Health Service (NHS) number). At the moment, the NB Defense PII plugin has support for English language only. 5 | 6 | The PII analyser is adapted from [Miscrosoft Presidio](https://microsoft.github.io/presidio/) whereas the PII anonymization is handled by NB Defense. 7 | 8 | !!! warning 9 | 10 | Before you begin scanning with the PII plugin, please execute all code inside the notebook you would like scanned. This plugin does not execute code, and will only scan output for PII if it exists in the notebook. 11 | 12 | 13 | ## PII Entities 14 | NB Defense supports the following PII entities: 15 | 16 | ### Global PII entities: 17 | 18 | | Global PII Entity | Description | 19 | | :-- | :--- | 20 | | PERSON | If there is a name in a notebook, NB Defense will flag it as "PERSON". | 21 | | CREDIT_CARD | If there is a number between 12 to 19 digits in a notebook, NB Defense will flag it as "CREDIT_CARD".| 22 | | CRYPTO | If there is a Bitcoin wallet number in a notebook, NB Defense will flag it as "CRYPTO". At the moment, only Bitcoin addresses are supported. | 23 | | EMAIL_ADDRESS | If there is an email address in a notebook, NB Defense will flag it as "EMAIL_ADDRESS". | 24 | | IBAN_CODE | If there is an International Bank Account Number (IBAN) in a notebook, NB Defense will flag it as "IBAN_CODE". | 25 | | IP_ADDRESS | If there is an Internet Protocol (IP) version 4 or version 6 address in a notebook, NB Defense will flag it as "IP_ADDRESS". | 26 | |NRP | If there is a mention of a person's nationality, religious or political affiliation (NRP) in a notebook, NB Defense will flag it as "NRP". | 27 | |PHONE_NUMBER| If there is a telephone number in a notebook, NB Defense will flag it as a "PHONE_NUMBER".| 28 | |LOCATION| If there is a geographraphically defined location name in a notebook such as a city, province or state name, NB Defense will flag it as "LOCATION". | 29 | | MEDICAL_LICENSE | If there is a medical license number in a notebook, NB Defense will flag it as a "MEDICAL_LICENSE". | 30 | 31 | 32 | 33 | 34 | ### United States of America (US)-specific PII entities: 35 | 36 | 37 | | US-Specific PII Entities | Description | 38 | | :-- | :-- | 39 | | US_BANK_NUMBER | If there is a US bank account number between 8 to 17 digits in a notebook, NB Defense will flag it as "US_BANK_NUMBER". | 40 | | US_DRIVER_LICENSE | If there is a US driver license number in a notebook, NB Defense will flag it as "US_DRIVER_LICENSE". | 41 | | US_ITIN | If there is a US Individual Taxpayer Identification Number (ITIN) in a notebook, NB Defense will flag it as "US_ITIN". The US ITIN starts with a "9" and has a "7" or "8" as the fourth digit. | 42 | |US_PASSPORT | If there is a US passport number in a notebook, NB Defense will flag it as "US_PASSPORT". | 43 | |US_SSN| If there is a US Social Security Number (SSN) in a notebook, NB Defense will flag it as "US_SSN". The US SSN has 9 digits. | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | ### United Kingdom (UK)-specific PII entities: 52 | 53 | |UK-specific PII Entities | Description | 54 | |:--- | :--- | 55 | | UK_NHS | If there is a UK National Health Service (NHS) number in a notebook, NB Defense will flag it as a "UK_NHS". The UK NHS is a 10 digit number. | 56 | 57 | 58 | 59 | ### Australia (AU)-specific PII entities: 60 | |AU-specific PII Entities | Description | 61 | |:--- | :--- | 62 | | AU_ABN | If there is an Australian Bank Number (ABN) in a notebook, NB Defense will flag it as a "AU_ABN". The ABN is a 11 digit number. | 63 | |AU_ACN | If there is an Australian Company Number (ACN) in a notebook, NB Defense will flag it as a "AU_ACN". The AU_ACN is a 9 digit number. | 64 | | AU_TFN | If there is an Australian Tax File Number (TFN) in a notbook, NB Defense will flag it as a "AU_TFN". | 65 | | AU_MEDICARE| If there is an Australian Medicare number in a notbook, NB Defense will flag it as a "AU_MEDICARE". | 66 | 67 | 68 | ### PII Scan Results 69 | Below is a sample result for JLE with PII found in ```notebook_2.ipynb``` 70 | 71 | |  | 72 | | :--: | 73 | | *NB Defense JupyterLab Extension (JLE) scan report with Personally Identifiable Information (PII) found.* | 74 | 75 | For any PII found in the notebook, the scan flags it as a HIGH severity issue, and also includes the cell number where it is found. 76 | 77 | On clicking on the ```Issue type: PII``` will focus the cell where PII is found. Upon hovering over the cell, NB Defense will show the total number of PII found in that cell: (in the sample scan result above) a total of 40 potential PII are found. -------------------------------------------------------------------------------- /docs/docs/supported-scans/detecting-licenses.md: -------------------------------------------------------------------------------- 1 | # License Detection 2 | 3 | NB Defense scans for common vulnerabilities and exposures (CVEs) associated with the dependencies in your project's `requirements.txt` file and your python environment. We evaluate your dependencies for licenses that are not included in your list of accepted licenses. 4 | 5 | ## License Detection with the JupyterLab Extension (JLE) 6 | 7 | The NB Defense JupyterLab Extension tracks your notebooks currently configured kernel to scan imported third party dependencies for licenses. 8 | 9 | !!! warning 10 | 11 | Before you begin, please configure a kernel for the notebook you plan to scan, and install all the third party dependencies neccessary to execute your notebook into the kernel. If the notebooks dependencies are not installed in the kernel and are not imported by the notebook, they will not be scanned. You can check that all dependencies are correctly installed by running the python code in your notebook; if your python code is valid and executes without any errors, all related dependencies should be installed correctly. 12 | 13 | Before scanning, verify that the kernel in the NB Defense panel matches the kernel that you have configured. When you press scan, NB Defense will gather imported modules from your notebook and link them to third party packages installed in your kernel. The installed version of the package associated with the imported modules will then be scanned for unapproved licenses. 14 | 15 | ### JLE Settings 16 | 17 | You can configure your list of accepted licenses, and license source in the [JupyterLab extensions settings](../scan-settings/jupyterlab-settings.md). Configure accepted licenses to include all licenses that are acceptable to your project's standards. Configure the license source to determine where NB Defense will look for license data associated with your package (local kernel, pypi, or a combination of the two). 18 | 19 | ### JLE Scan Results 20 | 21 | The example below shows that an unapproved license has been found in the `matplotlibXtns` version `20.5` package. 22 | 23 | |  | 24 | | :----------------------------------------------------------------------: | 25 | | _NBDefense JupyterLab Extension (JLE) scan report with licenses found._ | 26 | 27 | ## License Detection with the CLI 28 | 29 | The NBDefense CLI currently supports scanning for licenses using a python `requirements.txt` file. A dependency will only be scanned for licenses if the version is pinned to a specific version number (ei. `numpy==1.0.0` and not `numpy>=1.0.0`). 30 | 31 | ### CLI Settings 32 | 33 | Using your [settings.toml file](../scan-settings/cli-settings.md) you can configure the list of licenses to include licenses that are acceptable to your projects standards. 34 | 35 | !!! note "Example Settings" 36 | 37 | ```toml 38 | [plugins."nbdefense.plugins.LicenseDependencyFilePlugin"] 39 | enabled = true 40 | accepted_licenses = ["Apache License 2.0", "BSD", "MIT", "Python Software Foundation License", "GNU Library or Lesser General Public License (LGPL)", "Apache Software License", "Apache 2.0", "Apache-2.0" , "BSD License", "BSD 3-Clause", "BSD-3-Clause", "Microsoft Public License" , "MIT License", "ISC License (ISCL)", "MIT-0"] 41 | ``` 42 | 43 | ### CLI Scan Results 44 | 45 | The example below surfaces three seperate issues: an unapproved license, a package where a license couldn't be found, and a package that does not have a pinned dependency. 46 | 47 | |  | 48 | | :----------------------------------------------: | 49 | | _NBDefense CLI scan report with licenses found._ | 50 | -------------------------------------------------------------------------------- /docs/docs/supported-scans/detecting-secrets.md: -------------------------------------------------------------------------------- 1 | # Secrets Detection 2 | 3 | NB Defense scans for any secrets or authentication information(such as passwords or tokens) that may be present in a notebook. 4 | 5 | To enable this we have built a wrapper around Yelp's [detect-secrets](https://github.com/Yelp/detect-secrets) library, porting its capabilities to check the input and output cells of your notebooks. 6 | 7 | !!! warning 8 | 9 | Before you begin scanning for secrets, please execute all code inside the notebook that you would like scanned. This plugin does not execute code, and will only scan output for secrets if it exists in the notebook. 10 | 11 | ## Supported detect-secrets Plugins 12 | 13 | Following is a list of the different types of authentication information that is scanned for by the NB Defense: 14 | 15 | 1. API keys and tokens - Application Programming Interface (API) keys and tokens will be detected by NB Defense scan. They are typically used to authenticate a calling program communicating with an API. 16 | 2. Amazon Web Services (AWS) key - AWS key is used to gain access to all the AWS resources. 17 | 3. Azure storage key - Azure storage key is used to authorize access to data in Azure storage account. 18 | 4. Basic authentication - HTTP web browser authentication is usually undertaken using a username and password when making a request such as accessing email. 19 | 5. Cloudant detector - The Cloudant detector is a unique identifier for a document in a database. 20 | 6. Discord bot token - The Artificial Intelligence (AI) driven bots that can automate tasks for moderating server. 21 | 7. GitHub token - GitHub token is an alternative to password when using the GitHub API or the command line for accessing GitHub resources. 22 | 8. Base64 High Entropy String - Strings with high entropy that appear to be Base64 encoded. 23 | 9. Hex High Entropy String - Strings with high entropy that appear to be in a hexadecimal format. 24 | 10. IBM Cloud Identity and Access Management 25 | 11. IBM Hash-based Message Authentication Code (HMAC) - IBM HMAC credentials consist of an Access Key and Secret Key paired for use with S3-compatible tools and libraries that require authentication. 26 | 12. JSON Web Token - JSON Web Tokens (JWT) are an open, industry standard RFC 7519 method for representing claims securely between two parties. 27 | 13. Keywords - Keywords are used for finding tokens and passwords such as 'The password is: **\***'. The word password is a keyword since it gives context. 28 | 14. Mailchimp - Mailchimp is used by marketers for promotional emails. NB Defense detection scans for login information for Mailchimp. 29 | 15. Node Package Manager (NPM) - NPM detection scans for login information for NPM. 30 | 16. Private Key - Private key detection is used for detecting any private or secret keys that could be used for data encryption. 31 | 17. SendGrid - SendGrid is an email marketing provider used for promotional emails. 32 | 18. Slack - Slack is a messaging application used by businesses for connecting their team. 33 | 19. Softlayer - IBM SoftLayer is a public cloud computing platform that offers a range of services, such as compute, storage, and application development. 34 | 20. SquareOAuth - The OAuth allows for sharing of information between services without exposing a password. 35 | 21. Stripe - Stripe enables online payment processing for online businesses. 36 | 22. Twilio - Twilio is a customer engagement platform which is programmable. 37 | 38 | ### Plugin Options 39 | 40 | There are a few plugins that have their own options: 41 | 42 | | Plugin | Option | Description | 43 | | ------------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 44 | | `Base64HighEntropyString` | `limit` | Sets the [Shannon entropy](https://rzepsky.medium.com/hunting-for-secrets-with-the-dumpsterdiver-93d38a9cd4c1) limit for high entropy strings. Value must be between 0.0 and 8.0, defaults to 4.5. | 45 | | `HexHighEntropyString` | `limit` | Sets the [Shannon entropy](https://rzepsky.medium.com/hunting-for-secrets-with-the-dumpsterdiver-93d38a9cd4c1) limit for high entropy strings. Value must be between 0.0 and 8.0, defaults to 3.0. | 46 | | `KeywordDetector` | `keyword_exclude` | Specify a regex string to exclude certain strings from the secrets scan. | 47 | -------------------------------------------------------------------------------- /docs/docs/supported-scans/images/nbd-cli-cve-results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/supported-scans/images/nbd-cli-cve-results.png -------------------------------------------------------------------------------- /docs/docs/supported-scans/images/nbd-cli-license-results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/supported-scans/images/nbd-cli-license-results.png -------------------------------------------------------------------------------- /docs/docs/supported-scans/images/nbd-jle-cve-results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/supported-scans/images/nbd-jle-cve-results.png -------------------------------------------------------------------------------- /docs/docs/supported-scans/images/nbd-jle-license-results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/supported-scans/images/nbd-jle-license-results.png -------------------------------------------------------------------------------- /docs/docs/supported-scans/images/nbd-jle-scan-pii-found.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/docs/supported-scans/images/nbd-jle-scan-pii-found.png -------------------------------------------------------------------------------- /docs/mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: "NB Defense: Secure Jupyter Notebooks" 2 | site_url: "https://nbdefense.ai" 3 | 4 | repo_name: protectai/nbdefense 5 | repo_url: https://github.com/protectai/nbdefense 6 | edit_uri: "" 7 | 8 | copyright: Copyright © 2023 9 | 10 | theme: 11 | name: material 12 | home: home.html 13 | custom_dir: overrides 14 | features: 15 | - navigation.footer 16 | - navigation.tabs 17 | - navigation.tabs.sticky 18 | - navigation.indexes 19 | palette: 20 | - scheme: default 21 | toggle: 22 | icon: material/brightness-7 23 | name: Switch to dark mode 24 | - scheme: slate 25 | toggle: 26 | icon: material/brightness-4 27 | name: Switch to light mode 28 | logo: assets/imgs/top-logo.svg 29 | favicon: assets/imgs/favicon.svg 30 | 31 | nav: 32 | - Home: "index.md" 33 | - "Getting Started": 34 | - "getting-started/index.md" 35 | - "CLI": "getting-started/cli.md" 36 | - "JupyterLab Extension": "getting-started/jupyter-lab-extension.md" 37 | - "JupyterLab Extension on Cloud Services": 38 | - "getting-started/cloud-services/index.md" 39 | - "SageMaker Notebook Instances": "getting-started/cloud-services/sage-maker-notebook-instances.md" 40 | - "Sage Maker Studio Lab": "getting-started/cloud-services/sage-maker-studio-lab.md" 41 | - "Azure ML Notebooks": "getting-started/cloud-services/azure-ml-notebooks.md" 42 | - "SageMaker Studio - COMING SOON": "getting-started/cloud-services/sage-maker-studio.md" 43 | - "Supported Scans": 44 | - "Secrets Detection": "supported-scans/detecting-secrets.md" 45 | - "PII Detection": "supported-scans/detecting-PII.md" 46 | - "CVE Detection": "supported-scans/detecting-CVEs.md" 47 | - "License Detection": "supported-scans/detecting-licenses.md" 48 | - "Scan Settings": 49 | - "scan-settings/index.md" 50 | - "JupyterLab Extension Settings": "scan-settings/jupyterlab-settings.md" 51 | - "CLI Settings": "scan-settings/cli-settings.md" 52 | - "CLI Flags": "scan-settings/cli-flags.md" 53 | - "FAQ": 54 | - "FAQ": "faq.md" 55 | - "About Us": "about-us.md" 56 | 57 | markdown_extensions: 58 | - pymdownx.highlight: 59 | anchor_linenums: true 60 | - pymdownx.details 61 | - pymdownx.inlinehilite 62 | - pymdownx.superfences 63 | - attr_list 64 | - lightgallery 65 | - admonition 66 | 67 | plugins: 68 | - search 69 | - meta-descriptions: 70 | export_csv: false 71 | quiet: false 72 | enable_checks: false 73 | min_length: 10 74 | max_length: 160 75 | - git-revision-date-localized: 76 | enable_creation_date: true 77 | - git-authors: 78 | sort_authors_by: contribution 79 | - minify: 80 | minify_js: true 81 | minify_css: true 82 | cache_safe: true 83 | js_files: 84 | - assets/js/timeago_mkdocs.js 85 | css_files: 86 | - assets/css/extra.css 87 | 88 | extra: 89 | social: 90 | - icon: fontawesome/brands/github 91 | link: https://github.com/protectai/nbdefense 92 | - icon: fontawesome/brands/linkedin 93 | link: https://www.linkedin.com/company/protect-ai/ 94 | - icon: fontawesome/brands/slack 95 | link: https://mlsecops.slack.com 96 | - icon: social-discussion 97 | link: https://github.com/protectai/nbdefense/discussions 98 | generator: false 99 | 100 | extra_javascript: 101 | - https://cdnjs.cloudflare.com/ajax/libs/timeago.js/4.0.2/timeago.min.js 102 | - assets/js/timeago_mkdocs.js 103 | 104 | extra_css: 105 | - assets/css/extra.css 106 | -------------------------------------------------------------------------------- /docs/overrides/.icons/social-discussion.svg: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /docs/overrides/.icons/social-github.svg: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /docs/overrides/.icons/social-linkedin.svg: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /docs/overrides/.icons/social-slack.svg: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /docs/overrides/assets/css/extra.css: -------------------------------------------------------------------------------- 1 | /* Define Font-Family */ 2 | @font-face { 3 | font-family: "SF Pro Display"; 4 | src: url("../fonts/SF-Pro-Display-Bold.woff"); 5 | } 6 | @font-face { 7 | font-family: "SF Pro Text"; 8 | src: url("../fonts/sf-pro-text-regular.woff"); 9 | } 10 | @font-face { 11 | font-family: "SF Pro Text Bold"; 12 | src: url("../fonts/sf-pro-text-bold.woff"); 13 | } 14 | 15 | /* Define Variable */ 16 | :root > * { 17 | --copyright-text-color: #dfdfdf; 18 | --copyright-logo-color: white; 19 | 20 | /* Links */ 21 | --md-typeset-a-color: #138bff; 22 | --md-accent-fg-color: #fe9a2d; 23 | } 24 | 25 | /* Define stylesheet */ 26 | [data-md-color-scheme="default"] { 27 | /* Header */ 28 | --md-primary-fg-color: #384860; 29 | 30 | /* Footer */ 31 | --md-footer-bg-color: white; 32 | --md-footer-bg-color--dark: #384860; 33 | --md-footer-fg-color: black; 34 | } 35 | [data-md-color-scheme="slate"] { 36 | /* Header */ 37 | --md-primary-fg-color: #010101; 38 | 39 | /* Main */ 40 | --md-default-bg-color: #061a38; 41 | --md-default-fg-color--light: white; 42 | 43 | /* Footer */ 44 | --md-footer-bg-color: #061a38; 45 | --md-footer-bg-color--dark: #061a38; 46 | 47 | /* Footer - Copyright */ 48 | --copyright-text-color: #969696; 49 | --copyright-logo-color: #dfdfdf; 50 | } 51 | 52 | /* Header Customization */ 53 | .custom-copyright { 54 | font-family: "Roboto"; 55 | font-style: normal; 56 | font-weight: 400; 57 | font-size: 14px; 58 | line-height: 16px; 59 | color: var(--copyright-text-color); 60 | 61 | display: flex; 62 | flex-direction: row; 63 | gap: 8px; 64 | } 65 | .custom-copyright svg { 66 | color: var(--copyright-logo-color); 67 | } 68 | .custom-copyright svg:hover { 69 | color: white; 70 | } 71 | 72 | #top-logo { 73 | height: 24px; 74 | width: 98px; 75 | } 76 | 77 | /* Footer Customization */ 78 | .md-footer-meta { 79 | padding: 24px 0px; 80 | } 81 | .md-footer-meta__inner { 82 | position: relative; 83 | 84 | align-items: center; 85 | justify-content: center; 86 | 87 | margin-left: auto; 88 | margin-right: auto; 89 | max-width: 61rem; 90 | } 91 | .md-social { 92 | flex: 0; 93 | 94 | position: absolute; 95 | right: 4px; 96 | 97 | display: flex; 98 | } 99 | html .md-footer-meta.md-typeset a:is(:focus, :hover) { 100 | color: white; 101 | } 102 | 103 | /* Copyright customization */ 104 | .protectai-logo { 105 | padding-left: 4px; 106 | } 107 | 108 | @media (max-width: 500px) { 109 | .md-social { 110 | flex: 1; 111 | position: inherit; 112 | } 113 | .md-footer-meta__inner { 114 | flex-direction: column; 115 | } 116 | } 117 | 118 | /* Search Bar in header customization */ 119 | .md-search__form { 120 | background-color: hsla(0, 0%, 100%, 0.06); 121 | } 122 | 123 | /* table width customization */ 124 | .md-typeset table:not([class]) th { 125 | min-width: 10rem; 126 | } 127 | 128 | /* md-button customization */ 129 | .md-typeset .md-button--primary { 130 | padding: 12px 20px; 131 | background-color: #138bff; 132 | border: 1px solid #138bff; 133 | border-radius: 4px; 134 | 135 | font-family: "SF Pro Text"; 136 | font-style: normal; 137 | font-weight: 600; 138 | font-size: 14px; 139 | line-height: 24px; 140 | 141 | color: white; 142 | } 143 | .md-typeset .md-button--primary:hover { 144 | background-color: white; 145 | border: 1px solid #138bff; 146 | color: #138bff; 147 | } 148 | 149 | /* Git commit information */ 150 | .md-source-file { 151 | display: flex; 152 | flex-direction: column; 153 | gap: 8px; 154 | } 155 | 156 | .md-source-file__fact { 157 | display: flex; 158 | flex-direction: row; 159 | gap: 8px; 160 | } 161 | 162 | .md-source-file__fact .md-icon { 163 | min-width: 24px; 164 | min-height: 24px; 165 | } -------------------------------------------------------------------------------- /docs/overrides/assets/fonts/SF-Pro-Display-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/overrides/assets/fonts/SF-Pro-Display-Bold.woff -------------------------------------------------------------------------------- /docs/overrides/assets/fonts/lg.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/overrides/assets/fonts/lg.ttf -------------------------------------------------------------------------------- /docs/overrides/assets/fonts/lg.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/overrides/assets/fonts/lg.woff -------------------------------------------------------------------------------- /docs/overrides/assets/fonts/sf-pro-text-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/overrides/assets/fonts/sf-pro-text-bold.woff -------------------------------------------------------------------------------- /docs/overrides/assets/fonts/sf-pro-text-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/overrides/assets/fonts/sf-pro-text-regular.woff -------------------------------------------------------------------------------- /docs/overrides/assets/imgs/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/overrides/assets/imgs/background.png -------------------------------------------------------------------------------- /docs/overrides/assets/imgs/branch-bottom.svg: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /docs/overrides/assets/imgs/circle-arrow.svg: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /docs/overrides/assets/imgs/favicon.svg: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /docs/overrides/assets/imgs/footer-logo.svg: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /docs/overrides/assets/imgs/git-contributors.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/assets/imgs/git-created.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/assets/imgs/git-updated.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/assets/imgs/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/protectai/nbdefense/f836d3702636b715058e6e80f53165414ee159ff/docs/overrides/assets/imgs/loading.gif -------------------------------------------------------------------------------- /docs/overrides/assets/imgs/vulnerability-cve.svg: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /docs/overrides/assets/imgs/vulnerability-pii.svg: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /docs/overrides/assets/imgs/vulnerability-secrets.svg: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /docs/overrides/assets/imgs/vulnerability-third-party.svg: -------------------------------------------------------------------------------- 1 | 22 | -------------------------------------------------------------------------------- /docs/overrides/assets/js/timeago_mkdocs.js: -------------------------------------------------------------------------------- 1 | const nodes = document.querySelectorAll(".timeago"); 2 | if (nodes.length > 0) { 3 | const locale = nodes[0].getAttribute("locale"); 4 | timeago.render(nodes, locale); 5 | } -------------------------------------------------------------------------------- /docs/overrides/main.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block extrahead %} 3 | {% endblock %} 4 | 5 | 6 | {% block article %} 7 | {{ super() }} 8 | {% include "partials/content.html" %} 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /docs/overrides/partials/content.html: -------------------------------------------------------------------------------- 1 | {% if "\x3ch1" not in page.content %} 2 |
Path: {{ issue_details.file_path }}
5 |Description:
6 |Could not find a pinned version for package `{{ issue_details.name }}`
7 |Path: {{ issue_details.file_path }}
5 |{{issue_details.name}}
9 |{{issue_details.version}}
13 |Path: {{ issue.details.file_path }}
4 |Description:
5 |{{ issue.details.description }} with the following tag(s):
6 |7 |
{{ issue.details.summary_field | to_pretty_json | scrub_html | safe }}8 | 9 |
10 | Location: cell {{ issue.location.value }} 11 |
12 |Cell #{{ issue.cell.cell_index }}
15 |Path: {{ issue.details.file_path }}
4 |Vulnerability: Exposed Secret
5 |Description:
6 |{{ issue.details.description | replace(",", ", ") }}
7 |8 | Location: cell {{ issue.details.location }} 9 |
10 |Cell #{{ issue.cell.cell_index }}
13 |Path: {{ issue_details.file_path }}
5 |License: {{issue_details.unapproved_license}}
6 |{{issue_details.package_name}}
10 |{{issue_details.package_version}}
14 |Path: {{ issue_details.file_path }}
5 |6 | Vulnerability: 7 | {{ issue_details.vulnerability['VulnerabilityID'] }} 14 |
15 |{{ issue_details.vulnerability['PkgName'] }}
19 |{{ issue_details.vulnerability['InstalledVersion'] }}
23 |{{ issue_details.vulnerability['FixedVersion'] }}
27 |