sbomify/sbomify

GitHub: sbomify/sbomify

软件物料清单(SBOM)和安全文档的集中管理平台,支持多格式聚合、合规检测和供应链透明化共享。

Stars: 46 | Forks: 8

![sbomify logo](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/8f173ed55a001858.svg) [![sbomified](https://sbomify.com/assets/images/logo/badge.svg)](https://app.sbomify.com/public/product/eP_4dk8ixV/) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/sbomify/sbomify/badge)](https://securityscorecards.dev/viewer/?uri=github.com/sbomify/sbomify&sort_by=check-score&sort_direction=desc) [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/10952/badge)](https://www.bestpractices.dev/projects/10952) [![Slack](https://img.shields.io/badge/Slack-Join%20Community-4A154B?logo=slack)](https://join.slack.com/t/sbomify/shared_invite/zt-3na54pa1f-MXrFWhotmZr0YxXc8sABTw) [![CI/CD Pipeline](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/e9c4dbbcdd001859.svg)](https://github.com/sbomify/sbomify/actions/workflows/ci-cd.yml) sbomify 是一个软件物料清单 (SBOM) 和文档管理平台,支持自托管或通过 [app.sbomify.com](https://app.sbomify.com) 访问。该平台提供了一个集中位置来上传和管理您的 SBOM 及相关文档,允许您与利益相关者共享或将其公开。 sbomify 后端与我们的 [github actions module](https://github.com/sbomify/sbomify-action) 集成,可从 lock 文件和 docker 文件自动生成 SBOM。 欲了解更多信息,请参阅 [sbomify.com](https://sbomify.com)。 ## 功能特性 ### SBOM 管理 - 支持 CycloneDX 和 SPDX SBOM 格式(包括 SPDX 3.0) - 通过 Web 界面或 API 上传 SBOM - 以多种格式为产品和发布版本生成聚合 SBOM: - CycloneDX 1.6, 1.7 - SPDX 2.3, 3.0 - 漏洞扫描集成 - 公共和私有访问控制 - 基于工作区的组织结构 ### 合规性插件 | Plugin | Type | Standard | | --------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | NTIA Minimum Elements (2021) | Compliance | [NTIA Minimum Elements for SBOM](https://www.ntia.gov/report/2021/minimum-elements-software-bill-materials-sbom) | | CISA Minimum Elements (2025 Draft) | Compliance | [CISA 2025 SBOM Minimum Elements](https://www.cisa.gov/sites/default/files/2025-08/2025_CISA_SBOM_Minimum_Elements.pdf) _(Public Comment Draft)_ | | BSI TR-03183-2 v2.1 (EU CRA) | Compliance | [BSI TR-03183-2: Cyber Resilience Requirements](https://bsi.bund.de/dok/TR-03183-en) | | FDA Medical Device Cybersecurity (2025) | Compliance | [FDA Cybersecurity in Medical Devices](https://www.fda.gov/media/119933/download) | | GitHub Artifact Attestation | Attestation | [GitHub Artifact Attestations](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations) | ### 文档管理 - 上传和管理文档工件(规范、手册、报告、合规文档等) - 将文档与软件组件关联 - 文档版本控制 - 使用可配置 S3 buckets 进行安全存储 - 公共和私有文档共享 ### 组织结构 - **Components (组件)**:核心实体,可包含 SBOM 或文档 - **Projects (项目)**:将相关组件组合在一起 - **Products (产品)**:组织多个项目 - **Workspaces (工作区)**:控制访问和权限 ### Transparency Exchange API (TEA) - 实现 [Transparency Exchange API](https://github.com/CycloneDX/transparency-exchange-api/) v0.3.0-beta.2 - 通过 `.well-known/tea` endpoints 进行标准化 SBOM 发现 - 支持跨供应链自动发现和检索 SBOM ## 发布 有关创建新发布版本的信息,请参阅 [RELEASE.md](docs/RELEASE.md)。 ## 架构决策记录 (ADRs) 我们使用架构决策记录 来记录本项目中做出的重大架构决策。ADR 为决策提供了背景和理由,帮助当前和未来的贡献者理解为何选择某些方法。 有关所有 ADR,请参阅 [docs/ADR](docs/ADR) 文件夹。 ## 部署 有关部署过程的详细信息,包括: - CI/CD workflow - 环境设置 - 存储配置 请参阅 [docs/deployment.md](docs/deployment.md)。 有关完整的生产部署说明,请参阅 [the deployment guide](docs/deployment.md)。 ## 本地开发 ### 开发期间的认证 对于本地开发,认证通过 Django 的 admin 界面处理: ``` # 为本地开发创建 superuser docker compose \ -f docker-compose.yml \ -f docker-compose.dev.yml exec \ sbomify-backend \ uv run python manage.py createsuperuser ``` 然后访问 `http://localhost:8000/admin` 处的 admin 界面登录。 ### 开发先决条件 - Python 3.13+ - uv (Python 包管理器) - Docker (用于运行 PostgreSQL 和 Minio) - Bun (用于 JavaScript 开发) #### 安装 uv - 使用官方安装程序安装 uv: ``` curl -LsSf https://astral.sh/uv/install.sh | sh ``` - 验证安装: ``` uv --version ``` #### 安装依赖项 - 使用 uv 安装 Python 依赖项: ``` # 安装所有依赖,包括开发依赖 uv sync # 使用 uv 运行命令 uv run python manage.py --help ``` - 使用 Bun 安装 JavaScript 依赖项: ``` bun install ``` ### API 文档 API 文档可在以下位置获取: - 交互式 API 文档 (Swagger UI): `http://localhost:8000/api/v1/docs` - OpenAPI 规范: `http://localhost:8000/api/v1/openapi.json` 该 API 提供用于管理的 endpoints: - **SBOMs**: 上传、检索和管理软件物料清单 - **Documents**: 上传、检索和管理文档工件 - **Components**: 管理包含 SBOM 或文档的组件 - **Projects & Products**: 组织和分组组件 - **Workspaces**: 用户管理和访问控制 #### 聚合 SBOM 下载 下载产品和发布版本的聚合 SBOM,并支持格式选择: ``` # 下载 CycloneDX 1.6 (默认) 格式的 release SBOM curl "https://app.sbomify.com/api/v1/releases/{release_id}/download" # 下载 SPDX 2.3 格式的 release SBOM curl "https://app.sbomify.com/api/v1/releases/{release_id}/download?format=spdx" # 下载 SPDX 3.0 格式的 release SBOM curl "https://app.sbomify.com/api/v1/releases/{release_id}/download?format=spdx&version=3.0" # 下载 CycloneDX 1.7 格式的 release SBOM curl "https://app.sbomify.com/api/v1/releases/{release_id}/download?format=cyclonedx&version=1.7" # 下载 SPDX 2.3 格式的 product SBOM curl "https://app.sbomify.com/api/v1/products/{product_id}/download?format=spdx&version=2.3" ``` **支持的格式和版本:** | Format | Versions | Default | | --------- | -------- | ------- | | CycloneDX | 1.6, 1.7 | 1.6 | | SPDX | 2.3, 3.0 | 2.3 | 这些 endpoints 在运行开发服务器时可用。 ### 设置 通过在 shell 中设置或使用 Docker Compose 覆盖文件来配置环境变量。 **重要:添加到 `/etc/hosts`** 为了使开发环境能够与 Keycloak 认证正常配合工作,您必须将以下条目添加到您的 `/etc/hosts` 文件中: ``` 127.0.0.1 keycloak ``` 启动开发环境(推荐方法): ``` ./bin/developer_mode.sh build ./bin/developer_mode.sh up ``` 创建本地管理员账户: ``` docker compose \ -f docker-compose.yml \ -f docker-compose.dev.yml exec \ -e DJANGO_SUPERUSER_USERNAME=sbomifyadmin \ -e DJANGO_SUPERUSER_PASSWORD=sbomifyadmin \ -e DJANGO_SUPERUSER_EMAIL=admin@sbomify.com \ sbomify-backend \ uv run python manage.py createsuperuser --noinput ``` 访问应用程序: - Admin 界面: `http://localhost:8000/admin` - 主应用程序: `http://localhost:8000` #### 替代方案:本地运行(Django 不在 Docker 中) - 在 Docker 中启动所需服务: ``` # 同时启动 PostgreSQL 和 MinIO docker compose up sbomify-db sbomify-minio sbomify-createbuckets -d ``` - 安装依赖项: ``` uv sync bun install # for JavaScript dependencies ``` - 运行迁移: ``` uv run python manage.py migrate ``` - 启动开发服务器: ``` # 在一个终端中,启动 Django uv run python manage.py runserver # 在另一个终端中,启动 Vite bun run dev ``` ### 配置 #### 开发服务器设置 应用程序使用 Vite 进行 JavaScript 开发。以下环境变量控制开发服务器: ``` # Vite 开发设置 DJANGO_VITE_DEV_MODE=True DJANGO_VITE_DEV_SERVER_PORT=5170 DJANGO_VITE_DEV_SERVER_HOST=http://localhost # 静态文件和开发服务器设置 STATIC_URL=/static/ DEV_JS_SERVER=http://127.0.0.1:5170 WEBSITE_BASE_URL=http://127.0.0.1:8000 VITE_API_BASE_URL=http://127.0.0.1:8000/api/v1 VITE_WEBSITE_BASE_URL=http://127.0.0.1:8000 ``` 这些设置可以使用环境变量进行配置。 #### Keycloak 认证设置 Keycloak 现作为 Docker Compose 环境的一部分进行管理。您无需手动运行 Keycloak。 Keycloak 的持久化存储由 Docker 使用命名卷 (`keycloak_data`) 管理。 ##### Keycloak 引导 当您使用 Docker Compose 启动开发环境时,Keycloak 会使用位于 `bin/keycloak-bootstrap.sh` 的脚本自动进行引导。此脚本使用环境变量(例如 `KEYCLOAK_REALM`、`KEYCLOAK_CLIENT_ID`、`KEYCLOAK_ADMIN_USERNAME`、`KEYCLOAK_ADMIN_PASSWORD`、`KEYCLOAK_CLIENT_SECRET` 等)来配置 realm、client 和凭据。**您无需编辑脚本本身**——只需在 Docker Compose 配置中设置适当的环境变量即可控制引导过程。 在开发模式下运行时(使用 `docker-compose.dev.yml`),引导脚本会自动: - **禁用 SSL 要求**,以便于本地开发 - **创建测试用户**用于认证测试: - **John Doe** - 用户名: `jdoe`, 密码: `foobar123`, 邮箱: `jdoe@example.com` - **Steve Smith** - 用户名: `ssmith`, 密码: `foobar123`, 邮箱: `ssmith@example.com` 这些特定于开发的配置由 `KEYCLOAK_DEV_MODE` 环境变量控制,仅在运行开发 Docker Compose 堆栈时应用。 要在开发环境中启动 Keycloak(及所有其他服务),只需运行: ``` docker compose -f docker-compose.yml -f docker-compose.dev.yml up ``` Keycloak 将在 处可用。 #### S3/Minio 存储 应用程序使用兼容 S3 的存储来存储文件和资产。在开发中,我们使用 Minio 作为本地 S3 替代品。 - 使用 Docker Compose 运行时,一切都会自动配置 - 本地运行时(Django 在 Docker 外部): - 确保通过 Docker 运行 Minio: `docker compose up sbomify-minio sbomify-createbuckets -d` - 在您的环境变量中设置 `AWS_ENDPOINT_URL_S3=http://localhost:9000` - 所需的 buckets (`sbomify-media`, `sbomify-sboms`, 以及可选的 `sbomify-documents`) 将自动创建 ##### 存储 Buckets 应用程序针对不同类型的内容使用独立的 S3 buckets: - **Media Bucket**: 用户头像、工作区 logo 和其他媒体资产 - **SBOMs Bucket**: 软件物料清单文件 - **Documents Bucket**: 文档工件(规范、手册、报告、合规文档等) - 如果未单独配置,文档将自动使用 SBOMs bucket - 对于生产环境,建议使用单独的 bucket 以便更好地组织和访问控制 您可以访问 Minio 控制台: - `http://localhost:9001` - 默认凭据: minioadmin/minioadmin ##### 生产存储配置 对于生产部署,您可以为文档配置独立的 S3 buckets: ``` # 可选:配置专用 documents bucket(推荐用于生产环境) export AWS_DOCUMENTS_ACCESS_KEY_ID="your-documents-access-key" export AWS_DOCUMENTS_SECRET_ACCESS_KEY="your-documents-secret-key" export AWS_DOCUMENTS_STORAGE_BUCKET_NAME="your-documents-bucket" export AWS_DOCUMENTS_STORAGE_BUCKET_URL="https://your-documents-bucket.s3.region.amazonaws.com" # 如果未配置,documents 将自动使用 SBOMs bucket export AWS_SBOMS_ACCESS_KEY_ID="your-sboms-access-key" export AWS_SBOMS_SECRET_ACCESS_KEY="your-sboms-secret-key" export AWS_SBOMS_STORAGE_BUCKET_NAME="your-sboms-bucket" export AWS_SBOMS_STORAGE_BUCKET_URL="https://your-sboms-bucket.s3.region.amazonaws.com" ``` 独立 buckets 的优势: - **安全性**: 针对 SBOM 与文档采用不同的访问策略 - **组织性**: 清晰区分内容类型 - **备份**: 针对不同数据类型的独立备份策略 #### Dependency Track 集成 sbomify 支持与 [Dependency Track](https://dependencytrack.org/) 集成,以进行高级漏洞管理和分析。Dependency Track 集成适用于商业版和企业版计划。 **注意:** Dependency Track 仅支持 CycloneDX 格式的 SBOM。无论工作区配置如何,SPDX SBOM 将自动使用 OSV 扫描。 ##### 基于环境的项目命名 当跨多个环境(开发、预发布、生产)使用共享的 Dependency Track 实例时,sbomify 会自动为项目名称添加环境前缀以帮助区分它们: **示例:** - **生产环境** (`https://app.sbomify.com`): `prod-sbomify-{component-id}` - **预发布环境** (`https://staging.sbomify.com`): `staging-sbomify-{component-id}` - **开发环境** (`https://dev.sbomify.com`): `dev-sbomify-{component-id}` - **本地环境** (`http://localhost:8000`): `local-sbomify-{component-id}` **自定义环境前缀:** 您可以通过设置 `DT_ENVIRONMENT_PREFIX` 环境变量来覆盖自动检测: ``` export DT_ENVIRONMENT_PREFIX="my-custom-env" # 结果为:my-custom-env-sbomify-{component-id} ``` 这使得在查看 Dependency Track 仪表板时可以轻松识别项目所属的环境。 ##### 所需权限 要与 Dependency Track 集成,您需要创建一个具有以下权限的 API token: - `BOM_UPLOAD` - `PROJECT_CREATION_UPLOAD` - `VIEW_PORTFOLIO` - `VIEW_VULNERABILITY` 您可以在 Dependency Track 实例的 **Administration → Access Management** 下创建 token(使用那里的工作区管理界面)。 ##### DT 配置 1. **通过 Django admin 添加 Dependency Track Server**: - 导航至 `/admin/vulnerability_scanning/dependencytrackserver/` - 点击 "Add Dependency Track Server" - 填写服务器详细信息: - **Name**: 服务器的友好名称 - **URL**: 您的 Dependency Track 实例的基础 URL - **API Key**: 具有所需权限的 Token - **Priority**: 数字越小 = 负载均衡优先级越高 - **Max Concurrent Scans**: 同时上传 SBOM 的最大数量 2. **配置工作区设置**: - 商业版/企业版工作区可以在 **Settings → Integrations** 中选择 Dependency Track - 企业版工作区可以选择配置自定义 Dependency Track 实例 - 商业版工作区使用共享服务器池 ##### DT 功能特性 - **自动漏洞扫描**: - 社区版工作区:使用 OSV 进行每周漏洞扫描 - 商业版/企业版工作区:使用 Dependency Track 每 12 小时更新一次漏洞信息 - **负载均衡**: 在多个 Dependency Track 服务器之间分配扫描任务 - **健康监控**: 自动服务器健康检查和容量管理 - **历史跟踪**: 完整的扫描结果历史记录,用于趋势分析 - **统一结果**: 跨 OSV 和 Dependency Track 的一致漏洞数据格式 ### 行测试用例 在运行测试之前,您需要启动 docker-compose.tests.yml: ``` docker compose -f docker-compose.tests.yml up -d ``` 使用 Django 的 test profile 运行测试: ``` # 运行所有测试并生成覆盖率 uv run coverage run -m pytest # 运行特定测试组 uv run coverage run -m pytest core/tests/ uv run coverage run -m pytest sboms/tests/ uv run coverage run -m pytest teams/tests/ # 在失败时运行 debugger uv run coverage run -m pytest --pdb -x -s # 生成覆盖率报告 uv run coverage report ``` 测试覆盖率必须至少达到 80% 才能通过 CI 检查。 ### E2E 快照 (截图) 测试 该项目包含端到端快照测试,用于捕获 UI 的截图并将其与基准图像进行比较。这有助于确保不同屏幕尺寸下以及代码更改后的视觉一致性。 #### E2E 测试先决条件 在运行 e2e 快照测试之前,您需要: **构建 JavaScript 资产:** ``` bun run build ``` 这确保在截图之前所有静态资产(JavaScript, CSS)都是最新的。 #### 编写快照测试 以下是编写快照测试的抽象示例: ``` @pytest.mark.django_db @pytest.mark.parametrize("width", [1920, 992, 576, 375]) class TestYourPageSnapshot: def test_your_page_snapshot( self, authenticated_page, your_test_fixtures, # noqa: F811 snapshot, width: int, ) -> None: # Navigate to the page you want to test authenticated_page.goto("/your-page") authenticated_page.wait_for_load_state("networkidle") # Get or create baseline screenshot (stored in __snapshots__) baseline = snapshot.get_or_create_baseline_screenshot(authenticated_page, width=width) # Take current screenshot current = snapshot.take_screenshot(authenticated_page, width=width) # Compare screenshots snapshot.assert_screenshot(baseline.as_posix(), current.as_posix()) ``` **关键组件:** - 使用 `@pytest.mark.django_db` 启用数据库访问 - 使用 `@pytest.mark.parametrize("width", [...])` 测试多种屏幕尺寸 - 注入 `authenticated_page` fixture 用于浏览器自动化 - 注入 `snapshot` fixture 用于截图管理 - 使用 `get_or_create_baseline_screenshot()` 获取基准(如果缺失则创建) - 使用 `take_screenshot()` 捕获当前状态 - 使用 `assert_screenshot()` 进行比较 #### 运行 E2E 快照测试 构建资产后,您可以使用专用的 E2E docker-compose 堆栈来运行快照测试: ``` # 启动测试 stack(数据库、chromium 和 tests container) docker compose -f docker-compose.tests.yml up -d # 在 tests container 内运行所有 E2E snapshot 测试 docker compose -f docker-compose.tests.yml exec tests uv run pytest sbomify/apps//tests/e2e/ # 运行单个 E2E snapshot 测试(示例) docker compose -f docker-compose.tests.yml exec tests uv run pytest \ sbomify/apps//tests/e2e/test_your_page.py::TestYourPageSnapshot::test_your_page_snapshot[1920] ``` #### 处理快照测试 **新测试** 当您编写新的快照测试时,它会自动在 `__snapshots__` 目录(位于 `sbomify/apps//tests/e2e/__snapshots__/`)中创建基准截图。只需运行测试并验证生成的截图看起来是否正确。 **现有测试 - 通过** 如果测试已存在并通过,则一切按预期工作。无需操作。 **现有测试 - 失败** 如果测试失败,请检查 `__diffs__` 目录(位于 `sbomify/apps//tests/e2e/__diffs__/`)以查看更改内容。差异图像显示基准截图与当前截图之间的差异。 **更新过时的快照** 如果 `__diffs__` 中的差异截图显示新的视觉状态是正确的(即基准快照已过时),您需要更新基准: 1. 从 `__snapshots__` 中删除过时的快照文件 2. 重新运行测试 - 它将使用当前状态自动重新创建基准截图 **示例:** ``` # 删除过期的 snapshot rm sbomify/apps//tests/e2e/__snapshots__/test_your_page_snapshot[1920].jpg # 重新运行测试以创建新基线 uv run pytest sbomify/apps//tests/e2e/test_your_page.py::TestYourPageSnapshot::test_your_page_snapshot ``` 有关实际示例,请参阅 `sbomify/apps/core/tests/e2e/test_dashboard.py`。 ### 测试数据管理 应用程序包含管理命令,以帮助您在开发环境中设置和管理测试数据: ``` # 使用示例 SBOM 数据创建测试环境 # 如果未指定 workspace,则使用数据库中的第一个 workspace # (management command 保留了旧的 --team-id flag 名称以保持兼容性) python manage.py create_test_sbom_environment # 为特定 workspace 创建测试环境(仍使用旧的 --team-id flag) python manage.py create_test_sbom_environment --team-id=your_team_id # 清理现有测试数据并创建新环境 python manage.py create_test_sbom_environment --clean # 清理所有 workspace 的所有测试数据 python manage.py cleanup_test_sbom_environment # 清理特定 workspace 的测试数据(仍使用旧的 --team-id flag) python manage.py cleanup_test_sbom_environment --team-id=your_team_id # 预览将被删除的内容(dry run) python manage.py cleanup_test_sbom_environment --dry-run ``` 这些命令将: 1. 创建测试产品、项目和组件 2. 从测试文件加载真实的 SBOM 数据(SPDX 和 CycloneDX 格式) 3. 设置所有实体之间的正确关系 4. 允许您在需要时清理测试数据 测试数据按来源(例如 hello-world 和 sbomify)而不是按格式分组,因此每个组件都将附加 SPDX 和 CycloneDX SBOM。 注意:您必须在数据库中至少拥有一个工作区,才能在不指定旧版 `--team-id` 标志的情况下使用这些命令。 ### JS 构建工具 对于前端 JS 工作,需要设置 JS 工具。 #### Bun ``` curl -fsSL https://bun.sh/install | bash ``` 在 `package.json` 同级的文件夹中: ``` bun install ``` #### Linting 对于 JavaScript/TypeScript linting: ``` # 检查 linting 问题(用于 CI,也可在本地运行) bun lint # 自动修复 linting 问题(仅限本地开发) bun lint-fix ``` #### 运行 vite dev server ``` bun run dev ``` ### Pre-commit 检查 该项目使用 pre-commit hooks 来确保代码质量和一致性。hooks 会检查: - 代码格式化 (ruff-format) - Python linting (ruff) - 安全问题 (bandit) - Markdown 格式化 - TypeScript 类型检查 - JavaScript/TypeScript linting - 合并冲突 - Debug 语句 设置 pre-commit: - 安装 pre-commit hooks: ``` uv run pre-commit install ``` - 手动运行 pre-commit 检查: ``` # 检查所有文件 uv run pre-commit run --all-files # 仅检查暂存文件 uv run pre-commit run ``` ## 生产部署 ### 生产环境先决条件 - Docker 和 Docker Compose - 兼容 S3 的存储(如 Amazon S3 或 Google Cloud Storage) - PostgreSQL 数据库 - 用于生产部署的反向代理(例如 Nginx) ### Docker Compose 配置 提供了 `docker-compose.prod.yml` 文件用于类生产设置。**注意:** 此配置未经过充分测试,不建议按原样用于实际生产环境。提供的设置仅用于演示和预发布目的,未来将会更新和改进。 对于生产部署,为签名 URL 生成一个安全的签名 salt: ``` # 为 signed URLs 生成安全 signing salt export SIGNED_URL_SALT="$(openssl rand -hex 32)" ``` `SIGNED_URL_SALT` 用于为产品/项目 SBOM 中的私有组件的下载 URL 进行签名。 要尝试类生产堆栈: ``` docker compose -f docker-compose.yml -f docker-compose.prod.yml build docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d ``` 您需要设置适当的环境变量,并确保您的反向代理、存储和数据库已安全配置。
标签:API集成, CycloneDX, DevSecOps, Docker, GitHub Actions, IP 地址批量处理, SaaS, SBOM, SPDX, 上游代理, 产品安全, 人工智能安全, 信任中心, 制品仓库, 可观测性, 合规性, 安全管理, 安全防御评估, 开源治理, 文档安全, 文档管理, 测试用例, 漏洞探索, 硬件无关, 私有化部署, 自动笔记, 请求拦截, 跌倒检测, 软件开发工具包, 软件物料清单, 逆向工具, 防御规避