@wazir-dev/cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +111 -0
- package/CHANGELOG.md +14 -0
- package/CONTRIBUTING.md +101 -0
- package/LICENSE +21 -0
- package/README.md +314 -0
- package/assets/composition-engine.mmd +34 -0
- package/assets/demo-script.sh +17 -0
- package/assets/logo-dark.svg +14 -0
- package/assets/logo.svg +14 -0
- package/assets/pipeline.mmd +39 -0
- package/assets/record-demo.sh +51 -0
- package/docs/README.md +51 -0
- package/docs/adapters/context-mode.md +60 -0
- package/docs/concepts/architecture.md +87 -0
- package/docs/concepts/artifact-model.md +60 -0
- package/docs/concepts/composition-engine.md +36 -0
- package/docs/concepts/indexing-and-recall.md +160 -0
- package/docs/concepts/observability.md +41 -0
- package/docs/concepts/roles-and-workflows.md +59 -0
- package/docs/concepts/terminology-policy.md +27 -0
- package/docs/getting-started/01-installation.md +78 -0
- package/docs/getting-started/02-first-run.md +102 -0
- package/docs/getting-started/03-adding-to-project.md +15 -0
- package/docs/getting-started/04-host-setup.md +15 -0
- package/docs/guides/ci-integration.md +15 -0
- package/docs/guides/creating-skills.md +15 -0
- package/docs/guides/expertise-module-authoring.md +15 -0
- package/docs/guides/hook-development.md +15 -0
- package/docs/guides/memory-and-learnings.md +34 -0
- package/docs/guides/multi-host-export.md +15 -0
- package/docs/guides/troubleshooting.md +101 -0
- package/docs/guides/writing-custom-roles.md +15 -0
- package/docs/plans/2026-03-15-cli-pipeline-integration-design.md +592 -0
- package/docs/plans/2026-03-15-cli-pipeline-integration-plan.md +598 -0
- package/docs/plans/2026-03-15-docs-enforcement-plan.md +238 -0
- package/docs/readmes/INDEX.md +99 -0
- package/docs/readmes/features/expertise/README.md +171 -0
- package/docs/readmes/features/exports/README.md +222 -0
- package/docs/readmes/features/hooks/README.md +103 -0
- package/docs/readmes/features/hooks/loop-cap-guard.md +133 -0
- package/docs/readmes/features/hooks/post-tool-capture.md +121 -0
- package/docs/readmes/features/hooks/post-tool-lint.md +130 -0
- package/docs/readmes/features/hooks/pre-compact-summary.md +122 -0
- package/docs/readmes/features/hooks/pre-tool-capture-route.md +100 -0
- package/docs/readmes/features/hooks/protected-path-write-guard.md +128 -0
- package/docs/readmes/features/hooks/session-start.md +119 -0
- package/docs/readmes/features/hooks/stop-handoff-harvest.md +125 -0
- package/docs/readmes/features/roles/README.md +157 -0
- package/docs/readmes/features/roles/clarifier.md +152 -0
- package/docs/readmes/features/roles/content-author.md +190 -0
- package/docs/readmes/features/roles/designer.md +193 -0
- package/docs/readmes/features/roles/executor.md +184 -0
- package/docs/readmes/features/roles/learner.md +210 -0
- package/docs/readmes/features/roles/planner.md +182 -0
- package/docs/readmes/features/roles/researcher.md +164 -0
- package/docs/readmes/features/roles/reviewer.md +184 -0
- package/docs/readmes/features/roles/specifier.md +162 -0
- package/docs/readmes/features/roles/verifier.md +215 -0
- package/docs/readmes/features/schemas/README.md +178 -0
- package/docs/readmes/features/skills/README.md +63 -0
- package/docs/readmes/features/skills/brainstorming.md +96 -0
- package/docs/readmes/features/skills/debugging.md +148 -0
- package/docs/readmes/features/skills/design.md +120 -0
- package/docs/readmes/features/skills/prepare-next.md +109 -0
- package/docs/readmes/features/skills/run-audit.md +159 -0
- package/docs/readmes/features/skills/scan-project.md +109 -0
- package/docs/readmes/features/skills/self-audit.md +176 -0
- package/docs/readmes/features/skills/tdd.md +137 -0
- package/docs/readmes/features/skills/using-skills.md +92 -0
- package/docs/readmes/features/skills/verification.md +120 -0
- package/docs/readmes/features/skills/writing-plans.md +104 -0
- package/docs/readmes/features/tooling/README.md +320 -0
- package/docs/readmes/features/workflows/README.md +186 -0
- package/docs/readmes/features/workflows/author.md +181 -0
- package/docs/readmes/features/workflows/clarify.md +154 -0
- package/docs/readmes/features/workflows/design-review.md +171 -0
- package/docs/readmes/features/workflows/design.md +169 -0
- package/docs/readmes/features/workflows/discover.md +162 -0
- package/docs/readmes/features/workflows/execute.md +173 -0
- package/docs/readmes/features/workflows/learn.md +167 -0
- package/docs/readmes/features/workflows/plan-review.md +165 -0
- package/docs/readmes/features/workflows/plan.md +170 -0
- package/docs/readmes/features/workflows/prepare-next.md +167 -0
- package/docs/readmes/features/workflows/review.md +169 -0
- package/docs/readmes/features/workflows/run-audit.md +191 -0
- package/docs/readmes/features/workflows/spec-challenge.md +159 -0
- package/docs/readmes/features/workflows/specify.md +160 -0
- package/docs/readmes/features/workflows/verify.md +177 -0
- package/docs/readmes/packages/README.md +50 -0
- package/docs/readmes/packages/ajv.md +117 -0
- package/docs/readmes/packages/context-mode.md +118 -0
- package/docs/readmes/packages/gray-matter.md +116 -0
- package/docs/readmes/packages/node-test.md +137 -0
- package/docs/readmes/packages/yaml.md +112 -0
- package/docs/reference/configuration-reference.md +159 -0
- package/docs/reference/expertise-index.md +52 -0
- package/docs/reference/git-flow.md +43 -0
- package/docs/reference/hooks.md +87 -0
- package/docs/reference/host-exports.md +50 -0
- package/docs/reference/launch-checklist.md +172 -0
- package/docs/reference/marketplace-listings.md +76 -0
- package/docs/reference/release-process.md +34 -0
- package/docs/reference/roles-reference.md +77 -0
- package/docs/reference/skills.md +33 -0
- package/docs/reference/templates.md +29 -0
- package/docs/reference/tooling-cli.md +94 -0
- package/docs/truth-claims.yaml +222 -0
- package/expertise/PROGRESS.md +63 -0
- package/expertise/README.md +18 -0
- package/expertise/antipatterns/PROGRESS.md +56 -0
- package/expertise/antipatterns/backend/api-design-antipatterns.md +1271 -0
- package/expertise/antipatterns/backend/auth-antipatterns.md +1195 -0
- package/expertise/antipatterns/backend/caching-antipatterns.md +622 -0
- package/expertise/antipatterns/backend/database-antipatterns.md +1038 -0
- package/expertise/antipatterns/backend/index.md +24 -0
- package/expertise/antipatterns/backend/microservices-antipatterns.md +850 -0
- package/expertise/antipatterns/code/architecture-antipatterns.md +919 -0
- package/expertise/antipatterns/code/async-antipatterns.md +622 -0
- package/expertise/antipatterns/code/code-smells.md +1186 -0
- package/expertise/antipatterns/code/dependency-antipatterns.md +1209 -0
- package/expertise/antipatterns/code/error-handling-antipatterns.md +1360 -0
- package/expertise/antipatterns/code/index.md +27 -0
- package/expertise/antipatterns/code/naming-and-abstraction.md +1118 -0
- package/expertise/antipatterns/code/state-management-antipatterns.md +1076 -0
- package/expertise/antipatterns/code/testing-antipatterns.md +1053 -0
- package/expertise/antipatterns/design/accessibility-antipatterns.md +1136 -0
- package/expertise/antipatterns/design/dark-patterns.md +1121 -0
- package/expertise/antipatterns/design/index.md +22 -0
- package/expertise/antipatterns/design/ui-antipatterns.md +1202 -0
- package/expertise/antipatterns/design/ux-antipatterns.md +680 -0
- package/expertise/antipatterns/frontend/css-layout-antipatterns.md +691 -0
- package/expertise/antipatterns/frontend/flutter-antipatterns.md +1827 -0
- package/expertise/antipatterns/frontend/index.md +23 -0
- package/expertise/antipatterns/frontend/mobile-antipatterns.md +573 -0
- package/expertise/antipatterns/frontend/react-antipatterns.md +1128 -0
- package/expertise/antipatterns/frontend/spa-antipatterns.md +1235 -0
- package/expertise/antipatterns/index.md +31 -0
- package/expertise/antipatterns/performance/index.md +20 -0
- package/expertise/antipatterns/performance/performance-antipatterns.md +1013 -0
- package/expertise/antipatterns/performance/premature-optimization.md +623 -0
- package/expertise/antipatterns/performance/scaling-antipatterns.md +785 -0
- package/expertise/antipatterns/process/ai-coding-antipatterns.md +853 -0
- package/expertise/antipatterns/process/code-review-antipatterns.md +656 -0
- package/expertise/antipatterns/process/deployment-antipatterns.md +920 -0
- package/expertise/antipatterns/process/index.md +23 -0
- package/expertise/antipatterns/process/technical-debt-antipatterns.md +647 -0
- package/expertise/antipatterns/security/index.md +20 -0
- package/expertise/antipatterns/security/secrets-antipatterns.md +849 -0
- package/expertise/antipatterns/security/security-theater.md +843 -0
- package/expertise/antipatterns/security/vulnerability-patterns.md +801 -0
- package/expertise/architecture/PROGRESS.md +70 -0
- package/expertise/architecture/data/caching-architecture.md +671 -0
- package/expertise/architecture/data/data-consistency.md +574 -0
- package/expertise/architecture/data/data-modeling.md +536 -0
- package/expertise/architecture/data/event-streams-and-queues.md +634 -0
- package/expertise/architecture/data/index.md +25 -0
- package/expertise/architecture/data/search-architecture.md +663 -0
- package/expertise/architecture/data/sql-vs-nosql.md +708 -0
- package/expertise/architecture/decisions/architecture-decision-records.md +640 -0
- package/expertise/architecture/decisions/build-vs-buy.md +616 -0
- package/expertise/architecture/decisions/index.md +23 -0
- package/expertise/architecture/decisions/monolith-to-microservices.md +790 -0
- package/expertise/architecture/decisions/technology-selection.md +616 -0
- package/expertise/architecture/distributed/cap-theorem-and-tradeoffs.md +800 -0
- package/expertise/architecture/distributed/circuit-breaker-bulkhead.md +741 -0
- package/expertise/architecture/distributed/consensus-and-coordination.md +796 -0
- package/expertise/architecture/distributed/distributed-systems-fundamentals.md +564 -0
- package/expertise/architecture/distributed/idempotency-and-retry.md +796 -0
- package/expertise/architecture/distributed/index.md +25 -0
- package/expertise/architecture/distributed/saga-pattern.md +797 -0
- package/expertise/architecture/foundations/architectural-thinking.md +460 -0
- package/expertise/architecture/foundations/coupling-and-cohesion.md +770 -0
- package/expertise/architecture/foundations/design-principles-solid.md +649 -0
- package/expertise/architecture/foundations/domain-driven-design.md +719 -0
- package/expertise/architecture/foundations/index.md +25 -0
- package/expertise/architecture/foundations/separation-of-concerns.md +472 -0
- package/expertise/architecture/foundations/twelve-factor-app.md +797 -0
- package/expertise/architecture/index.md +34 -0
- package/expertise/architecture/integration/api-design-graphql.md +638 -0
- package/expertise/architecture/integration/api-design-grpc.md +804 -0
- package/expertise/architecture/integration/api-design-rest.md +892 -0
- package/expertise/architecture/integration/index.md +25 -0
- package/expertise/architecture/integration/third-party-integration.md +795 -0
- package/expertise/architecture/integration/webhooks-and-callbacks.md +1152 -0
- package/expertise/architecture/integration/websockets-realtime.md +791 -0
- package/expertise/architecture/mobile-architecture/index.md +22 -0
- package/expertise/architecture/mobile-architecture/mobile-app-architecture.md +780 -0
- package/expertise/architecture/mobile-architecture/mobile-backend-for-frontend.md +670 -0
- package/expertise/architecture/mobile-architecture/offline-first.md +719 -0
- package/expertise/architecture/mobile-architecture/push-and-sync.md +782 -0
- package/expertise/architecture/patterns/cqrs-event-sourcing.md +717 -0
- package/expertise/architecture/patterns/event-driven.md +797 -0
- package/expertise/architecture/patterns/hexagonal-clean-architecture.md +870 -0
- package/expertise/architecture/patterns/index.md +27 -0
- package/expertise/architecture/patterns/layered-architecture.md +736 -0
- package/expertise/architecture/patterns/microservices.md +753 -0
- package/expertise/architecture/patterns/modular-monolith.md +692 -0
- package/expertise/architecture/patterns/monolith.md +626 -0
- package/expertise/architecture/patterns/plugin-architecture.md +735 -0
- package/expertise/architecture/patterns/serverless.md +780 -0
- package/expertise/architecture/scaling/database-scaling.md +615 -0
- package/expertise/architecture/scaling/feature-flags-and-rollouts.md +757 -0
- package/expertise/architecture/scaling/horizontal-vs-vertical.md +606 -0
- package/expertise/architecture/scaling/index.md +24 -0
- package/expertise/architecture/scaling/multi-tenancy.md +800 -0
- package/expertise/architecture/scaling/stateless-design.md +787 -0
- package/expertise/backend/embedded-firmware.md +625 -0
- package/expertise/backend/go.md +853 -0
- package/expertise/backend/index.md +24 -0
- package/expertise/backend/java-spring.md +448 -0
- package/expertise/backend/node-typescript.md +625 -0
- package/expertise/backend/python-fastapi.md +724 -0
- package/expertise/backend/rust.md +458 -0
- package/expertise/backend/solidity.md +711 -0
- package/expertise/composition-map.yaml +443 -0
- package/expertise/content/foundations/content-modeling.md +395 -0
- package/expertise/content/foundations/editorial-standards.md +449 -0
- package/expertise/content/foundations/index.md +24 -0
- package/expertise/content/foundations/microcopy.md +455 -0
- package/expertise/content/foundations/terminology-governance.md +509 -0
- package/expertise/content/index.md +34 -0
- package/expertise/content/patterns/accessibility-copy.md +518 -0
- package/expertise/content/patterns/index.md +24 -0
- package/expertise/content/patterns/notification-content.md +433 -0
- package/expertise/content/patterns/sample-content.md +486 -0
- package/expertise/content/patterns/state-copy.md +439 -0
- package/expertise/design/PROGRESS.md +58 -0
- package/expertise/design/disciplines/dark-mode-theming.md +577 -0
- package/expertise/design/disciplines/design-systems.md +595 -0
- package/expertise/design/disciplines/index.md +25 -0
- package/expertise/design/disciplines/information-architecture.md +800 -0
- package/expertise/design/disciplines/interaction-design.md +788 -0
- package/expertise/design/disciplines/responsive-design.md +552 -0
- package/expertise/design/disciplines/usability-testing.md +516 -0
- package/expertise/design/disciplines/user-research.md +792 -0
- package/expertise/design/foundations/accessibility-design.md +796 -0
- package/expertise/design/foundations/color-theory.md +797 -0
- package/expertise/design/foundations/iconography.md +795 -0
- package/expertise/design/foundations/index.md +26 -0
- package/expertise/design/foundations/motion-and-animation.md +653 -0
- package/expertise/design/foundations/rtl-design.md +585 -0
- package/expertise/design/foundations/spacing-and-layout.md +607 -0
- package/expertise/design/foundations/typography.md +800 -0
- package/expertise/design/foundations/visual-hierarchy.md +761 -0
- package/expertise/design/index.md +32 -0
- package/expertise/design/patterns/authentication-flows.md +474 -0
- package/expertise/design/patterns/content-consumption.md +789 -0
- package/expertise/design/patterns/data-display.md +618 -0
- package/expertise/design/patterns/e-commerce.md +1494 -0
- package/expertise/design/patterns/feedback-and-states.md +642 -0
- package/expertise/design/patterns/forms-and-input.md +819 -0
- package/expertise/design/patterns/gamification.md +801 -0
- package/expertise/design/patterns/index.md +31 -0
- package/expertise/design/patterns/microinteractions.md +449 -0
- package/expertise/design/patterns/navigation.md +800 -0
- package/expertise/design/patterns/notifications.md +705 -0
- package/expertise/design/patterns/onboarding.md +700 -0
- package/expertise/design/patterns/search-and-filter.md +601 -0
- package/expertise/design/patterns/settings-and-preferences.md +768 -0
- package/expertise/design/patterns/social-and-community.md +748 -0
- package/expertise/design/platforms/desktop-native.md +612 -0
- package/expertise/design/platforms/index.md +25 -0
- package/expertise/design/platforms/mobile-android.md +825 -0
- package/expertise/design/platforms/mobile-cross-platform.md +983 -0
- package/expertise/design/platforms/mobile-ios.md +699 -0
- package/expertise/design/platforms/tablet.md +794 -0
- package/expertise/design/platforms/web-dashboard.md +790 -0
- package/expertise/design/platforms/web-responsive.md +550 -0
- package/expertise/design/psychology/behavioral-nudges.md +449 -0
- package/expertise/design/psychology/cognitive-load.md +1191 -0
- package/expertise/design/psychology/error-psychology.md +778 -0
- package/expertise/design/psychology/index.md +22 -0
- package/expertise/design/psychology/persuasive-design.md +736 -0
- package/expertise/design/psychology/user-mental-models.md +623 -0
- package/expertise/design/tooling/open-pencil.md +266 -0
- package/expertise/frontend/angular.md +1073 -0
- package/expertise/frontend/desktop-electron.md +546 -0
- package/expertise/frontend/flutter.md +782 -0
- package/expertise/frontend/index.md +27 -0
- package/expertise/frontend/native-android.md +409 -0
- package/expertise/frontend/native-ios.md +490 -0
- package/expertise/frontend/react-native.md +1160 -0
- package/expertise/frontend/react.md +808 -0
- package/expertise/frontend/vue.md +1089 -0
- package/expertise/humanize/domain-rules-code.md +79 -0
- package/expertise/humanize/domain-rules-content.md +67 -0
- package/expertise/humanize/domain-rules-technical-docs.md +56 -0
- package/expertise/humanize/index.md +35 -0
- package/expertise/humanize/self-audit-checklist.md +87 -0
- package/expertise/humanize/sentence-patterns.md +218 -0
- package/expertise/humanize/vocabulary-blacklist.md +105 -0
- package/expertise/i18n/PROGRESS.md +65 -0
- package/expertise/i18n/advanced/accessibility-and-i18n.md +28 -0
- package/expertise/i18n/advanced/bidirectional-text-algorithm.md +38 -0
- package/expertise/i18n/advanced/complex-scripts.md +30 -0
- package/expertise/i18n/advanced/performance-and-i18n.md +27 -0
- package/expertise/i18n/advanced/testing-i18n.md +28 -0
- package/expertise/i18n/content/content-adaptation.md +23 -0
- package/expertise/i18n/content/locale-specific-formatting.md +23 -0
- package/expertise/i18n/content/machine-translation-integration.md +28 -0
- package/expertise/i18n/content/translation-management.md +29 -0
- package/expertise/i18n/foundations/date-time-calendars.md +67 -0
- package/expertise/i18n/foundations/i18n-architecture.md +272 -0
- package/expertise/i18n/foundations/locale-and-language-tags.md +79 -0
- package/expertise/i18n/foundations/numbers-currency-units.md +61 -0
- package/expertise/i18n/foundations/pluralization-and-gender.md +109 -0
- package/expertise/i18n/foundations/string-externalization.md +236 -0
- package/expertise/i18n/foundations/text-direction-bidi.md +241 -0
- package/expertise/i18n/foundations/unicode-and-encoding.md +86 -0
- package/expertise/i18n/index.md +38 -0
- package/expertise/i18n/platform/backend-i18n.md +31 -0
- package/expertise/i18n/platform/flutter-i18n.md +148 -0
- package/expertise/i18n/platform/native-android-i18n.md +36 -0
- package/expertise/i18n/platform/native-ios-i18n.md +36 -0
- package/expertise/i18n/platform/react-i18n.md +103 -0
- package/expertise/i18n/platform/web-css-i18n.md +81 -0
- package/expertise/i18n/rtl/arabic-specific.md +175 -0
- package/expertise/i18n/rtl/hebrew-specific.md +149 -0
- package/expertise/i18n/rtl/rtl-animations-and-transitions.md +111 -0
- package/expertise/i18n/rtl/rtl-forms-and-input.md +161 -0
- package/expertise/i18n/rtl/rtl-fundamentals.md +211 -0
- package/expertise/i18n/rtl/rtl-icons-and-images.md +181 -0
- package/expertise/i18n/rtl/rtl-layout-mirroring.md +252 -0
- package/expertise/i18n/rtl/rtl-navigation-and-gestures.md +107 -0
- package/expertise/i18n/rtl/rtl-testing-and-qa.md +147 -0
- package/expertise/i18n/rtl/rtl-typography.md +160 -0
- package/expertise/index.md +113 -0
- package/expertise/index.yaml +216 -0
- package/expertise/infrastructure/cloud-aws.md +597 -0
- package/expertise/infrastructure/cloud-gcp.md +599 -0
- package/expertise/infrastructure/cybersecurity.md +816 -0
- package/expertise/infrastructure/database-mongodb.md +447 -0
- package/expertise/infrastructure/database-postgres.md +400 -0
- package/expertise/infrastructure/devops-cicd.md +787 -0
- package/expertise/infrastructure/index.md +27 -0
- package/expertise/performance/PROGRESS.md +50 -0
- package/expertise/performance/backend/api-latency.md +1204 -0
- package/expertise/performance/backend/background-jobs.md +506 -0
- package/expertise/performance/backend/connection-pooling.md +1209 -0
- package/expertise/performance/backend/database-query-optimization.md +515 -0
- package/expertise/performance/backend/index.md +23 -0
- package/expertise/performance/backend/rate-limiting-and-throttling.md +971 -0
- package/expertise/performance/foundations/algorithmic-complexity.md +954 -0
- package/expertise/performance/foundations/caching-strategies.md +489 -0
- package/expertise/performance/foundations/concurrency-and-parallelism.md +847 -0
- package/expertise/performance/foundations/index.md +24 -0
- package/expertise/performance/foundations/measuring-and-profiling.md +440 -0
- package/expertise/performance/foundations/memory-management.md +964 -0
- package/expertise/performance/foundations/performance-budgets.md +1314 -0
- package/expertise/performance/index.md +31 -0
- package/expertise/performance/infrastructure/auto-scaling.md +1059 -0
- package/expertise/performance/infrastructure/cdn-and-edge.md +1081 -0
- package/expertise/performance/infrastructure/index.md +22 -0
- package/expertise/performance/infrastructure/load-balancing.md +1081 -0
- package/expertise/performance/infrastructure/observability.md +1079 -0
- package/expertise/performance/mobile/index.md +23 -0
- package/expertise/performance/mobile/mobile-animations.md +544 -0
- package/expertise/performance/mobile/mobile-memory-battery.md +416 -0
- package/expertise/performance/mobile/mobile-network.md +452 -0
- package/expertise/performance/mobile/mobile-rendering.md +599 -0
- package/expertise/performance/mobile/mobile-startup-time.md +505 -0
- package/expertise/performance/platform-specific/flutter-performance.md +647 -0
- package/expertise/performance/platform-specific/index.md +22 -0
- package/expertise/performance/platform-specific/node-performance.md +1307 -0
- package/expertise/performance/platform-specific/postgres-performance.md +1366 -0
- package/expertise/performance/platform-specific/react-performance.md +1403 -0
- package/expertise/performance/web/bundle-optimization.md +1239 -0
- package/expertise/performance/web/image-and-media.md +636 -0
- package/expertise/performance/web/index.md +24 -0
- package/expertise/performance/web/network-optimization.md +1133 -0
- package/expertise/performance/web/rendering-performance.md +1098 -0
- package/expertise/performance/web/ssr-and-hydration.md +918 -0
- package/expertise/performance/web/web-vitals.md +1374 -0
- package/expertise/quality/accessibility.md +985 -0
- package/expertise/quality/evidence-based-verification.md +499 -0
- package/expertise/quality/index.md +24 -0
- package/expertise/quality/ml-model-audit.md +614 -0
- package/expertise/quality/performance.md +600 -0
- package/expertise/quality/testing-api.md +891 -0
- package/expertise/quality/testing-mobile.md +496 -0
- package/expertise/quality/testing-web.md +849 -0
- package/expertise/security/PROGRESS.md +54 -0
- package/expertise/security/agentic-identity.md +540 -0
- package/expertise/security/compliance-frameworks.md +601 -0
- package/expertise/security/data/data-encryption.md +364 -0
- package/expertise/security/data/data-privacy-gdpr.md +692 -0
- package/expertise/security/data/database-security.md +1171 -0
- package/expertise/security/data/index.md +22 -0
- package/expertise/security/data/pii-handling.md +531 -0
- package/expertise/security/foundations/authentication.md +1041 -0
- package/expertise/security/foundations/authorization.md +603 -0
- package/expertise/security/foundations/cryptography.md +1001 -0
- package/expertise/security/foundations/index.md +25 -0
- package/expertise/security/foundations/owasp-top-10.md +1354 -0
- package/expertise/security/foundations/secrets-management.md +1217 -0
- package/expertise/security/foundations/secure-sdlc.md +700 -0
- package/expertise/security/foundations/supply-chain-security.md +698 -0
- package/expertise/security/index.md +31 -0
- package/expertise/security/infrastructure/cloud-security-aws.md +1296 -0
- package/expertise/security/infrastructure/cloud-security-gcp.md +1376 -0
- package/expertise/security/infrastructure/container-security.md +721 -0
- package/expertise/security/infrastructure/incident-response.md +1295 -0
- package/expertise/security/infrastructure/index.md +24 -0
- package/expertise/security/infrastructure/logging-and-monitoring.md +1618 -0
- package/expertise/security/infrastructure/network-security.md +1337 -0
- package/expertise/security/mobile/index.md +23 -0
- package/expertise/security/mobile/mobile-android-security.md +1218 -0
- package/expertise/security/mobile/mobile-binary-protection.md +1229 -0
- package/expertise/security/mobile/mobile-data-storage.md +1265 -0
- package/expertise/security/mobile/mobile-ios-security.md +1401 -0
- package/expertise/security/mobile/mobile-network-security.md +1520 -0
- package/expertise/security/smart-contract-security.md +594 -0
- package/expertise/security/testing/index.md +22 -0
- package/expertise/security/testing/penetration-testing.md +1258 -0
- package/expertise/security/testing/security-code-review.md +1765 -0
- package/expertise/security/testing/threat-modeling.md +1074 -0
- package/expertise/security/testing/vulnerability-scanning.md +1062 -0
- package/expertise/security/web/api-security.md +586 -0
- package/expertise/security/web/cors-and-headers.md +433 -0
- package/expertise/security/web/csrf.md +562 -0
- package/expertise/security/web/file-upload.md +1477 -0
- package/expertise/security/web/index.md +25 -0
- package/expertise/security/web/injection.md +1375 -0
- package/expertise/security/web/session-management.md +1101 -0
- package/expertise/security/web/xss.md +1158 -0
- package/exports/README.md +17 -0
- package/exports/hosts/claude/.claude/agents/clarifier.md +42 -0
- package/exports/hosts/claude/.claude/agents/content-author.md +63 -0
- package/exports/hosts/claude/.claude/agents/designer.md +55 -0
- package/exports/hosts/claude/.claude/agents/executor.md +55 -0
- package/exports/hosts/claude/.claude/agents/learner.md +51 -0
- package/exports/hosts/claude/.claude/agents/planner.md +53 -0
- package/exports/hosts/claude/.claude/agents/researcher.md +43 -0
- package/exports/hosts/claude/.claude/agents/reviewer.md +54 -0
- package/exports/hosts/claude/.claude/agents/specifier.md +47 -0
- package/exports/hosts/claude/.claude/agents/verifier.md +71 -0
- package/exports/hosts/claude/.claude/commands/author.md +42 -0
- package/exports/hosts/claude/.claude/commands/clarify.md +38 -0
- package/exports/hosts/claude/.claude/commands/design-review.md +46 -0
- package/exports/hosts/claude/.claude/commands/design.md +44 -0
- package/exports/hosts/claude/.claude/commands/discover.md +37 -0
- package/exports/hosts/claude/.claude/commands/execute.md +48 -0
- package/exports/hosts/claude/.claude/commands/learn.md +38 -0
- package/exports/hosts/claude/.claude/commands/plan-review.md +42 -0
- package/exports/hosts/claude/.claude/commands/plan.md +39 -0
- package/exports/hosts/claude/.claude/commands/prepare-next.md +37 -0
- package/exports/hosts/claude/.claude/commands/review.md +40 -0
- package/exports/hosts/claude/.claude/commands/run-audit.md +41 -0
- package/exports/hosts/claude/.claude/commands/spec-challenge.md +41 -0
- package/exports/hosts/claude/.claude/commands/specify.md +38 -0
- package/exports/hosts/claude/.claude/commands/verify.md +37 -0
- package/exports/hosts/claude/.claude/settings.json +34 -0
- package/exports/hosts/claude/CLAUDE.md +19 -0
- package/exports/hosts/claude/export.manifest.json +38 -0
- package/exports/hosts/claude/host-package.json +67 -0
- package/exports/hosts/codex/AGENTS.md +19 -0
- package/exports/hosts/codex/export.manifest.json +38 -0
- package/exports/hosts/codex/host-package.json +41 -0
- package/exports/hosts/cursor/.cursor/hooks.json +16 -0
- package/exports/hosts/cursor/.cursor/rules/wazir-core.mdc +19 -0
- package/exports/hosts/cursor/export.manifest.json +38 -0
- package/exports/hosts/cursor/host-package.json +42 -0
- package/exports/hosts/gemini/GEMINI.md +19 -0
- package/exports/hosts/gemini/export.manifest.json +38 -0
- package/exports/hosts/gemini/host-package.json +41 -0
- package/hooks/README.md +18 -0
- package/hooks/definitions/loop_cap_guard.yaml +21 -0
- package/hooks/definitions/post_tool_capture.yaml +24 -0
- package/hooks/definitions/pre_compact_summary.yaml +19 -0
- package/hooks/definitions/pre_tool_capture_route.yaml +19 -0
- package/hooks/definitions/protected_path_write_guard.yaml +19 -0
- package/hooks/definitions/session_start.yaml +19 -0
- package/hooks/definitions/stop_handoff_harvest.yaml +20 -0
- package/hooks/loop-cap-guard +17 -0
- package/hooks/post-tool-lint +36 -0
- package/hooks/protected-path-write-guard +17 -0
- package/hooks/session-start +41 -0
- package/llms-full.txt +2355 -0
- package/llms.txt +43 -0
- package/package.json +79 -0
- package/roles/README.md +20 -0
- package/roles/clarifier.md +42 -0
- package/roles/content-author.md +63 -0
- package/roles/designer.md +55 -0
- package/roles/executor.md +55 -0
- package/roles/learner.md +51 -0
- package/roles/planner.md +53 -0
- package/roles/researcher.md +43 -0
- package/roles/reviewer.md +54 -0
- package/roles/specifier.md +47 -0
- package/roles/verifier.md +71 -0
- package/schemas/README.md +24 -0
- package/schemas/accepted-learning.schema.json +20 -0
- package/schemas/author-artifact.schema.json +156 -0
- package/schemas/clarification.schema.json +19 -0
- package/schemas/design-artifact.schema.json +80 -0
- package/schemas/docs-claim.schema.json +18 -0
- package/schemas/export-manifest.schema.json +20 -0
- package/schemas/hook.schema.json +67 -0
- package/schemas/host-export-package.schema.json +18 -0
- package/schemas/implementation-plan.schema.json +19 -0
- package/schemas/proposed-learning.schema.json +19 -0
- package/schemas/research.schema.json +18 -0
- package/schemas/review.schema.json +29 -0
- package/schemas/run-manifest.schema.json +18 -0
- package/schemas/spec-challenge.schema.json +18 -0
- package/schemas/spec.schema.json +20 -0
- package/schemas/usage.schema.json +102 -0
- package/schemas/verification-proof.schema.json +29 -0
- package/schemas/wazir-manifest.schema.json +173 -0
- package/skills/README.md +40 -0
- package/skills/brainstorming/SKILL.md +77 -0
- package/skills/debugging/SKILL.md +50 -0
- package/skills/design/SKILL.md +61 -0
- package/skills/dispatching-parallel-agents/SKILL.md +128 -0
- package/skills/executing-plans/SKILL.md +70 -0
- package/skills/finishing-a-development-branch/SKILL.md +169 -0
- package/skills/humanize/SKILL.md +123 -0
- package/skills/init-pipeline/SKILL.md +124 -0
- package/skills/prepare-next/SKILL.md +20 -0
- package/skills/receiving-code-review/SKILL.md +123 -0
- package/skills/requesting-code-review/SKILL.md +105 -0
- package/skills/requesting-code-review/code-reviewer.md +108 -0
- package/skills/run-audit/SKILL.md +197 -0
- package/skills/scan-project/SKILL.md +41 -0
- package/skills/self-audit/SKILL.md +153 -0
- package/skills/subagent-driven-development/SKILL.md +154 -0
- package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
- package/skills/subagent-driven-development/implementer-prompt.md +102 -0
- package/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/skills/tdd/SKILL.md +23 -0
- package/skills/using-git-worktrees/SKILL.md +163 -0
- package/skills/using-skills/SKILL.md +95 -0
- package/skills/verification/SKILL.md +22 -0
- package/skills/wazir/SKILL.md +463 -0
- package/skills/writing-plans/SKILL.md +30 -0
- package/skills/writing-skills/SKILL.md +157 -0
- package/skills/writing-skills/anthropic-best-practices.md +122 -0
- package/skills/writing-skills/persuasion-principles.md +50 -0
- package/templates/README.md +20 -0
- package/templates/artifacts/README.md +10 -0
- package/templates/artifacts/accepted-learning.md +19 -0
- package/templates/artifacts/accepted-learning.template.json +12 -0
- package/templates/artifacts/author.md +74 -0
- package/templates/artifacts/author.template.json +19 -0
- package/templates/artifacts/clarification.md +21 -0
- package/templates/artifacts/clarification.template.json +12 -0
- package/templates/artifacts/execute-notes.md +19 -0
- package/templates/artifacts/implementation-plan.md +21 -0
- package/templates/artifacts/implementation-plan.template.json +11 -0
- package/templates/artifacts/learning-proposal.md +19 -0
- package/templates/artifacts/next-run-handoff.md +21 -0
- package/templates/artifacts/plan-review.md +19 -0
- package/templates/artifacts/proposed-learning.template.json +12 -0
- package/templates/artifacts/research.md +21 -0
- package/templates/artifacts/research.template.json +12 -0
- package/templates/artifacts/review-findings.md +19 -0
- package/templates/artifacts/review.template.json +11 -0
- package/templates/artifacts/run-manifest.template.json +8 -0
- package/templates/artifacts/spec-challenge.md +19 -0
- package/templates/artifacts/spec-challenge.template.json +11 -0
- package/templates/artifacts/spec.md +21 -0
- package/templates/artifacts/spec.template.json +12 -0
- package/templates/artifacts/verification-proof.md +19 -0
- package/templates/artifacts/verification-proof.template.json +11 -0
- package/templates/examples/accepted-learning.example.json +14 -0
- package/templates/examples/author.example.json +152 -0
- package/templates/examples/clarification.example.json +15 -0
- package/templates/examples/docs-claim.example.json +8 -0
- package/templates/examples/export-manifest.example.json +7 -0
- package/templates/examples/host-export-package.example.json +11 -0
- package/templates/examples/implementation-plan.example.json +17 -0
- package/templates/examples/proposed-learning.example.json +13 -0
- package/templates/examples/research.example.json +15 -0
- package/templates/examples/research.example.md +6 -0
- package/templates/examples/review.example.json +17 -0
- package/templates/examples/run-manifest.example.json +9 -0
- package/templates/examples/spec-challenge.example.json +14 -0
- package/templates/examples/spec.example.json +21 -0
- package/templates/examples/verification-proof.example.json +21 -0
- package/templates/examples/wazir-manifest.example.yaml +65 -0
- package/templates/task-definition-schema.md +99 -0
- package/tooling/README.md +20 -0
- package/tooling/src/adapters/context-mode.js +50 -0
- package/tooling/src/capture/command.js +376 -0
- package/tooling/src/capture/store.js +99 -0
- package/tooling/src/capture/usage.js +270 -0
- package/tooling/src/checks/branches.js +50 -0
- package/tooling/src/checks/brand-truth.js +110 -0
- package/tooling/src/checks/changelog.js +231 -0
- package/tooling/src/checks/command-registry.js +36 -0
- package/tooling/src/checks/commits.js +102 -0
- package/tooling/src/checks/docs-drift.js +103 -0
- package/tooling/src/checks/docs-truth.js +201 -0
- package/tooling/src/checks/runtime-surface.js +156 -0
- package/tooling/src/cli.js +116 -0
- package/tooling/src/command-options.js +56 -0
- package/tooling/src/commands/validate.js +320 -0
- package/tooling/src/doctor/command.js +91 -0
- package/tooling/src/export/command.js +77 -0
- package/tooling/src/export/compiler.js +498 -0
- package/tooling/src/guards/loop-cap-guard.js +52 -0
- package/tooling/src/guards/protected-path-write-guard.js +67 -0
- package/tooling/src/index/command.js +152 -0
- package/tooling/src/index/storage.js +1061 -0
- package/tooling/src/index/summarizers.js +261 -0
- package/tooling/src/loaders.js +18 -0
- package/tooling/src/project-root.js +22 -0
- package/tooling/src/recall/command.js +225 -0
- package/tooling/src/schema-validator.js +30 -0
- package/tooling/src/state-root.js +40 -0
- package/tooling/src/status/command.js +71 -0
- package/wazir.manifest.yaml +135 -0
- package/workflows/README.md +19 -0
- package/workflows/author.md +42 -0
- package/workflows/clarify.md +38 -0
- package/workflows/design-review.md +46 -0
- package/workflows/design.md +44 -0
- package/workflows/discover.md +37 -0
- package/workflows/execute.md +48 -0
- package/workflows/learn.md +38 -0
- package/workflows/plan-review.md +42 -0
- package/workflows/plan.md +39 -0
- package/workflows/prepare-next.md +37 -0
- package/workflows/review.md +40 -0
- package/workflows/run-audit.md +41 -0
- package/workflows/spec-challenge.md +41 -0
- package/workflows/specify.md +38 -0
- package/workflows/verify.md +37 -0
|
@@ -0,0 +1,1062 @@
|
|
|
1
|
+
# Vulnerability Scanning
|
|
2
|
+
|
|
3
|
+
> **Purpose:** Reference for AI agents to understand vulnerability scanning methodology, guide
|
|
4
|
+
> scan configuration and scheduling, interpret scan results, and assist with remediation
|
|
5
|
+
> prioritization. Covers SAST, DAST, IAST, and SCA across infrastructure, applications, and
|
|
6
|
+
> containers. This module is strictly DEFENSIVE.
|
|
7
|
+
> **Last updated:** 2026-03-08
|
|
8
|
+
> **Sources:** OWASP Testing Guide v5, NIST SP 800-115, PCI-DSS v4.0 (Req 11.2/11.3),
|
|
9
|
+
> CVSS v3.1/v4.0, FIRST EPSS, NVD, ProjectDiscovery Nuclei, Trivy v0.68, Semgrep,
|
|
10
|
+
> OWASP ZAP, VulnCheck State of Exploitation 2026
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Threat Landscape
|
|
15
|
+
|
|
16
|
+
### Why Vulnerability Scanning Matters
|
|
17
|
+
|
|
18
|
+
Vulnerability scanning is the systematic, automated examination of systems, applications, and
|
|
19
|
+
infrastructure to identify known security weaknesses before adversaries exploit them. Unlike
|
|
20
|
+
penetration testing (which relies on human creativity and chained exploitation), vulnerability
|
|
21
|
+
scanning provides breadth-first coverage at a scale and frequency that manual testing cannot match.
|
|
22
|
+
|
|
23
|
+
Key statistics:
|
|
24
|
+
|
|
25
|
+
- A record 48,185 CVEs were published in 2025, with 3,984 rated critical (NVD).
|
|
26
|
+
- Over 21,500 CVEs were disclosed in the first half of 2026 alone — a 16-18% increase YoY.
|
|
27
|
+
- VulnCheck identified 432 CVEs exploited in the wild in H1 2025; 32.1% were exploited on or
|
|
28
|
+
before disclosure day (zero-day weaponization).
|
|
29
|
+
- 28.96% of CISA KEVs in 2025 were exploited on or before CVE publication — up from 23.6% in 2024.
|
|
30
|
+
- Average cost of a data breach reached $4.88M in 2024 (IBM Cost of a Data Breach Report).
|
|
31
|
+
- Organizations running weekly vulnerability scans detect exploitable issues 11x faster
|
|
32
|
+
than those scanning quarterly.
|
|
33
|
+
|
|
34
|
+
### Real-World Breaches That Scanners Would Have Detected
|
|
35
|
+
|
|
36
|
+
| Breach / Vulnerability | Year | CVE | Root Cause | Scanner Type |
|
|
37
|
+
|------------------------|------|-----|-----------|--------------|
|
|
38
|
+
| MOVEit Transfer mass exploitation | 2023 | CVE-2023-34362 | SQL injection in file transfer | DAST + SCA |
|
|
39
|
+
| Log4Shell (Apache Log4j) | 2021 | CVE-2021-44228 | JNDI injection in logging lib | SCA |
|
|
40
|
+
| Citrix Bleed | 2023 | CVE-2023-4966 | Buffer overflow in NetScaler | Infrastructure scanner |
|
|
41
|
+
| Spring4Shell | 2022 | CVE-2022-22965 | RCE in Spring Framework | SCA + DAST |
|
|
42
|
+
| Equifax breach | 2017 | CVE-2017-5638 | Unpatched Apache Struts | SCA + infrastructure |
|
|
43
|
+
| SolarWinds Orion | 2020 | CVE-2020-10148 | Supply chain compromise | SCA (SBOM analysis) |
|
|
44
|
+
| XZ Utils backdoor | 2024 | CVE-2024-3094 | Malicious code in compression lib | SCA |
|
|
45
|
+
| React2Shell (React RSC) | 2025 | CVE-2025-8671 | Unauth RCE via Server Components | SCA + SAST |
|
|
46
|
+
| Langflow AI platform | 2025 | CVE-2025-3248 | Critical flaw in AI orchestration | SCA + DAST |
|
|
47
|
+
| Apache Tika SSRF/XXE | 2025 | CVE-2025-66516 | SSRF/XXE via crafted document | SAST + DAST |
|
|
48
|
+
|
|
49
|
+
### Disclosure-to-Exploitation Timeline Collapse
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
2020: Average 42 days from disclosure to exploitation
|
|
53
|
+
2022: Average 19 days from disclosure to exploitation
|
|
54
|
+
2024: Average 5 days from disclosure to exploitation
|
|
55
|
+
2025: 32.1% exploited on or BEFORE disclosure (zero-day)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
This trend makes continuous, automated scanning non-negotiable.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Core Security Principles
|
|
63
|
+
|
|
64
|
+
### The Four Pillars of Vulnerability Scanning
|
|
65
|
+
|
|
66
|
+
1. **Coverage** — Scan all assets: infrastructure, applications, containers, IaC, dependencies.
|
|
67
|
+
2. **Frequency** — Scan continuously; weekly minimum for infra, on every commit for code.
|
|
68
|
+
3. **Accuracy** — Tune scanners to minimize false positives without suppressing true findings.
|
|
69
|
+
4. **Action** — Every finding must have an owner, a severity, and a remediation deadline.
|
|
70
|
+
|
|
71
|
+
### Scanning Taxonomy
|
|
72
|
+
|
|
73
|
+
| Type | Acronym | What It Scans | When | Examples |
|
|
74
|
+
|------|---------|--------------|------|----------|
|
|
75
|
+
| Static Application Security Testing | SAST | Source code, bytecode | Pre-commit, CI | Semgrep, CodeQL, SonarQube |
|
|
76
|
+
| Dynamic Application Security Testing | DAST | Running applications | Post-deploy, staging | OWASP ZAP, Burp Suite, Nuclei |
|
|
77
|
+
| Interactive Application Security Testing | IAST | Instrumented runtime | QA/testing | Contrast Security, Hdiv |
|
|
78
|
+
| Software Composition Analysis | SCA | Dependencies, libraries | CI, scheduled | Trivy, Snyk, Dependabot, Grype |
|
|
79
|
+
| Infrastructure Scanning | Infra | Hosts, networks, services | Scheduled | Nessus, OpenVAS, Qualys |
|
|
80
|
+
| Container Scanning | Container | Images, registries | CI, hooks | Trivy, Grype, Anchore |
|
|
81
|
+
| IaC Scanning | IaC | Terraform, CloudFormation | Pre-commit, CI | Checkov, tfsec, KICS |
|
|
82
|
+
| Cloud Security Posture Mgmt | CSPM | Cloud configurations | Continuous | Prowler, ScoutSuite, Wiz |
|
|
83
|
+
|
|
84
|
+
### Vulnerability Scoring: CVSS v3.1 and v4.0
|
|
85
|
+
|
|
86
|
+
| Score Range | v3.1 Rating | Recommended SLA |
|
|
87
|
+
|-------------|-------------|-----------------|
|
|
88
|
+
| 0.0 | None | Informational |
|
|
89
|
+
| 0.1 - 3.9 | Low | 90 days |
|
|
90
|
+
| 4.0 - 6.9 | Medium | 30 days |
|
|
91
|
+
| 7.0 - 8.9 | High | 14 days |
|
|
92
|
+
| 9.0 - 10.0 | Critical | 48 hours |
|
|
93
|
+
|
|
94
|
+
**CVSS v4.0 improvements** (released Nov 2023, adopted across NVD 2024-2025):
|
|
95
|
+
|
|
96
|
+
- **Attack Requirements (AT)** — distinguishes "no special conditions" from race conditions.
|
|
97
|
+
- **Threat metrics** — optional group capturing real-world exploitation status.
|
|
98
|
+
- **Supplemental metrics** — safety, automatable, recovery, value density, provider urgency.
|
|
99
|
+
|
|
100
|
+
### Risk-Based Prioritization (Beyond CVSS)
|
|
101
|
+
|
|
102
|
+
CVSS alone is insufficient. Combine with:
|
|
103
|
+
|
|
104
|
+
- **EPSS** — probability a CVE will be exploited in next 30 days. Score > 0.1 (10%) = immediate.
|
|
105
|
+
- **CISA KEV** — if listed, treat as emergency regardless of CVSS.
|
|
106
|
+
- **Asset criticality** — medium finding on payment server outweighs critical on isolated dev VM.
|
|
107
|
+
- **Reachability analysis** — is the vulnerable function actually called in your codebase?
|
|
108
|
+
|
|
109
|
+
### False Positive Management
|
|
110
|
+
|
|
111
|
+
1. **Triage within 48 hours** — unreviewed findings become noise.
|
|
112
|
+
2. **Suppress with documentation** — justification + compensating controls + expiry date.
|
|
113
|
+
3. **Track rates** — target < 15% for SAST, < 5% for SCA.
|
|
114
|
+
4. **Feed back** — custom rules, tuned policies, updated ignore lists.
|
|
115
|
+
5. **Periodic review** — re-validate suppressions quarterly.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Implementation Patterns
|
|
120
|
+
|
|
121
|
+
### Pattern 1: SAST Integration with Semgrep (TypeScript)
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
// semgrep-runner.ts — Programmatic Semgrep runner for CI pipelines
|
|
125
|
+
import { execSync } from "child_process";
|
|
126
|
+
import { readFileSync } from "fs";
|
|
127
|
+
|
|
128
|
+
interface SemgrepFinding {
|
|
129
|
+
check_id: string;
|
|
130
|
+
path: string;
|
|
131
|
+
start: { line: number; col: number };
|
|
132
|
+
extra: {
|
|
133
|
+
severity: "ERROR" | "WARNING" | "INFO";
|
|
134
|
+
message: string;
|
|
135
|
+
metadata: { cwe?: string[]; owasp?: string[] };
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
interface ScanResult {
|
|
140
|
+
findings: SemgrepFinding[];
|
|
141
|
+
criticalCount: number;
|
|
142
|
+
passed: boolean;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function runSastScan(targetDir: string, config = "auto"): ScanResult {
|
|
146
|
+
const out = "/tmp/semgrep-results.json";
|
|
147
|
+
try {
|
|
148
|
+
execSync(
|
|
149
|
+
`semgrep scan --config=${config} --json --output=${out} ${targetDir}`,
|
|
150
|
+
{ stdio: "pipe", timeout: 300_000 }
|
|
151
|
+
);
|
|
152
|
+
} catch {
|
|
153
|
+
// Semgrep exits non-zero when findings exist — expected
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const raw = JSON.parse(readFileSync(out, "utf-8"));
|
|
157
|
+
const findings: SemgrepFinding[] = raw.results ?? [];
|
|
158
|
+
const criticalCount = findings.filter(
|
|
159
|
+
(f) => f.extra.severity === "ERROR"
|
|
160
|
+
).length;
|
|
161
|
+
|
|
162
|
+
return { findings, criticalCount, passed: criticalCount === 0 };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// CI quality gate
|
|
166
|
+
const result = runSastScan("./src", "p/security-audit");
|
|
167
|
+
if (!result.passed) {
|
|
168
|
+
console.error(`SAST FAILED: ${result.criticalCount} critical findings`);
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Pattern 2: SCA Container Scanning (Python)
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
"""trivy_scanner.py — Container and dependency scanning with Trivy."""
|
|
177
|
+
import json
|
|
178
|
+
import subprocess
|
|
179
|
+
import sys
|
|
180
|
+
from dataclasses import dataclass
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
@dataclass
|
|
184
|
+
class VulnFinding:
|
|
185
|
+
vuln_id: str
|
|
186
|
+
pkg_name: str
|
|
187
|
+
installed_version: str
|
|
188
|
+
fixed_version: str
|
|
189
|
+
severity: str
|
|
190
|
+
cvss_score: float
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def scan_image(image: str, threshold: str = "HIGH") -> list[VulnFinding]:
|
|
194
|
+
"""Scan a container image, return findings >= threshold."""
|
|
195
|
+
result = subprocess.run(
|
|
196
|
+
["trivy", "image", "--format", "json",
|
|
197
|
+
"--severity", f"{threshold},CRITICAL", image],
|
|
198
|
+
capture_output=True, text=True, timeout=300,
|
|
199
|
+
)
|
|
200
|
+
data = json.loads(result.stdout)
|
|
201
|
+
findings: list[VulnFinding] = []
|
|
202
|
+
|
|
203
|
+
for target in data.get("Results", []):
|
|
204
|
+
for vuln in target.get("Vulnerabilities", []):
|
|
205
|
+
findings.append(VulnFinding(
|
|
206
|
+
vuln_id=vuln["VulnerabilityID"],
|
|
207
|
+
pkg_name=vuln["PkgName"],
|
|
208
|
+
installed_version=vuln.get("InstalledVersion", "unknown"),
|
|
209
|
+
fixed_version=vuln.get("FixedVersion", "no fix"),
|
|
210
|
+
severity=vuln["Severity"],
|
|
211
|
+
cvss_score=vuln.get("CVSS", {}).get("nvd", {}).get("V3Score", 0.0),
|
|
212
|
+
))
|
|
213
|
+
return sorted(findings, key=lambda f: f.cvss_score, reverse=True)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def enforce_gate(findings: list[VulnFinding], max_critical: int = 0) -> bool:
|
|
217
|
+
critical = [f for f in findings if f.severity == "CRITICAL"]
|
|
218
|
+
if len(critical) > max_critical:
|
|
219
|
+
for f in critical:
|
|
220
|
+
print(f" CRITICAL: {f.vuln_id} in {f.pkg_name}@{f.installed_version}")
|
|
221
|
+
return False
|
|
222
|
+
return True
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
if __name__ == "__main__":
|
|
226
|
+
img = sys.argv[1] if len(sys.argv) > 1 else "myapp:latest"
|
|
227
|
+
vulns = scan_image(img)
|
|
228
|
+
if not enforce_gate(vulns):
|
|
229
|
+
sys.exit(1)
|
|
230
|
+
print(f"Scan passed: {len(vulns)} findings, 0 critical")
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Pattern 3: Secure Dependency Lockfile Verification (TypeScript)
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
// verify-deps.ts — Verify lockfile integrity before install
|
|
237
|
+
import { execSync } from "child_process";
|
|
238
|
+
import { createHash } from "crypto";
|
|
239
|
+
import { readFileSync } from "fs";
|
|
240
|
+
|
|
241
|
+
function verifyLockfileIntegrity(lockfilePath: string): boolean {
|
|
242
|
+
const lockfile = readFileSync(lockfilePath, "utf-8");
|
|
243
|
+
const parsed = JSON.parse(lockfile);
|
|
244
|
+
|
|
245
|
+
for (const [name, meta] of Object.entries(parsed.packages ?? {})) {
|
|
246
|
+
const pkg = meta as { integrity?: string };
|
|
247
|
+
if (name && !pkg.integrity) {
|
|
248
|
+
console.error(`Missing integrity hash: ${name}`);
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Compare to committed version to detect tampering
|
|
254
|
+
try {
|
|
255
|
+
const committed = execSync(`git show HEAD:${lockfilePath}`, {
|
|
256
|
+
encoding: "utf-8",
|
|
257
|
+
});
|
|
258
|
+
const cur = createHash("sha256").update(lockfile).digest("hex");
|
|
259
|
+
const prev = createHash("sha256").update(committed).digest("hex");
|
|
260
|
+
if (cur !== prev) {
|
|
261
|
+
console.warn("Lockfile modified since last commit — review changes");
|
|
262
|
+
}
|
|
263
|
+
} catch {
|
|
264
|
+
console.warn("No committed lockfile — first-time setup");
|
|
265
|
+
}
|
|
266
|
+
return true;
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Vulnerability Catalog
|
|
273
|
+
|
|
274
|
+
### Critical Vulnerability Classes Detected by Scanners
|
|
275
|
+
|
|
276
|
+
| CWE | Name | Severity | Scanner Type | Example Pattern |
|
|
277
|
+
|-----|------|----------|-------------|----------------|
|
|
278
|
+
| CWE-89 | SQL Injection | Critical | SAST, DAST | `query("SELECT * FROM users WHERE id=" + userId)` |
|
|
279
|
+
| CWE-79 | Cross-Site Scripting (XSS) | High | SAST, DAST | `innerHTML = userInput` |
|
|
280
|
+
| CWE-78 | OS Command Injection | Critical | SAST, DAST | `exec("ping " + hostname)` |
|
|
281
|
+
| CWE-502 | Unsafe Deserialization | Critical | SAST, IAST | `pickle.loads(user_data)` |
|
|
282
|
+
| CWE-611 | XML External Entity (XXE) | High | SAST, DAST | XML parser with external entities enabled |
|
|
283
|
+
| CWE-918 | Server-Side Request Forgery | High | SAST, DAST | `fetch(userProvidedUrl)` without allowlist |
|
|
284
|
+
| CWE-1321 | Prototype Pollution | High | SAST, SCA | `merge(target, JSON.parse(userInput))` |
|
|
285
|
+
| CWE-327 | Broken Cryptography | Medium | SAST | MD5/SHA1 for password hashing |
|
|
286
|
+
| CWE-798 | Hard-coded Credentials | Critical | SAST, Secrets | `const API_KEY = "sk-live-abc123"` |
|
|
287
|
+
| CWE-1104 | Unmaintained Component | Medium | SCA | Dependency with no updates in 2+ years |
|
|
288
|
+
| CWE-269 | Improper Privilege Mgmt | High | CSPM, IaC | IAM `Action: *` on all resources |
|
|
289
|
+
| CWE-295 | Improper Cert Validation | High | SAST, DAST | `rejectUnauthorized: false` |
|
|
290
|
+
| CWE-434 | Unrestricted File Upload | Critical | DAST, SAST | No file type/content validation |
|
|
291
|
+
|
|
292
|
+
### Dependency Vulnerabilities (SCA Focus)
|
|
293
|
+
|
|
294
|
+
```text
|
|
295
|
+
CRIT: log4j-core < 2.17.1 — Remote code execution (CVE-2021-44228)
|
|
296
|
+
CRIT: spring-core < 5.3.18 — RCE via data binding (CVE-2022-22965)
|
|
297
|
+
CRIT: xz-utils 5.6.0-5.6.1 — Backdoor in compression (CVE-2024-3094)
|
|
298
|
+
HIGH: lodash < 4.17.21 — Prototype pollution (CVE-2021-23337)
|
|
299
|
+
HIGH: jsonwebtoken < 9.0.0 — Algorithm confusion (CVE-2022-23529)
|
|
300
|
+
HIGH: axios < 1.6.0 — SSRF via protocol bypass (CVE-2023-45857)
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Container Image Findings
|
|
304
|
+
|
|
305
|
+
| Finding | Severity | Remediation |
|
|
306
|
+
|---------|----------|-------------|
|
|
307
|
+
| Base image has known CVEs in glibc | High | Switch to distroless or Alpine |
|
|
308
|
+
| Container runs as root | Medium | Add `USER nonroot` to Dockerfile |
|
|
309
|
+
| Secrets baked into image layer | Critical | Use runtime secrets injection |
|
|
310
|
+
| Package manager cache not cleared | Low | `rm -rf /var/lib/apt/lists/*` |
|
|
311
|
+
| Outdated OS packages | Variable | Rebuild with updated base image |
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Security Checklist
|
|
316
|
+
|
|
317
|
+
### Pre-Deployment Gate
|
|
318
|
+
|
|
319
|
+
- [ ] SAST scan passes — zero critical/high findings or documented exceptions
|
|
320
|
+
- [ ] SCA scan passes — no known critical CVEs in dependencies
|
|
321
|
+
- [ ] Container image scan passes — base image updated within 30 days
|
|
322
|
+
- [ ] IaC scan passes — no public buckets, no overprivileged IAM, no open security groups
|
|
323
|
+
- [ ] Secrets scan passes — no hardcoded credentials, API keys, or tokens
|
|
324
|
+
- [ ] DAST baseline completed (staging) — zero high-severity findings
|
|
325
|
+
- [ ] License compliance verified — no GPL in proprietary code (if applicable)
|
|
326
|
+
- [ ] SBOM generated — CycloneDX or SPDX stored alongside release artifacts
|
|
327
|
+
|
|
328
|
+
### Scanning Cadence
|
|
329
|
+
|
|
330
|
+
- [ ] **Every PR:** SAST, SCA, secrets scan, IaC scan
|
|
331
|
+
- [ ] **Weekly:** Full DAST active scan against staging
|
|
332
|
+
- [ ] **Weekly:** Infrastructure vulnerability scan (Nessus/OpenVAS/Qualys)
|
|
333
|
+
- [ ] **Monthly:** Full container registry scan of all deployed images
|
|
334
|
+
- [ ] **Quarterly:** External ASV scan (PCI requirement)
|
|
335
|
+
- [ ] **On-demand:** Ad-hoc scans on new critical CVE disclosures
|
|
336
|
+
|
|
337
|
+
### False Positive Review
|
|
338
|
+
|
|
339
|
+
- [ ] Finding reviewed by security engineer within 48 hours
|
|
340
|
+
- [ ] Suppression justified in writing with compensating controls
|
|
341
|
+
- [ ] Suppression has expiry date (max 90 days)
|
|
342
|
+
- [ ] Suppressions tracked in central register
|
|
343
|
+
- [ ] Quarterly audit of all active suppressions
|
|
344
|
+
|
|
345
|
+
### Remediation Workflow
|
|
346
|
+
|
|
347
|
+
- [ ] Finding assigned to owner within SLA
|
|
348
|
+
- [ ] Root cause identified (not just symptom)
|
|
349
|
+
- [ ] Fix verified by re-scan
|
|
350
|
+
- [ ] Regression test added
|
|
351
|
+
- [ ] Postmortem documented for critical/high findings
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## Tools & Automation
|
|
356
|
+
|
|
357
|
+
### SAST: Semgrep Configuration
|
|
358
|
+
|
|
359
|
+
```yaml
|
|
360
|
+
# .semgrep.yml
|
|
361
|
+
rules:
|
|
362
|
+
- id: sql-injection-string-concat
|
|
363
|
+
patterns:
|
|
364
|
+
- pattern: |
|
|
365
|
+
$QUERY = "..." + $INPUT + "..."
|
|
366
|
+
- metavariable-pattern:
|
|
367
|
+
metavariable: $INPUT
|
|
368
|
+
pattern-not: "..."
|
|
369
|
+
message: >
|
|
370
|
+
SQL injection via string concatenation. Use parameterized queries.
|
|
371
|
+
severity: ERROR
|
|
372
|
+
languages: [typescript, javascript]
|
|
373
|
+
metadata:
|
|
374
|
+
cwe: ["CWE-89: SQL Injection"]
|
|
375
|
+
owasp: ["A03:2021 - Injection"]
|
|
376
|
+
|
|
377
|
+
- id: hardcoded-secret
|
|
378
|
+
pattern-regex: (?i)(api[_-]?key|secret|password|token)\s*[:=]\s*["'][a-zA-Z0-9+/=]{16,}["']
|
|
379
|
+
paths:
|
|
380
|
+
exclude: ["**/*test*", "**/*mock*"]
|
|
381
|
+
message: Hardcoded secret detected. Use env vars or secrets manager.
|
|
382
|
+
severity: ERROR
|
|
383
|
+
languages: [generic]
|
|
384
|
+
metadata:
|
|
385
|
+
cwe: ["CWE-798: Hard-coded Credentials"]
|
|
386
|
+
|
|
387
|
+
- id: insecure-tls
|
|
388
|
+
patterns:
|
|
389
|
+
- pattern: rejectUnauthorized: false
|
|
390
|
+
message: TLS validation disabled — allows MITM attacks.
|
|
391
|
+
severity: WARNING
|
|
392
|
+
languages: [typescript, javascript]
|
|
393
|
+
metadata:
|
|
394
|
+
cwe: ["CWE-295: Improper Certificate Validation"]
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
```bash
|
|
398
|
+
# CI execution with quality gate
|
|
399
|
+
semgrep scan --config=p/security-audit --config=.semgrep.yml \
|
|
400
|
+
--json --output=semgrep.json --error --severity=ERROR src/
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### DAST: OWASP ZAP Automation Framework
|
|
404
|
+
|
|
405
|
+
```yaml
|
|
406
|
+
# zap-automation.yaml
|
|
407
|
+
env:
|
|
408
|
+
contexts:
|
|
409
|
+
- name: "target-app"
|
|
410
|
+
urls: ["https://staging.example.com"]
|
|
411
|
+
includePaths: ["https://staging.example.com/.*"]
|
|
412
|
+
excludePaths: ["https://staging.example.com/logout.*"]
|
|
413
|
+
authentication:
|
|
414
|
+
method: "json"
|
|
415
|
+
parameters:
|
|
416
|
+
loginRequestUrl: "https://staging.example.com/api/auth/login"
|
|
417
|
+
loginRequestBody: '{"email":"{%username%}","password":"{%password%}"}'
|
|
418
|
+
verification:
|
|
419
|
+
method: "response"
|
|
420
|
+
loggedInRegex: '"token":".+"'
|
|
421
|
+
users:
|
|
422
|
+
- name: "test-user"
|
|
423
|
+
credentials:
|
|
424
|
+
username: "${ZAP_AUTH_USER}"
|
|
425
|
+
password: "${ZAP_AUTH_PASS}"
|
|
426
|
+
jobs:
|
|
427
|
+
- type: spider
|
|
428
|
+
parameters: { context: "target-app", user: "test-user", maxDuration: 5 }
|
|
429
|
+
- type: spiderAjax
|
|
430
|
+
parameters: { context: "target-app", user: "test-user", maxDuration: 5 }
|
|
431
|
+
- type: passiveScan-wait
|
|
432
|
+
parameters: { maxDuration: 10 }
|
|
433
|
+
- type: activeScan
|
|
434
|
+
parameters:
|
|
435
|
+
context: "target-app"
|
|
436
|
+
user: "test-user"
|
|
437
|
+
maxScanDurationInMins: 30
|
|
438
|
+
policy: "API-Scan"
|
|
439
|
+
- type: report
|
|
440
|
+
parameters:
|
|
441
|
+
template: "traditional-json"
|
|
442
|
+
reportDir: "/zap/reports"
|
|
443
|
+
reportFile: "zap-report.json"
|
|
444
|
+
risks: [high, medium]
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
```bash
|
|
448
|
+
# Run ZAP in CI via Docker
|
|
449
|
+
docker run --rm \
|
|
450
|
+
-v $(pwd)/zap-automation.yaml:/zap/wrk/zap-automation.yaml:ro \
|
|
451
|
+
-v $(pwd)/reports:/zap/reports \
|
|
452
|
+
-e ZAP_AUTH_USER="${ZAP_AUTH_USER}" \
|
|
453
|
+
-e ZAP_AUTH_PASS="${ZAP_AUTH_PASS}" \
|
|
454
|
+
ghcr.io/zaproxy/zaproxy:stable \
|
|
455
|
+
zap.sh -cmd -autorun /zap/wrk/zap-automation.yaml
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### SCA: Trivy Multi-Target Scanning
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
# Container image scan
|
|
462
|
+
trivy image --severity CRITICAL,HIGH --format json --output trivy-image.json myapp:latest
|
|
463
|
+
|
|
464
|
+
# Filesystem / dependency scan
|
|
465
|
+
trivy fs --severity CRITICAL,HIGH --format json --output trivy-fs.json ./
|
|
466
|
+
|
|
467
|
+
# IaC scan (Terraform, CloudFormation, Kubernetes)
|
|
468
|
+
trivy config --severity CRITICAL,HIGH --format json --output trivy-iac.json ./infra/
|
|
469
|
+
|
|
470
|
+
# SBOM generation (CycloneDX)
|
|
471
|
+
trivy fs --format cyclonedx --output sbom.cdx.json ./
|
|
472
|
+
|
|
473
|
+
# Scan an existing SBOM for new vulnerabilities
|
|
474
|
+
trivy sbom sbom.cdx.json --severity CRITICAL,HIGH
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### Infrastructure: Nuclei Template Scanning
|
|
478
|
+
|
|
479
|
+
```yaml
|
|
480
|
+
# custom-template.yaml — Detect exposed internal services
|
|
481
|
+
id: internal-service-exposure
|
|
482
|
+
info:
|
|
483
|
+
name: Internal Service Publicly Accessible
|
|
484
|
+
author: security-team
|
|
485
|
+
severity: high
|
|
486
|
+
tags: internal,exposure,misconfiguration
|
|
487
|
+
metadata:
|
|
488
|
+
cwe-id: CWE-668
|
|
489
|
+
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
|
|
490
|
+
cvss-score: 7.5
|
|
491
|
+
http:
|
|
492
|
+
- method: GET
|
|
493
|
+
path:
|
|
494
|
+
- "{{BaseURL}}/actuator/health"
|
|
495
|
+
- "{{BaseURL}}/debug/vars"
|
|
496
|
+
- "{{BaseURL}}/_cluster/health"
|
|
497
|
+
- "{{BaseURL}}/server-status"
|
|
498
|
+
matchers-condition: and
|
|
499
|
+
matchers:
|
|
500
|
+
- type: word
|
|
501
|
+
words: ['"status":"UP"', "cmdline", '"cluster_name"', "Apache Server Status"]
|
|
502
|
+
condition: or
|
|
503
|
+
- type: status
|
|
504
|
+
status: [200]
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
```bash
|
|
508
|
+
nuclei -l targets.txt -t /path/to/nuclei-templates/ -t ./custom-templates/ \
|
|
509
|
+
-severity critical,high -rate-limit 100 -json -output nuclei-results.json
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Secrets: Gitleaks Configuration
|
|
513
|
+
|
|
514
|
+
```toml
|
|
515
|
+
# .gitleaks.toml
|
|
516
|
+
title = "Custom Gitleaks Config"
|
|
517
|
+
|
|
518
|
+
[extend]
|
|
519
|
+
useDefault = true
|
|
520
|
+
|
|
521
|
+
[[rules]]
|
|
522
|
+
id = "custom-internal-api-key"
|
|
523
|
+
description = "Internal API Key"
|
|
524
|
+
regex = '''internal[_-]?api[_-]?key\s*[:=]\s*["']?[a-zA-Z0-9]{32,}["']?'''
|
|
525
|
+
entropy = 3.5
|
|
526
|
+
keywords = ["internal_api_key", "internal-api-key"]
|
|
527
|
+
|
|
528
|
+
[allowlist]
|
|
529
|
+
paths = ['''(^|/)test[s]?/''', '''\.md$''', '''\.example$''']
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
### CI/CD Pipeline: GitHub Actions
|
|
533
|
+
|
|
534
|
+
```yaml
|
|
535
|
+
# .github/workflows/security-scan.yml
|
|
536
|
+
name: Security Scanning Pipeline
|
|
537
|
+
on:
|
|
538
|
+
pull_request:
|
|
539
|
+
branches: [main, develop]
|
|
540
|
+
push:
|
|
541
|
+
branches: [main]
|
|
542
|
+
schedule:
|
|
543
|
+
- cron: "0 6 * * 1" # Weekly Monday 6AM UTC
|
|
544
|
+
|
|
545
|
+
jobs:
|
|
546
|
+
sast:
|
|
547
|
+
name: SAST — Semgrep
|
|
548
|
+
runs-on: ubuntu-latest
|
|
549
|
+
container: { image: "semgrep/semgrep:latest" }
|
|
550
|
+
steps:
|
|
551
|
+
- uses: actions/checkout@v4
|
|
552
|
+
- run: semgrep scan --config=auto --config=p/security-audit --json --output=semgrep.json --error src/
|
|
553
|
+
- uses: actions/upload-artifact@v4
|
|
554
|
+
if: always()
|
|
555
|
+
with: { name: semgrep-results, path: semgrep.json }
|
|
556
|
+
|
|
557
|
+
sca:
|
|
558
|
+
name: SCA — Trivy
|
|
559
|
+
runs-on: ubuntu-latest
|
|
560
|
+
steps:
|
|
561
|
+
- uses: actions/checkout@v4
|
|
562
|
+
- uses: aquasecurity/trivy-action@master
|
|
563
|
+
with:
|
|
564
|
+
scan-type: fs
|
|
565
|
+
scan-ref: "."
|
|
566
|
+
format: json
|
|
567
|
+
output: trivy-fs.json
|
|
568
|
+
severity: CRITICAL,HIGH
|
|
569
|
+
exit-code: "1"
|
|
570
|
+
|
|
571
|
+
container-scan:
|
|
572
|
+
name: Container — Trivy Image
|
|
573
|
+
runs-on: ubuntu-latest
|
|
574
|
+
needs: [sast]
|
|
575
|
+
steps:
|
|
576
|
+
- uses: actions/checkout@v4
|
|
577
|
+
- run: docker build -t myapp:${{ github.sha }} .
|
|
578
|
+
- uses: aquasecurity/trivy-action@master
|
|
579
|
+
with:
|
|
580
|
+
image-ref: myapp:${{ github.sha }}
|
|
581
|
+
format: json
|
|
582
|
+
output: trivy-image.json
|
|
583
|
+
severity: CRITICAL,HIGH
|
|
584
|
+
exit-code: "1"
|
|
585
|
+
|
|
586
|
+
secrets-scan:
|
|
587
|
+
name: Secrets — Gitleaks
|
|
588
|
+
runs-on: ubuntu-latest
|
|
589
|
+
steps:
|
|
590
|
+
- uses: actions/checkout@v4
|
|
591
|
+
with: { fetch-depth: 0 }
|
|
592
|
+
- uses: gitleaks/gitleaks-action@v2
|
|
593
|
+
env: { GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" }
|
|
594
|
+
|
|
595
|
+
dast:
|
|
596
|
+
name: DAST — ZAP (Staging)
|
|
597
|
+
runs-on: ubuntu-latest
|
|
598
|
+
if: github.ref == 'refs/heads/main'
|
|
599
|
+
needs: [sast, sca, container-scan]
|
|
600
|
+
steps:
|
|
601
|
+
- uses: actions/checkout@v4
|
|
602
|
+
- uses: zaproxy/action-baseline@v0.14.0
|
|
603
|
+
with:
|
|
604
|
+
target: ${{ vars.STAGING_URL }}
|
|
605
|
+
rules_file_name: zap-rules.tsv
|
|
606
|
+
cmd_options: "-a -j"
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
### Tool Comparison Matrix
|
|
610
|
+
|
|
611
|
+
| Tool | Type | License | CI Integration | False Positive Rate |
|
|
612
|
+
|------|------|---------|----------------|---------------------|
|
|
613
|
+
| Semgrep | SAST | OSS (LGPL-2.1) | Native | Low |
|
|
614
|
+
| CodeQL | SAST | Free for OSS | GitHub native | Low |
|
|
615
|
+
| SonarQube | SAST+Quality | Community/Paid | Plugins | Medium |
|
|
616
|
+
| OWASP ZAP | DAST | OSS (Apache-2.0) | Docker/Actions | Medium |
|
|
617
|
+
| Burp Suite | DAST | Commercial | CI extension | Low |
|
|
618
|
+
| Nuclei | DAST/Infra | OSS (MIT) | CLI | Low |
|
|
619
|
+
| Trivy | SCA+Container+IaC | OSS (Apache-2.0) | Native Actions | Low |
|
|
620
|
+
| Snyk | SCA+Container | Freemium | Native | Low |
|
|
621
|
+
| Grype | SCA+Container | OSS (Apache-2.0) | CLI | Low |
|
|
622
|
+
| Nessus | Infrastructure | Commercial | API | Low |
|
|
623
|
+
| OpenVAS | Infrastructure | OSS (GPL) | API | Medium |
|
|
624
|
+
| Qualys | Infrastructure+Cloud | Commercial | API/Agents | Low |
|
|
625
|
+
| Gitleaks | Secrets | OSS (MIT) | Native Actions | Low |
|
|
626
|
+
| Checkov | IaC | OSS (Apache-2.0) | CLI | Low |
|
|
627
|
+
|
|
628
|
+
---
|
|
629
|
+
|
|
630
|
+
## Platform-Specific Guidance
|
|
631
|
+
|
|
632
|
+
### Web Applications
|
|
633
|
+
|
|
634
|
+
- Authenticate DAST scanners using the same auth flow as real users (OAuth, JWT, sessions).
|
|
635
|
+
- Exclude destructive endpoints (DELETE, account termination) from active scans.
|
|
636
|
+
- Run baseline (passive) scans on every PR deploy; full active scans weekly on staging.
|
|
637
|
+
- Import OpenAPI/Swagger specs into ZAP or Burp for complete API coverage.
|
|
638
|
+
- SPAs require AJAX spider or browser-based crawling for full page discovery.
|
|
639
|
+
- Focus SAST on server-side for injection; client-side for XSS and DOM manipulation.
|
|
640
|
+
- Template engines (Handlebars, EJS, Jinja2) need framework-specific rules.
|
|
641
|
+
|
|
642
|
+
### Mobile Applications
|
|
643
|
+
|
|
644
|
+
- **Binary analysis:** MobSF for APK/IPA static analysis.
|
|
645
|
+
- **Hardcoded secrets:** Mobile binaries frequently embed API keys and certificates.
|
|
646
|
+
- **Insecure storage:** Check SharedPreferences (Android) / UserDefaults (iOS) for unencrypted data.
|
|
647
|
+
- **Certificate pinning:** Verify implementation and resistance to bypass.
|
|
648
|
+
- **Third-party SDKs:** SCA scan all bundled SDKs — many bundle vulnerable native libraries.
|
|
649
|
+
|
|
650
|
+
```bash
|
|
651
|
+
# MobSF static analysis via Docker
|
|
652
|
+
docker run -it --rm -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest
|
|
653
|
+
curl -F "file=@app-release.apk" http://localhost:8000/api/v1/upload \
|
|
654
|
+
-H "Authorization: ${MOBSF_API_KEY}"
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
### Cloud Infrastructure (AWS/GCP/Azure)
|
|
658
|
+
|
|
659
|
+
| Layer | Tool | What It Detects |
|
|
660
|
+
|-------|------|----------------|
|
|
661
|
+
| IaC (pre-deploy) | Checkov, tfsec, KICS | Misconfigurations before production |
|
|
662
|
+
| Runtime config | Prowler, ScoutSuite | Drift from secure baselines |
|
|
663
|
+
| Containers | Trivy, Grype | Vulnerable packages in deployed images |
|
|
664
|
+
| Kubernetes | kubeaudit, kube-bench | CIS benchmark violations |
|
|
665
|
+
| Serverless | AWS Inspector | Function-level vulnerabilities |
|
|
666
|
+
|
|
667
|
+
```bash
|
|
668
|
+
# Prowler — AWS security best practices
|
|
669
|
+
prowler aws --severity critical high --compliance cis_2.0_aws \
|
|
670
|
+
--output-formats json-ocsf --output-directory ./prowler-results
|
|
671
|
+
|
|
672
|
+
# AWS Inspector — automated vulnerability management
|
|
673
|
+
aws inspector2 list-findings \
|
|
674
|
+
--filter-criteria '{"severity":[{"comparison":"EQUALS","value":"CRITICAL"}]}' \
|
|
675
|
+
--max-results 50
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
### Kubernetes Continuous Scanning
|
|
679
|
+
|
|
680
|
+
```yaml
|
|
681
|
+
# Trivy Operator — install via Helm for in-cluster continuous scanning
|
|
682
|
+
# helm install trivy-operator aquasecurity/trivy-operator \
|
|
683
|
+
# --namespace trivy-system --create-namespace \
|
|
684
|
+
# --set trivy.severity=CRITICAL,HIGH
|
|
685
|
+
|
|
686
|
+
# Auto-generated VulnerabilityReport example:
|
|
687
|
+
apiVersion: aquasecurity.github.io/v1alpha1
|
|
688
|
+
kind: VulnerabilityReport
|
|
689
|
+
metadata:
|
|
690
|
+
name: deployment-myapp
|
|
691
|
+
namespace: production
|
|
692
|
+
report:
|
|
693
|
+
vulnerabilities:
|
|
694
|
+
- vulnerabilityID: CVE-2024-3094
|
|
695
|
+
resource: xz-utils
|
|
696
|
+
installedVersion: "5.6.1"
|
|
697
|
+
fixedVersion: "5.6.2"
|
|
698
|
+
severity: CRITICAL
|
|
699
|
+
score: 10.0
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
---
|
|
703
|
+
|
|
704
|
+
## Incident Patterns
|
|
705
|
+
|
|
706
|
+
### Scenario 1: Zero-Day CVE — Emergency Response
|
|
707
|
+
|
|
708
|
+
**Trigger:** Critical CVE (CVSS 9.0+) disclosed and listed on CISA KEV.
|
|
709
|
+
|
|
710
|
+
1. **T+0h:** Run targeted SCA scan across all repos and registries for affected package.
|
|
711
|
+
```bash
|
|
712
|
+
trivy fs --severity CRITICAL --format json . | \
|
|
713
|
+
jq '.Results[].Vulnerabilities[] | select(.VulnerabilityID == "CVE-XXXX-XXXXX")'
|
|
714
|
+
```
|
|
715
|
+
2. **T+1h:** Assess blast radius — affected services, reachability, compensating controls.
|
|
716
|
+
3. **T+4h:** Deploy mitigations — WAF rules, network restrictions, config changes.
|
|
717
|
+
4. **T+24h:** Deploy patches — update deps, rebuild containers, redeploy.
|
|
718
|
+
5. **T+48h:** Verify — re-scan all affected systems.
|
|
719
|
+
6. **T+72h:** Postmortem — document timeline, assess detection gaps, update rules.
|
|
720
|
+
|
|
721
|
+
### Scenario 2: SAST Blocks SQL Injection in PR
|
|
722
|
+
|
|
723
|
+
1. CI gate blocks merge on CWE-89 finding.
|
|
724
|
+
2. Developer confirms true positive (string concatenation in query).
|
|
725
|
+
3. Fix: replace with parameterized query.
|
|
726
|
+
4. Re-scan passes.
|
|
727
|
+
5. Regression test added for parameterized path.
|
|
728
|
+
|
|
729
|
+
### Scenario 3: Container Base Image Vulnerability
|
|
730
|
+
|
|
731
|
+
1. Trivy detects critical CVEs in production container base image.
|
|
732
|
+
2. Assess: is the vulnerable package actually used?
|
|
733
|
+
3. Update `FROM` directive, rebuild, run integration tests.
|
|
734
|
+
4. Rolling deploy to production.
|
|
735
|
+
5. Scan registry for other images using the same base.
|
|
736
|
+
|
|
737
|
+
### Scenario 4: Secrets Detected in Git History
|
|
738
|
+
|
|
739
|
+
1. **Rotate immediately** — credential is compromised regardless of repo visibility.
|
|
740
|
+
2. **Audit** — review CloudTrail/audit logs for unauthorized use.
|
|
741
|
+
3. **Remove** — `git filter-repo` or BFG Repo Cleaner (rewrites history).
|
|
742
|
+
4. **Prevent** — pre-commit hook with Gitleaks, server-side push protection.
|
|
743
|
+
5. **Educate** — share anonymized incident as learning opportunity.
|
|
744
|
+
|
|
745
|
+
### Scan Scheduling Matrix
|
|
746
|
+
|
|
747
|
+
| Scan Type | Trigger | Frequency | Max Duration | Failure Action |
|
|
748
|
+
|-----------|---------|-----------|-------------|----------------|
|
|
749
|
+
| SAST | PR/push | Every commit | 5 min | Block merge |
|
|
750
|
+
| SCA | PR/push | Every commit | 2 min | Block merge |
|
|
751
|
+
| Secrets | PR/push | Every commit | 1 min | Block merge |
|
|
752
|
+
| Container | Image build | Every build | 3 min | Block deploy |
|
|
753
|
+
| IaC | PR/push | Every commit | 2 min | Block merge |
|
|
754
|
+
| DAST baseline | Staging deploy | On deploy | 15 min | Alert |
|
|
755
|
+
| DAST active | Scheduled | Weekly | 2 hours | Create tickets |
|
|
756
|
+
| Infrastructure | Scheduled | Weekly | 4 hours | Create tickets |
|
|
757
|
+
| Registry sweep | Scheduled | Monthly | 8 hours | Create tickets |
|
|
758
|
+
| External ASV | Scheduled | Quarterly | Variable | Compliance report |
|
|
759
|
+
|
|
760
|
+
---
|
|
761
|
+
|
|
762
|
+
## Compliance & Standards
|
|
763
|
+
|
|
764
|
+
### Scanning Requirements by Framework
|
|
765
|
+
|
|
766
|
+
| Standard | Requirement | Scanning Type | Frequency |
|
|
767
|
+
|----------|-------------|--------------|-----------|
|
|
768
|
+
| PCI DSS v4.0 (6.3) | Identify/manage vulnerabilities | SCA, SAST | Continuous |
|
|
769
|
+
| PCI DSS v4.0 (11.3.1) | Internal vulnerability scans | Infra, container | Quarterly min |
|
|
770
|
+
| PCI DSS v4.0 (11.3.2) | External scans by ASV | ASV external | Quarterly + changes |
|
|
771
|
+
| NIST 800-115 | Technical security testing | SAST, DAST, infra | Risk-based |
|
|
772
|
+
| NIST 800-53 (RA-5) | Vulnerability monitoring | All types | Continuous |
|
|
773
|
+
| ISO 27001 (A.12.6) | Technical vuln management | Infra, SCA | Per risk assessment |
|
|
774
|
+
| SOC 2 (CC7.1) | Detect/monitor vulnerabilities | All types | Continuous |
|
|
775
|
+
| HIPAA (164.308(a)(8)) | Periodic technical evaluation | Infra, app | Annual minimum |
|
|
776
|
+
| FedRAMP | Continuous monitoring | All types | Monthly OS, annual app |
|
|
777
|
+
| DORA (EU) | ICT risk management, testing | App, infra | Regular, risk-based |
|
|
778
|
+
| NIS2 (EU) | Network/info system security | Infra, app | Regular, risk-based |
|
|
779
|
+
|
|
780
|
+
### PCI DSS v4.0 ASV Requirements
|
|
781
|
+
|
|
782
|
+
- **Scope:** All externally accessible IPs and domains in the cardholder data environment.
|
|
783
|
+
- **Frequency:** Quarterly minimum, plus after significant infrastructure changes.
|
|
784
|
+
- **Pass criteria:** No vulnerabilities with CVSS >= 4.0 (after dispute resolution).
|
|
785
|
+
- **Exceptions:** Documented false positives with compensating controls are permitted.
|
|
786
|
+
- **Retention:** ASV scan results retained for at least 12 months.
|
|
787
|
+
- **Methodology:** Must follow PCI SSC ASV Program Guide; recognized methodologies include
|
|
788
|
+
NIST SP 800-115, OSSTMM, OWASP, and PTES.
|
|
789
|
+
|
|
790
|
+
### NIST SP 800-115 Scanning Hierarchy
|
|
791
|
+
|
|
792
|
+
1. **Review techniques** — documentation, log, ruleset review (passive).
|
|
793
|
+
2. **Identification and analysis** — network discovery, port scanning, vulnerability scanning.
|
|
794
|
+
3. **Vulnerability validation** — penetration testing to confirm findings.
|
|
795
|
+
|
|
796
|
+
Key principles: scan from both internal and external perspectives; credentialed scans
|
|
797
|
+
produce significantly more accurate results; correlate findings with asset inventory
|
|
798
|
+
and threat intelligence.
|
|
799
|
+
|
|
800
|
+
### SBOM Requirements (Executive Order 14028)
|
|
801
|
+
|
|
802
|
+
```bash
|
|
803
|
+
# Generate CycloneDX SBOM
|
|
804
|
+
trivy fs --format cyclonedx --output sbom.cdx.json ./
|
|
805
|
+
|
|
806
|
+
# Generate SPDX SBOM
|
|
807
|
+
trivy fs --format spdx-json --output sbom.spdx.json ./
|
|
808
|
+
|
|
809
|
+
# Scan existing SBOM for new vulnerabilities
|
|
810
|
+
trivy sbom sbom.cdx.json --severity CRITICAL,HIGH
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
| Format | Standard Body | Best For |
|
|
814
|
+
|--------|--------------|----------|
|
|
815
|
+
| CycloneDX | OWASP | Security, vulnerability tracking |
|
|
816
|
+
| SPDX | Linux Foundation | License compliance |
|
|
817
|
+
| SWID | ISO/IEC 19770-2 | Software asset management |
|
|
818
|
+
|
|
819
|
+
---
|
|
820
|
+
|
|
821
|
+
## Code Examples
|
|
822
|
+
|
|
823
|
+
### Insecure vs Secure: SQL Query (TypeScript)
|
|
824
|
+
|
|
825
|
+
```typescript
|
|
826
|
+
// INSECURE — CWE-89: SQL injection via string concatenation
|
|
827
|
+
import { Client } from "pg";
|
|
828
|
+
|
|
829
|
+
async function getUserInsecure(client: Client, userId: string) {
|
|
830
|
+
// Attacker passes userId = "1' OR '1'='1" to dump all users
|
|
831
|
+
const query = `SELECT * FROM users WHERE id = '${userId}'`;
|
|
832
|
+
return (await client.query(query)).rows;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
// SECURE — Parameterized query, immune to injection
|
|
836
|
+
async function getUserSecure(client: Client, userId: string) {
|
|
837
|
+
const query = "SELECT * FROM users WHERE id = $1";
|
|
838
|
+
return (await client.query(query, [userId])).rows;
|
|
839
|
+
}
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
### Insecure vs Secure: Command Execution (Python)
|
|
843
|
+
|
|
844
|
+
```python
|
|
845
|
+
# INSECURE — CWE-78: Shell injection via unsanitized input
|
|
846
|
+
import os
|
|
847
|
+
|
|
848
|
+
def ping_host_insecure(hostname: str) -> str:
|
|
849
|
+
# Attacker passes "8.8.8.8; cat /etc/passwd"
|
|
850
|
+
return os.popen(f"ping -c 4 {hostname}").read()
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+
# SECURE — subprocess with argument list, no shell interpolation
|
|
854
|
+
import re
|
|
855
|
+
import subprocess
|
|
856
|
+
|
|
857
|
+
def ping_host_secure(hostname: str) -> str:
|
|
858
|
+
if not re.match(r"^[a-zA-Z0-9.\-]+$", hostname):
|
|
859
|
+
raise ValueError(f"Invalid hostname: {hostname}")
|
|
860
|
+
result = subprocess.run(
|
|
861
|
+
["ping", "-c", "4", hostname],
|
|
862
|
+
capture_output=True, text=True, timeout=30, shell=False,
|
|
863
|
+
)
|
|
864
|
+
return result.stdout
|
|
865
|
+
```
|
|
866
|
+
|
|
867
|
+
### Insecure vs Secure: Deserialization (Python)
|
|
868
|
+
|
|
869
|
+
```python
|
|
870
|
+
# INSECURE — CWE-502: Pickle deserialization of untrusted data
|
|
871
|
+
import pickle
|
|
872
|
+
|
|
873
|
+
def load_data_insecure(raw: bytes) -> dict:
|
|
874
|
+
return pickle.loads(raw) # Attacker crafts payload for arbitrary code exec
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
# SECURE — JSON with explicit schema validation
|
|
878
|
+
import json
|
|
879
|
+
from dataclasses import dataclass
|
|
880
|
+
|
|
881
|
+
@dataclass
|
|
882
|
+
class UserData:
|
|
883
|
+
user_id: str
|
|
884
|
+
name: str
|
|
885
|
+
email: str
|
|
886
|
+
|
|
887
|
+
@classmethod
|
|
888
|
+
def from_json(cls, raw: bytes) -> "UserData":
|
|
889
|
+
data = json.loads(raw)
|
|
890
|
+
for field in ("user_id", "name", "email"):
|
|
891
|
+
if not isinstance(data.get(field), str):
|
|
892
|
+
raise ValueError(f"{field} must be a string")
|
|
893
|
+
return cls(user_id=data["user_id"], name=data["name"], email=data["email"])
|
|
894
|
+
```
|
|
895
|
+
|
|
896
|
+
### Insecure vs Secure: SSRF Prevention (TypeScript)
|
|
897
|
+
|
|
898
|
+
```typescript
|
|
899
|
+
// INSECURE — CWE-918: Unrestricted URL fetch
|
|
900
|
+
async function fetchInsecure(url: string): Promise<string> {
|
|
901
|
+
// Attacker passes "http://169.254.169.254/latest/meta-data/" to steal IAM creds
|
|
902
|
+
return (await fetch(url)).text();
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
// SECURE — URL validation with allowlist and private IP blocking
|
|
906
|
+
import { URL } from "url";
|
|
907
|
+
import * as dns from "dns/promises";
|
|
908
|
+
|
|
909
|
+
const ALLOWED_PROTOCOLS = new Set(["https:"]);
|
|
910
|
+
const ALLOWED_DOMAINS = new Set(["api.example.com", "cdn.example.com"]);
|
|
911
|
+
|
|
912
|
+
async function fetchSecure(rawUrl: string): Promise<string> {
|
|
913
|
+
const parsed = new URL(rawUrl);
|
|
914
|
+
if (!ALLOWED_PROTOCOLS.has(parsed.protocol))
|
|
915
|
+
throw new Error(`Blocked protocol: ${parsed.protocol}`);
|
|
916
|
+
if (!ALLOWED_DOMAINS.has(parsed.hostname))
|
|
917
|
+
throw new Error(`Blocked domain: ${parsed.hostname}`);
|
|
918
|
+
|
|
919
|
+
// Resolve DNS and block private IPs (anti-DNS-rebinding)
|
|
920
|
+
const addrs = await dns.resolve4(parsed.hostname);
|
|
921
|
+
for (const ip of addrs) {
|
|
922
|
+
if (isPrivateIP(ip)) throw new Error(`Private IP: ${ip}`);
|
|
923
|
+
}
|
|
924
|
+
return (await fetch(rawUrl)).text();
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
function isPrivateIP(ip: string): boolean {
|
|
928
|
+
const p = ip.split(".").map(Number);
|
|
929
|
+
return (
|
|
930
|
+
p[0] === 10 || p[0] === 127 ||
|
|
931
|
+
(p[0] === 172 && p[1] >= 16 && p[1] <= 31) ||
|
|
932
|
+
(p[0] === 192 && p[1] === 168) ||
|
|
933
|
+
(p[0] === 169 && p[1] === 254) // Cloud metadata endpoint
|
|
934
|
+
);
|
|
935
|
+
}
|
|
936
|
+
```
|
|
937
|
+
|
|
938
|
+
### Insecure vs Secure: Dependency Management
|
|
939
|
+
|
|
940
|
+
```json5
|
|
941
|
+
// INSECURE — Wildcard and unpinned versions
|
|
942
|
+
{
|
|
943
|
+
"dependencies": {
|
|
944
|
+
"express": "*", // Any version — could pull malicious update
|
|
945
|
+
"lodash": "^4.0.0", // Wide range — could pull vulnerable minor
|
|
946
|
+
"jsonwebtoken": "latest" // No reproducibility
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
```json5
|
|
952
|
+
// SECURE — Exact pinning + lockfile + overrides
|
|
953
|
+
{
|
|
954
|
+
"dependencies": {
|
|
955
|
+
"express": "4.21.1",
|
|
956
|
+
"lodash": "4.17.21",
|
|
957
|
+
"jsonwebtoken": "9.0.2"
|
|
958
|
+
},
|
|
959
|
+
"overrides": {
|
|
960
|
+
"semver": "7.5.4" // Force transitive dep to patched version
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
// Pair with: committed package-lock.json, npm ci in CI,
|
|
964
|
+
// Dependabot/Renovate for updates, Trivy/Snyk SCA on every PR
|
|
965
|
+
```
|
|
966
|
+
|
|
967
|
+
### Unified Security Quality Gate (Python)
|
|
968
|
+
|
|
969
|
+
```python
|
|
970
|
+
"""security_gate.py — Unified quality gate for CI/CD pipelines."""
|
|
971
|
+
import json
|
|
972
|
+
import subprocess
|
|
973
|
+
import sys
|
|
974
|
+
from dataclasses import dataclass, field
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
@dataclass
|
|
978
|
+
class GateResult:
|
|
979
|
+
tool: str
|
|
980
|
+
passed: bool
|
|
981
|
+
critical: int = 0
|
|
982
|
+
high: int = 0
|
|
983
|
+
medium: int = 0
|
|
984
|
+
details: list[str] = field(default_factory=list)
|
|
985
|
+
|
|
986
|
+
|
|
987
|
+
def run_semgrep(src: str) -> GateResult:
|
|
988
|
+
r = subprocess.run(
|
|
989
|
+
["semgrep", "scan", "--config=auto", "--json", "--quiet", src],
|
|
990
|
+
capture_output=True, text=True, timeout=300,
|
|
991
|
+
)
|
|
992
|
+
findings = json.loads(r.stdout).get("results", [])
|
|
993
|
+
sev_map = {"ERROR": "critical", "WARNING": "high", "INFO": "medium"}
|
|
994
|
+
counts = {"critical": 0, "high": 0, "medium": 0}
|
|
995
|
+
for f in findings:
|
|
996
|
+
s = sev_map.get(f["extra"]["severity"], "medium")
|
|
997
|
+
counts[s] += 1
|
|
998
|
+
return GateResult(tool="semgrep", passed=counts["critical"] == 0, **counts)
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
def run_trivy(target: str) -> GateResult:
|
|
1002
|
+
r = subprocess.run(
|
|
1003
|
+
["trivy", "fs", "--format", "json", "--quiet", target],
|
|
1004
|
+
capture_output=True, text=True, timeout=300,
|
|
1005
|
+
)
|
|
1006
|
+
data = json.loads(r.stdout)
|
|
1007
|
+
counts = {"critical": 0, "high": 0, "medium": 0}
|
|
1008
|
+
for t in data.get("Results", []):
|
|
1009
|
+
for v in t.get("Vulnerabilities", []):
|
|
1010
|
+
s = v.get("Severity", "").lower()
|
|
1011
|
+
if s in counts:
|
|
1012
|
+
counts[s] += 1
|
|
1013
|
+
return GateResult(tool="trivy", passed=counts["critical"] == 0, **counts)
|
|
1014
|
+
|
|
1015
|
+
|
|
1016
|
+
def run_gitleaks() -> GateResult:
|
|
1017
|
+
r = subprocess.run(
|
|
1018
|
+
["gitleaks", "detect", "--source=.", "--report-format=json",
|
|
1019
|
+
"--report-path=/dev/stdout"],
|
|
1020
|
+
capture_output=True, text=True, timeout=120,
|
|
1021
|
+
)
|
|
1022
|
+
findings = json.loads(r.stdout) if r.stdout.strip() else []
|
|
1023
|
+
return GateResult(tool="gitleaks", passed=len(findings) == 0,
|
|
1024
|
+
critical=len(findings))
|
|
1025
|
+
|
|
1026
|
+
|
|
1027
|
+
def evaluate(results: list[GateResult], max_c=0, max_h=0, max_m=10) -> bool:
|
|
1028
|
+
tc = sum(r.critical for r in results)
|
|
1029
|
+
th = sum(r.high for r in results)
|
|
1030
|
+
tm = sum(r.medium for r in results)
|
|
1031
|
+
print("\n" + "=" * 50)
|
|
1032
|
+
print("SECURITY QUALITY GATE")
|
|
1033
|
+
print("=" * 50)
|
|
1034
|
+
for r in results:
|
|
1035
|
+
s = "PASS" if r.passed else "FAIL"
|
|
1036
|
+
print(f" [{s}] {r.tool}: C={r.critical} H={r.high} M={r.medium}")
|
|
1037
|
+
passed = tc <= max_c and th <= max_h and tm <= max_m
|
|
1038
|
+
print(f" Total: C={tc} H={th} M={tm} | GATE: {'PASS' if passed else 'FAIL'}")
|
|
1039
|
+
print("=" * 50)
|
|
1040
|
+
return passed
|
|
1041
|
+
|
|
1042
|
+
|
|
1043
|
+
if __name__ == "__main__":
|
|
1044
|
+
results = [run_semgrep("./src"), run_trivy("."), run_gitleaks()]
|
|
1045
|
+
if not evaluate(results):
|
|
1046
|
+
sys.exit(1)
|
|
1047
|
+
```
|
|
1048
|
+
|
|
1049
|
+
---
|
|
1050
|
+
|
|
1051
|
+
> **References:**
|
|
1052
|
+
> - [OWASP Testing Guide v5](https://owasp.org/www-project-web-security-testing-guide/)
|
|
1053
|
+
> - [NIST SP 800-115](https://csrc.nist.gov/pubs/sp/800/115/final)
|
|
1054
|
+
> - [PCI DSS v4.0](https://www.pcisecuritystandards.org/document_library/)
|
|
1055
|
+
> - [CVSS v4.0 Specification](https://www.first.org/cvss/v4.0/)
|
|
1056
|
+
> - [FIRST EPSS](https://www.first.org/epss/)
|
|
1057
|
+
> - [CISA KEV Catalog](https://www.cisa.gov/known-exploited-vulnerabilities-catalog)
|
|
1058
|
+
> - [VulnCheck State of Exploitation 2026](https://www.vulncheck.com/blog/state-of-exploitation-2026)
|
|
1059
|
+
> - [Semgrep Documentation](https://semgrep.dev/docs/)
|
|
1060
|
+
> - [Trivy Documentation](https://trivy.dev/docs/)
|
|
1061
|
+
> - [Nuclei Documentation](https://docs.projectdiscovery.io/opensource/nuclei/overview)
|
|
1062
|
+
> - [OWASP ZAP Documentation](https://www.zaproxy.org/docs/)
|