@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,1209 @@
|
|
|
1
|
+
# Dependency Management Anti-Patterns
|
|
2
|
+
|
|
3
|
+
> **Domain:** Code
|
|
4
|
+
> **Purpose:** Comprehensive reference for identifying, understanding, and preventing dependency
|
|
5
|
+
> management anti-patterns that cause build failures, security breaches, legal liability, and
|
|
6
|
+
> maintenance nightmares across software projects.
|
|
7
|
+
>
|
|
8
|
+
> **Last updated:** 2026-03-08
|
|
9
|
+
> **Documented incidents span:** 2016 -- 2026
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Incident Context: Why This Matters
|
|
14
|
+
|
|
15
|
+
Dependency management failures have caused some of the most consequential incidents in modern
|
|
16
|
+
software engineering. A single 11-line utility package brought down thousands of builds worldwide.
|
|
17
|
+
A social-engineering attack on a popular streaming library stole Bitcoin from cryptocurrency
|
|
18
|
+
wallets. A researcher proved he could infiltrate Apple, Microsoft, and Tesla through name
|
|
19
|
+
collisions in public registries. These are not hypotheticals -- they are documented, real events.
|
|
20
|
+
|
|
21
|
+
The average JavaScript project pulls in over 1,600 transitive dependencies. Each one is an
|
|
22
|
+
attack surface, a license obligation, and a maintenance commitment. The anti-patterns catalogued
|
|
23
|
+
here represent the most common and costly mistakes teams make when managing that surface area.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Anti-Pattern Catalogue
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
### AP-01: Left-Pad Syndrome (Trivial Dependencies)
|
|
32
|
+
|
|
33
|
+
**One-line summary:** Importing an entire package for functionality achievable in a few lines of code.
|
|
34
|
+
|
|
35
|
+
**Severity:** Medium
|
|
36
|
+
**Frequency:** Very High
|
|
37
|
+
**Detection difficulty:** Low
|
|
38
|
+
|
|
39
|
+
**Description:**
|
|
40
|
+
Developers import micro-packages for trivial operations -- padding a string, checking if a number
|
|
41
|
+
is even, flattening an array -- instead of writing the 1-10 lines of code themselves. Each trivial
|
|
42
|
+
dependency adds a node in the dependency graph that must be downloaded, audited, maintained, and
|
|
43
|
+
trusted. When any one of those nodes disappears or is compromised, every project depending on it
|
|
44
|
+
breaks or is exposed.
|
|
45
|
+
|
|
46
|
+
**Real-world incident:**
|
|
47
|
+
On March 22, 2016, developer Azer Koculu unpublished 273 npm packages -- including `left-pad`, an
|
|
48
|
+
11-line string-padding function -- after a trademark dispute with Kik Messenger. Because `left-pad`
|
|
49
|
+
was a transitive dependency of Babel, React, and thousands of other projects, builds across the
|
|
50
|
+
JavaScript ecosystem began failing with 404 errors. npm restored the package from backup within
|
|
51
|
+
two hours and changed its unpublish policy: packages older than 24 hours with dependents can no
|
|
52
|
+
longer be removed.
|
|
53
|
+
|
|
54
|
+
**The anti-pattern in code:**
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
// package.json -- 3 trivial dependencies for one-liner operations
|
|
58
|
+
{
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"is-odd": "^3.0.1",
|
|
61
|
+
"is-even": "^1.0.0",
|
|
62
|
+
"left-pad": "^1.1.3"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**What to do instead:**
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
// Write the trivial logic yourself -- zero dependencies, zero risk
|
|
71
|
+
function leftPad(str, len, ch = ' ') {
|
|
72
|
+
return String(str).padStart(len, ch);
|
|
73
|
+
}
|
|
74
|
+
function isEven(n) {
|
|
75
|
+
return n % 2 === 0;
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Detection signals:**
|
|
80
|
+
- `node_modules` folder contains packages under 20 lines of source
|
|
81
|
+
- Package name describes a single native language operation (is-number, is-string, to-array)
|
|
82
|
+
- `npm ls --all | wc -l` returns a number disproportionate to project complexity
|
|
83
|
+
|
|
84
|
+
**Root cause:** Cargo-cult adoption of "small modules" philosophy without weighing the cost of each
|
|
85
|
+
new dependency against the cost of writing the equivalent code inline.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
### AP-02: Unpinned Dependency Versions
|
|
90
|
+
|
|
91
|
+
**One-line summary:** Using loose version ranges that allow untested versions to enter production.
|
|
92
|
+
|
|
93
|
+
**Severity:** High
|
|
94
|
+
**Frequency:** High
|
|
95
|
+
**Detection difficulty:** Low
|
|
96
|
+
|
|
97
|
+
**Description:**
|
|
98
|
+
Specifying `"^2.0.0"` or `"*"` or `"latest"` in a manifest file allows the package manager to
|
|
99
|
+
resolve any compatible version, including ones never tested with the project. A patch release with
|
|
100
|
+
a regression or a minor release with a breaking behavioral change can silently corrupt builds.
|
|
101
|
+
|
|
102
|
+
**The anti-pattern in code:**
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"dependencies": {
|
|
107
|
+
"express": "*",
|
|
108
|
+
"lodash": ">=4.0.0",
|
|
109
|
+
"axios": "latest"
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**What to do instead:**
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"dependencies": {
|
|
119
|
+
"express": "4.18.2",
|
|
120
|
+
"lodash": "4.17.21",
|
|
121
|
+
"axios": "1.6.7"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Use exact versions in package.json and rely on lock files for reproducibility. Update deliberately
|
|
127
|
+
with `npm update --save-exact` after running the test suite.
|
|
128
|
+
|
|
129
|
+
**Detection signals:**
|
|
130
|
+
- `*`, `latest`, or `>=` operators in dependency version fields
|
|
131
|
+
- CI builds that pass locally but fail on fresh installs
|
|
132
|
+
- "Works on my machine" reports that trace to version differences
|
|
133
|
+
|
|
134
|
+
**Root cause:** Convenience bias -- developers want the latest features automatically and
|
|
135
|
+
underestimate the risk of untested code entering the build.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
### AP-03: Missing or Ignored Lock Files
|
|
140
|
+
|
|
141
|
+
**One-line summary:** Not committing lock files to version control, or deleting them to "fix" conflicts.
|
|
142
|
+
|
|
143
|
+
**Severity:** High
|
|
144
|
+
**Frequency:** High
|
|
145
|
+
**Detection difficulty:** Low
|
|
146
|
+
|
|
147
|
+
**Description:**
|
|
148
|
+
Lock files (`package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `Gemfile.lock`, `poetry.lock`)
|
|
149
|
+
record the exact resolved versions of every direct and transitive dependency. Without them, two
|
|
150
|
+
developers running `npm install` on the same `package.json` can get different dependency trees.
|
|
151
|
+
CI/CD pipelines produce non-reproducible builds. A common anti-pattern is deleting the lock file
|
|
152
|
+
to "resolve" merge conflicts, which silently upgrades every transitive dependency.
|
|
153
|
+
|
|
154
|
+
**The anti-pattern in action:**
|
|
155
|
+
|
|
156
|
+
```gitignore
|
|
157
|
+
# .gitignore -- NEVER do this for applications
|
|
158
|
+
package-lock.json
|
|
159
|
+
yarn.lock
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
# "Fixing" merge conflicts by deleting and regenerating
|
|
164
|
+
rm package-lock.json
|
|
165
|
+
npm install
|
|
166
|
+
# Result: every transitive dependency upgraded to latest compatible version
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**What to do instead:**
|
|
170
|
+
|
|
171
|
+
- Always commit lock files for applications (libraries may choose not to).
|
|
172
|
+
- Resolve lock file conflicts with `npm install --package-lock-only` (npm 5.7+) which
|
|
173
|
+
auto-merges lock file conflicts after fixing `package.json` conflicts manually.
|
|
174
|
+
- Install `npm-merge-driver` to handle lock file merges automatically.
|
|
175
|
+
- In CI, use `npm ci` (not `npm install`) to enforce the exact lock file contents.
|
|
176
|
+
|
|
177
|
+
**Detection signals:**
|
|
178
|
+
- Lock file listed in `.gitignore`
|
|
179
|
+
- CI uses `npm install` instead of `npm ci`
|
|
180
|
+
- Frequent "it works on my machine" issues after pulling latest
|
|
181
|
+
|
|
182
|
+
**Root cause:** Lock files produce noisy diffs in code review and cause merge conflicts. Teams
|
|
183
|
+
choose short-term convenience over reproducibility.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
### AP-04: Dependency Confusion
|
|
188
|
+
|
|
189
|
+
**One-line summary:** Internal package names that collide with public registry names, allowing
|
|
190
|
+
attackers to inject malicious code.
|
|
191
|
+
|
|
192
|
+
**Severity:** Critical
|
|
193
|
+
**Frequency:** Medium
|
|
194
|
+
**Detection difficulty:** Medium
|
|
195
|
+
|
|
196
|
+
**Description:**
|
|
197
|
+
When a project depends on a private/internal package (e.g., `@company/utils`) but the package
|
|
198
|
+
manager also checks public registries, an attacker can publish a higher-version package with the
|
|
199
|
+
same name to the public registry. Most package managers prefer the higher version, pulling in
|
|
200
|
+
the attacker's code instead of the internal package.
|
|
201
|
+
|
|
202
|
+
**Real-world incident:**
|
|
203
|
+
In February 2021, security researcher Alex Birsan demonstrated this attack against Apple,
|
|
204
|
+
Microsoft, Tesla, Yelp, Uber, and over 30 other companies. By publishing packages to npm, PyPI,
|
|
205
|
+
and RubyGems with the same names as internal packages found in public source code, he achieved
|
|
206
|
+
code execution on internal build systems. The eight-month ethical hacking project earned Birsan
|
|
207
|
+
over $130,000 in bug bounties.
|
|
208
|
+
|
|
209
|
+
**The anti-pattern in configuration:**
|
|
210
|
+
|
|
211
|
+
```json
|
|
212
|
+
{
|
|
213
|
+
"dependencies": {
|
|
214
|
+
"company-auth-utils": "^1.0.0"
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
```ini
|
|
220
|
+
# .npmrc -- no registry scoping, checks public npm first
|
|
221
|
+
registry=https://registry.npmjs.org/
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**What to do instead:**
|
|
225
|
+
|
|
226
|
+
```ini
|
|
227
|
+
# .npmrc -- scope internal packages to private registry
|
|
228
|
+
@company:registry=https://npm.company.internal/
|
|
229
|
+
registry=https://registry.npmjs.org/
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
```json
|
|
233
|
+
{
|
|
234
|
+
"dependencies": {
|
|
235
|
+
"@company/auth-utils": "1.0.0"
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Additionally: register placeholder packages on public registries for all internal package names,
|
|
241
|
+
or use tools like `socket.dev` or `npm audit signatures` to verify package provenance.
|
|
242
|
+
|
|
243
|
+
**Detection signals:**
|
|
244
|
+
- Internal packages without scoped names (`@org/package`)
|
|
245
|
+
- `.npmrc` or pip config without explicit registry scoping
|
|
246
|
+
- Private package names discoverable in public repositories or error messages
|
|
247
|
+
|
|
248
|
+
**Root cause:** Package managers default to public registries. Teams assume internal names are
|
|
249
|
+
safe because they are not publicly documented, treating obscurity as security.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
### AP-05: Not Auditing Dependencies
|
|
254
|
+
|
|
255
|
+
**One-line summary:** Installing packages without checking for known vulnerabilities.
|
|
256
|
+
|
|
257
|
+
**Severity:** High
|
|
258
|
+
**Frequency:** Very High
|
|
259
|
+
**Detection difficulty:** Low
|
|
260
|
+
|
|
261
|
+
**Description:**
|
|
262
|
+
Every dependency inherits the security posture of its entire transitive tree. Running `npm install`
|
|
263
|
+
without following up with `npm audit` (or equivalent) means known CVEs in dependencies go
|
|
264
|
+
undetected. Teams that never audit accumulate a growing backlog of exploitable vulnerabilities
|
|
265
|
+
that attackers can find by simply checking public advisory databases.
|
|
266
|
+
|
|
267
|
+
**Real-world incident:**
|
|
268
|
+
In October 2021, the npm package `ua-parser-js` -- with nearly 8 million weekly downloads and
|
|
269
|
+
1,200 dependents -- was hijacked for approximately 4 hours. Three versions (0.7.29, 0.8.0, 1.0.0)
|
|
270
|
+
were published containing a cryptominer and credential-stealing malware targeting Windows and Linux.
|
|
271
|
+
CISA issued an official advisory. The attacker had reportedly offered access to the compromised
|
|
272
|
+
account on a Russian hacking forum for $20,000 prior to the incident.
|
|
273
|
+
|
|
274
|
+
**What to do instead:**
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
# Run after every install
|
|
278
|
+
npm audit
|
|
279
|
+
|
|
280
|
+
# In CI pipelines -- fail the build on critical/high vulnerabilities
|
|
281
|
+
npm audit --audit-level=high
|
|
282
|
+
|
|
283
|
+
# Use dedicated tools for deeper analysis
|
|
284
|
+
npx socket optimize # Socket.dev supply chain analysis
|
|
285
|
+
snyk test # Snyk vulnerability scanning
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Integrate Dependabot, Renovate, or Snyk into the repository to receive automated PRs for
|
|
289
|
+
vulnerable dependencies.
|
|
290
|
+
|
|
291
|
+
**Detection signals:**
|
|
292
|
+
- No `npm audit` step in CI pipeline
|
|
293
|
+
- `npm audit` output shows high/critical vulnerabilities with no tracking issues
|
|
294
|
+
- No dependency scanning tool configured in the repository
|
|
295
|
+
|
|
296
|
+
**Root cause:** Audit output is noisy and overwhelming. Teams defer action because fixing one
|
|
297
|
+
vulnerability often requires cascading upgrades, and no one owns the process.
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
### AP-06: Using Deprecated or Unmaintained Packages
|
|
302
|
+
|
|
303
|
+
**One-line summary:** Depending on packages that are no longer maintained, receiving no security
|
|
304
|
+
patches or bug fixes.
|
|
305
|
+
|
|
306
|
+
**Severity:** High
|
|
307
|
+
**Frequency:** High
|
|
308
|
+
**Detection difficulty:** Medium
|
|
309
|
+
|
|
310
|
+
**Description:**
|
|
311
|
+
A package that has not received a commit in 2+ years, has unresolved security advisories, or is
|
|
312
|
+
explicitly marked as deprecated is a liability. It will not receive patches when vulnerabilities
|
|
313
|
+
are discovered, and it may depend on other unmaintained packages. The longer it stays in the
|
|
314
|
+
dependency tree, the harder it becomes to remove because application code grows around its API.
|
|
315
|
+
|
|
316
|
+
**Real-world incident:**
|
|
317
|
+
The `event-stream` package was effectively abandoned by its original maintainer, Dominic Tarr, who
|
|
318
|
+
had lost interest in maintaining it. In September 2018, a new contributor (operating under the
|
|
319
|
+
username `right9ctrl`) offered to take over maintenance. Tarr handed over publishing rights. The
|
|
320
|
+
new maintainer added `flatmap-stream` as a dependency -- which contained encrypted malicious code
|
|
321
|
+
targeting the Copay Bitcoin wallet. The malware attempted to steal Bitcoin from wallets holding
|
|
322
|
+
over 100 BTC or 1,000 BCH. The attack went undetected for over two months.
|
|
323
|
+
|
|
324
|
+
**Detection signals:**
|
|
325
|
+
- `npm outdated` shows packages multiple major versions behind
|
|
326
|
+
- `npm ls` includes packages with `(deprecated)` annotations
|
|
327
|
+
- Package GitHub repository archived or last commit > 2 years ago
|
|
328
|
+
- Open security advisories with no maintainer response
|
|
329
|
+
|
|
330
|
+
**What to do instead:**
|
|
331
|
+
- Run `npm outdated` regularly and track deprecated packages
|
|
332
|
+
- Evaluate package health before adoption: check commit frequency, open issues/PRs ratio,
|
|
333
|
+
number of maintainers, and bus factor
|
|
334
|
+
- Use `npx is-website-vulnerable` or `npm-check` to identify stale dependencies
|
|
335
|
+
- Plan migration paths before packages reach end-of-life
|
|
336
|
+
|
|
337
|
+
**Root cause:** Initial selection was based on popularity or tutorial recommendations without
|
|
338
|
+
evaluating long-term maintenance viability. Once integrated, migration cost grows with each
|
|
339
|
+
line of code that touches the package API.
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
### AP-07: Typosquatting Vulnerability
|
|
344
|
+
|
|
345
|
+
**One-line summary:** Installing a malicious package due to a typo in the package name.
|
|
346
|
+
|
|
347
|
+
**Severity:** Critical
|
|
348
|
+
**Frequency:** Medium
|
|
349
|
+
**Detection difficulty:** Medium
|
|
350
|
+
|
|
351
|
+
**Description:**
|
|
352
|
+
Attackers publish packages with names that are slight misspellings of popular packages:
|
|
353
|
+
`coffe-script` instead of `coffee-script`, `crossenv` instead of `cross-env`, `electorn`
|
|
354
|
+
instead of `electron`. When a developer types the wrong name in `npm install`, they pull in
|
|
355
|
+
malicious code that may exfiltrate environment variables, install backdoors, or deploy
|
|
356
|
+
cryptominers.
|
|
357
|
+
|
|
358
|
+
**Real-world incidents:**
|
|
359
|
+
- **crossenv (2017):** The user `hacktask` published `crossenv` and over 30 other typosquatted
|
|
360
|
+
packages that stole environment variables (including npm tokens and CI credentials) from
|
|
361
|
+
victims' machines.
|
|
362
|
+
- **SANDWORM_MODE (2026):** 19 typosquatted npm packages impersonating popular utilities
|
|
363
|
+
including AI coding tools and crypto libraries. Once imported, the packages exfiltrated API
|
|
364
|
+
keys, SSH keys, environment variables, and cryptocurrency wallet keys. The malware was
|
|
365
|
+
self-spreading, infecting other projects on the developer's machine.
|
|
366
|
+
|
|
367
|
+
**The anti-pattern in action:**
|
|
368
|
+
|
|
369
|
+
```bash
|
|
370
|
+
# One character off -- pulls in malicious package
|
|
371
|
+
npm install expresss
|
|
372
|
+
npm install cross-env.js
|
|
373
|
+
npm install loadash
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
**What to do instead:**
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
# Always verify the exact package name on npmjs.com before installing
|
|
380
|
+
# Use copy-paste from the official package page
|
|
381
|
+
# After install, verify with:
|
|
382
|
+
npm ls <package-name>
|
|
383
|
+
# Check the package README and repository link match expectations
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
- Use `socket.dev` or npm's built-in typosquat detection
|
|
387
|
+
- Require PR review for any new dependency additions to `package.json`
|
|
388
|
+
- Use an allowlist of approved packages in enterprise environments
|
|
389
|
+
|
|
390
|
+
**Detection signals:**
|
|
391
|
+
- Package name is a near-homograph of a popular package
|
|
392
|
+
- Package has very few downloads but was installed recently
|
|
393
|
+
- Package README is empty or copied from the legitimate package
|
|
394
|
+
- Package repository URL points to a different project
|
|
395
|
+
|
|
396
|
+
**Root cause:** Command-line installation provides no visual confirmation of which package will
|
|
397
|
+
be installed. The typo goes unnoticed because the install succeeds without error.
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
### AP-08: Diamond Dependency Problem
|
|
402
|
+
|
|
403
|
+
**One-line summary:** Two dependencies requiring incompatible versions of the same transitive
|
|
404
|
+
dependency, causing resolution failures or runtime bugs.
|
|
405
|
+
|
|
406
|
+
**Severity:** High
|
|
407
|
+
**Frequency:** Medium
|
|
408
|
+
**Detection difficulty:** High
|
|
409
|
+
|
|
410
|
+
**Description:**
|
|
411
|
+
When package A depends on package C v1.x and package B depends on package C v2.x, and your
|
|
412
|
+
project depends on both A and B, the package manager must resolve a conflict. npm may install
|
|
413
|
+
two copies of C (bloating bundles and causing subtle bugs when `instanceof` checks fail across
|
|
414
|
+
versions). Other ecosystems (Java, Python) may force a single version, causing one consumer to
|
|
415
|
+
break. The problem is NP-complete in the general case and becomes intractable in deep dependency
|
|
416
|
+
trees.
|
|
417
|
+
|
|
418
|
+
**The anti-pattern in code:**
|
|
419
|
+
|
|
420
|
+
```json
|
|
421
|
+
{
|
|
422
|
+
"dependencies": {
|
|
423
|
+
"library-a": "^2.0.0",
|
|
424
|
+
"library-b": "^3.0.0"
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
// library-a requires react@16.x
|
|
428
|
+
// library-b requires react@18.x
|
|
429
|
+
// Result: two copies of React, broken hooks, mysterious runtime errors
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**What to do instead:**
|
|
433
|
+
|
|
434
|
+
- Before adding a dependency, check its peer dependency requirements against your existing tree
|
|
435
|
+
- Use `npm ls <package>` to detect duplicate installations
|
|
436
|
+
- Prefer libraries that declare peer dependencies instead of bundling their own copies
|
|
437
|
+
- Use `npm dedupe` to flatten the tree where version ranges overlap
|
|
438
|
+
- In monorepos, enforce a single version of shared dependencies via workspace constraints
|
|
439
|
+
|
|
440
|
+
**Detection signals:**
|
|
441
|
+
- `npm ls` shows the same package at multiple version levels
|
|
442
|
+
- Bundle size unexpectedly large
|
|
443
|
+
- `instanceof` checks or singleton patterns fail across module boundaries
|
|
444
|
+
- Runtime errors about "hooks can only be called inside a function component" (React-specific)
|
|
445
|
+
|
|
446
|
+
**Root cause:** Each library author independently specifies version ranges without coordinating
|
|
447
|
+
with the broader ecosystem, and semantic versioning provides insufficient guarantees about
|
|
448
|
+
behavioral compatibility.
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
452
|
+
### AP-09: Phantom Dependencies
|
|
453
|
+
|
|
454
|
+
**One-line summary:** Importing modules that exist in `node_modules` but are not listed in
|
|
455
|
+
your `package.json`.
|
|
456
|
+
|
|
457
|
+
**Severity:** Medium
|
|
458
|
+
**Frequency:** High
|
|
459
|
+
**Detection difficulty:** Medium
|
|
460
|
+
|
|
461
|
+
**Description:**
|
|
462
|
+
npm and Yarn hoist transitive dependencies to the root `node_modules` directory, making them
|
|
463
|
+
importable even though your project never declared them. This creates a phantom dependency: code
|
|
464
|
+
that works today but will break silently when the transitive parent upgrades, removes, or
|
|
465
|
+
replaces the hoisted package. The breakage is non-deterministic -- it depends on the install
|
|
466
|
+
order and tree structure.
|
|
467
|
+
|
|
468
|
+
**The anti-pattern in code:**
|
|
469
|
+
|
|
470
|
+
```javascript
|
|
471
|
+
// Your package.json only lists "express"
|
|
472
|
+
// But you directly import a transitive dependency of express:
|
|
473
|
+
const qs = require('qs'); // hoisted from express's dependency tree
|
|
474
|
+
const debug = require('debug'); // hoisted from express's dependency tree
|
|
475
|
+
// These work today but will break unpredictably
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
**What to do instead:**
|
|
479
|
+
|
|
480
|
+
```bash
|
|
481
|
+
# Explicitly declare every package you import
|
|
482
|
+
npm install qs debug --save
|
|
483
|
+
|
|
484
|
+
# Or switch to pnpm, which enforces strict dependency isolation
|
|
485
|
+
# pnpm creates a non-flat node_modules that prevents phantom access
|
|
486
|
+
npm install -g pnpm
|
|
487
|
+
pnpm install
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
**Detection signals:**
|
|
491
|
+
- `require()` or `import` statements for packages not in `package.json`
|
|
492
|
+
- Code that breaks after switching from npm to pnpm
|
|
493
|
+
- Lint rules like `import/no-extraneous-dependencies` (eslint-plugin-import) flagging violations
|
|
494
|
+
- Builds that work locally but fail in clean CI environments
|
|
495
|
+
|
|
496
|
+
**Root cause:** npm's flat `node_modules` structure makes every transitive dependency
|
|
497
|
+
accessible by design. The convenience masks the coupling.
|
|
498
|
+
|
|
499
|
+
---
|
|
500
|
+
|
|
501
|
+
### AP-10: Ignoring Security Advisories
|
|
502
|
+
|
|
503
|
+
**One-line summary:** Seeing `npm audit` warnings and choosing not to act on them.
|
|
504
|
+
|
|
505
|
+
**Severity:** Critical
|
|
506
|
+
**Frequency:** Very High
|
|
507
|
+
**Detection difficulty:** Low
|
|
508
|
+
|
|
509
|
+
**Description:**
|
|
510
|
+
Teams run `npm audit`, see dozens of advisories, feel overwhelmed, and defer action indefinitely.
|
|
511
|
+
The advisories accumulate. Eventually, a critical vulnerability in a deeply nested transitive
|
|
512
|
+
dependency is exploited in production. The audit output had been warning about it for months.
|
|
513
|
+
|
|
514
|
+
**Real-world incident:**
|
|
515
|
+
The Log4Shell vulnerability (CVE-2021-44228, December 2021) in Java's Log4j library was present
|
|
516
|
+
in thousands of applications as a transitive dependency. Organizations that had ignored dependency
|
|
517
|
+
audit tooling or lacked a process for triaging advisories scrambled for weeks to identify and
|
|
518
|
+
patch all affected systems. The vulnerability enabled remote code execution with a single
|
|
519
|
+
crafted log message.
|
|
520
|
+
|
|
521
|
+
**What to do instead:**
|
|
522
|
+
|
|
523
|
+
- Triage advisories by severity: fix critical/high immediately, track medium/low in backlog
|
|
524
|
+
- Use `npm audit fix` for automatic compatible upgrades
|
|
525
|
+
- For breaking fixes: `npm audit fix --force` (test thoroughly after)
|
|
526
|
+
- Configure CI to fail on high/critical: `npm audit --audit-level=high`
|
|
527
|
+
- Assign dependency security as a rotating team responsibility
|
|
528
|
+
- Use Dependabot or Renovate for automated upgrade PRs with CI checks
|
|
529
|
+
|
|
530
|
+
**Detection signals:**
|
|
531
|
+
- `npm audit` returns critical/high vulnerabilities with no open tracking issues
|
|
532
|
+
- Audit output suppressed or piped to `/dev/null` in CI scripts
|
|
533
|
+
- Security advisories older than 30 days with no resolution plan
|
|
534
|
+
|
|
535
|
+
**Root cause:** Alert fatigue. The volume of advisories (many in transitive dependencies the
|
|
536
|
+
team does not directly control) creates a sense of helplessness that leads to inaction.
|
|
537
|
+
|
|
538
|
+
---
|
|
539
|
+
|
|
540
|
+
### AP-11: Protestware and Maintainer Sabotage Risk
|
|
541
|
+
|
|
542
|
+
**One-line summary:** Depending on packages whose sole maintainer may sabotage them in protest
|
|
543
|
+
or frustration.
|
|
544
|
+
|
|
545
|
+
**Severity:** Critical
|
|
546
|
+
**Frequency:** Low
|
|
547
|
+
**Detection difficulty:** High
|
|
548
|
+
|
|
549
|
+
**Description:**
|
|
550
|
+
Open-source maintainers sometimes deliberately corrupt their own packages as protest against
|
|
551
|
+
perceived exploitation by corporations, as political statements, or due to burnout. When the
|
|
552
|
+
sabotaged package is deeply embedded in the dependency tree, the blast radius can affect
|
|
553
|
+
millions of projects.
|
|
554
|
+
|
|
555
|
+
**Real-world incident:**
|
|
556
|
+
In January 2022, Marak Squires -- the sole maintainer of `colors.js` (3.3 billion lifetime
|
|
557
|
+
downloads, 19,000 dependents) and `faker.js` (272 million lifetime downloads, 2,500 dependents)
|
|
558
|
+
-- deliberately sabotaged both packages. `colors.js` received a release containing an infinite
|
|
559
|
+
loop that printed "LIBERTY" and ASCII art to the console, hanging any process that imported it.
|
|
560
|
+
`faker.js` version 6.6.6 was published as an empty package with all source code removed.
|
|
561
|
+
Squires had previously warned in November 2020 that he would stop supporting corporations who
|
|
562
|
+
profited from his free work without compensation. GitHub suspended his account.
|
|
563
|
+
|
|
564
|
+
**Detection signals:**
|
|
565
|
+
- Critical dependency maintained by a single individual
|
|
566
|
+
- Maintainer has expressed burnout or frustration publicly
|
|
567
|
+
- No corporate backing or foundation governance for the package
|
|
568
|
+
- Package has no succession plan or co-maintainers
|
|
569
|
+
|
|
570
|
+
**What to do instead:**
|
|
571
|
+
|
|
572
|
+
- Evaluate bus factor before adopting a dependency (minimum 2 active maintainers preferred)
|
|
573
|
+
- Favor packages backed by foundations (OpenJS, Apache) or companies
|
|
574
|
+
- Pin exact versions and review changelogs before upgrading
|
|
575
|
+
- For critical dependencies, maintain an internal fork as a fallback
|
|
576
|
+
- Consider contributing financially to maintainers via GitHub Sponsors, Open Collective, or
|
|
577
|
+
Tidelift to support sustainable maintenance
|
|
578
|
+
|
|
579
|
+
**Root cause:** The open-source sustainability crisis. Maintainers of critical infrastructure
|
|
580
|
+
packages often work unpaid, and the ecosystem provides no governance safeguards against
|
|
581
|
+
unilateral action by a sole maintainer.
|
|
582
|
+
|
|
583
|
+
---
|
|
584
|
+
|
|
585
|
+
### AP-12: Auto-Updating Major Versions
|
|
586
|
+
|
|
587
|
+
**One-line summary:** Configuring automated tools to merge major version bumps without human review.
|
|
588
|
+
|
|
589
|
+
**Severity:** High
|
|
590
|
+
**Frequency:** Medium
|
|
591
|
+
**Detection difficulty:** Low
|
|
592
|
+
|
|
593
|
+
**Description:**
|
|
594
|
+
Dependabot, Renovate, or similar tools can be configured to auto-merge dependency updates.
|
|
595
|
+
While this is reasonable for patch versions with good test coverage, auto-merging major version
|
|
596
|
+
bumps is dangerous. Major versions signal intentional breaking changes: removed APIs, changed
|
|
597
|
+
default behaviors, dropped platform support. Auto-merging them bypasses the human judgment
|
|
598
|
+
needed to evaluate migration impact.
|
|
599
|
+
|
|
600
|
+
**The anti-pattern in configuration:**
|
|
601
|
+
|
|
602
|
+
```json
|
|
603
|
+
// renovate.json -- auto-merging everything
|
|
604
|
+
{
|
|
605
|
+
"extends": ["config:base"],
|
|
606
|
+
"automerge": true,
|
|
607
|
+
"major": {
|
|
608
|
+
"automerge": true
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
**What to do instead:**
|
|
614
|
+
|
|
615
|
+
```json
|
|
616
|
+
// renovate.json -- auto-merge patches only, require review for major/minor
|
|
617
|
+
{
|
|
618
|
+
"extends": ["config:base"],
|
|
619
|
+
"patch": {
|
|
620
|
+
"automerge": true
|
|
621
|
+
},
|
|
622
|
+
"minor": {
|
|
623
|
+
"automerge": false
|
|
624
|
+
},
|
|
625
|
+
"major": {
|
|
626
|
+
"automerge": false,
|
|
627
|
+
"labels": ["breaking-change", "needs-review"]
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
**Detection signals:**
|
|
633
|
+
- Major version bumps merged without changelog review
|
|
634
|
+
- Production breakages that trace to auto-merged dependency updates
|
|
635
|
+
- Renovate/Dependabot configured with blanket `automerge: true`
|
|
636
|
+
|
|
637
|
+
**Root cause:** Teams want to reduce dependency maintenance toil and assume that CI tests will
|
|
638
|
+
catch all breaking changes. Tests cover application behavior, not every edge case of every
|
|
639
|
+
dependency's API surface.
|
|
640
|
+
|
|
641
|
+
---
|
|
642
|
+
|
|
643
|
+
### AP-13: Vendoring Without Updating
|
|
644
|
+
|
|
645
|
+
**One-line summary:** Copying dependency source code into the repository and never updating it.
|
|
646
|
+
|
|
647
|
+
**Severity:** High
|
|
648
|
+
**Frequency:** Medium
|
|
649
|
+
**Detection difficulty:** Medium
|
|
650
|
+
|
|
651
|
+
**Description:**
|
|
652
|
+
Vendoring (copying dependency source into the repo) provides isolation from registry outages
|
|
653
|
+
and ensures reproducibility. But vendored code goes stale silently. Without the package manager's
|
|
654
|
+
update mechanism, security patches and bug fixes never arrive. The vendored copy drifts further
|
|
655
|
+
from upstream with each release, making eventual updates exponentially harder.
|
|
656
|
+
|
|
657
|
+
**The anti-pattern in practice:**
|
|
658
|
+
|
|
659
|
+
```
|
|
660
|
+
vendor/
|
|
661
|
+
lodash/ # copied in 2021, now 47 CVEs behind
|
|
662
|
+
moment/ # deprecated in 2020, vendored copy still used
|
|
663
|
+
leftpad.js # copied from npm in 2016, never touched again
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
**What to do instead:**
|
|
667
|
+
|
|
668
|
+
- If vendoring, maintain a manifest mapping each vendored package to its upstream version
|
|
669
|
+
- Schedule quarterly vendor refresh cycles
|
|
670
|
+
- Run vulnerability scanners against vendor directories (not just `node_modules`)
|
|
671
|
+
- Consider using lock files instead of vendoring -- they solve the reproducibility problem
|
|
672
|
+
without the maintenance burden of keeping copies in sync
|
|
673
|
+
|
|
674
|
+
**Detection signals:**
|
|
675
|
+
- `vendor/` directory with no update log or version manifest
|
|
676
|
+
- Vendored packages multiple major versions behind upstream
|
|
677
|
+
- Security scanners that skip `vendor/` directories
|
|
678
|
+
- Git blame shows vendored files untouched for years
|
|
679
|
+
|
|
680
|
+
**Root cause:** Vendoring front-loads reproducibility at the cost of ongoing maintenance.
|
|
681
|
+
Teams that vendor rarely budget for the maintenance, and the staleness is invisible until a
|
|
682
|
+
CVE surfaces.
|
|
683
|
+
|
|
684
|
+
---
|
|
685
|
+
|
|
686
|
+
### AP-14: Circular Dependencies
|
|
687
|
+
|
|
688
|
+
**One-line summary:** Two or more packages depending on each other, creating import cycles that
|
|
689
|
+
cause load-order bugs and make the code untestable.
|
|
690
|
+
|
|
691
|
+
**Severity:** Medium
|
|
692
|
+
**Frequency:** Medium
|
|
693
|
+
**Detection difficulty:** Medium
|
|
694
|
+
|
|
695
|
+
**Description:**
|
|
696
|
+
When module A imports module B and module B imports module A (directly or transitively), the
|
|
697
|
+
result is a circular dependency. In Node.js, this produces partially initialized modules --
|
|
698
|
+
the `require()` call returns an incomplete exports object, leading to `undefined is not a
|
|
699
|
+
function` errors that only manifest at runtime and depend on which module loads first. Circular
|
|
700
|
+
dependencies also make it impossible to test modules in isolation and signal tangled
|
|
701
|
+
architectural boundaries.
|
|
702
|
+
|
|
703
|
+
**The anti-pattern in code:**
|
|
704
|
+
|
|
705
|
+
```javascript
|
|
706
|
+
// user.js
|
|
707
|
+
const Order = require('./order');
|
|
708
|
+
class User {
|
|
709
|
+
getOrders() { return Order.findByUser(this.id); }
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
// order.js
|
|
713
|
+
const User = require('./user');
|
|
714
|
+
class Order {
|
|
715
|
+
getUser() { return User.findById(this.userId); }
|
|
716
|
+
}
|
|
717
|
+
// Result: one of these will get an empty object from require()
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
**What to do instead:**
|
|
721
|
+
|
|
722
|
+
```javascript
|
|
723
|
+
// Extract shared logic into a third module, or use dependency inversion
|
|
724
|
+
// user-repository.js -- depends on nothing
|
|
725
|
+
// order-repository.js -- depends on nothing
|
|
726
|
+
// user-service.js -- depends on both repositories (no cycle)
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
- Use `madge --circular` to detect circular dependencies in JavaScript/TypeScript
|
|
730
|
+
- Configure ESLint rule `import/no-cycle` to prevent new cycles
|
|
731
|
+
- Apply the Dependency Inversion Principle: both modules depend on an abstraction
|
|
732
|
+
|
|
733
|
+
**Detection signals:**
|
|
734
|
+
- `madge --circular src/` reports cycles
|
|
735
|
+
- `undefined is not a function` errors that appear only in certain import orders
|
|
736
|
+
- Modules that cannot be unit tested without importing half the application
|
|
737
|
+
- ESLint `import/no-cycle` violations
|
|
738
|
+
|
|
739
|
+
**Root cause:** Organic growth without architectural review. Each developer adds the import
|
|
740
|
+
they need without checking whether it creates a cycle.
|
|
741
|
+
|
|
742
|
+
---
|
|
743
|
+
|
|
744
|
+
### AP-15: Heavy Framework for Simple Task
|
|
745
|
+
|
|
746
|
+
**One-line summary:** Installing a large framework when a small library or native API suffices.
|
|
747
|
+
|
|
748
|
+
**Severity:** Medium
|
|
749
|
+
**Frequency:** High
|
|
750
|
+
**Detection difficulty:** Low
|
|
751
|
+
|
|
752
|
+
**Description:**
|
|
753
|
+
Pulling in a 500KB framework to solve a 5-line problem. Using Moment.js (330KB minified) to
|
|
754
|
+
format a single date. Installing Lodash (530 functions) to use `_.get()`. Adding jQuery to
|
|
755
|
+
toggle a CSS class. The framework brings hundreds of transitive dependencies, increases bundle
|
|
756
|
+
size, slows installation, and expands the attack surface -- all for functionality the platform
|
|
757
|
+
provides natively.
|
|
758
|
+
|
|
759
|
+
**The anti-pattern in code:**
|
|
760
|
+
|
|
761
|
+
```javascript
|
|
762
|
+
// Installing 72KB to check if a value is deeply nested
|
|
763
|
+
import _ from 'lodash';
|
|
764
|
+
const value = _.get(obj, 'a.b.c.d', 'default');
|
|
765
|
+
|
|
766
|
+
// Installing 330KB to format one date
|
|
767
|
+
import moment from 'moment';
|
|
768
|
+
const formatted = moment().format('YYYY-MM-DD');
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
**What to do instead:**
|
|
772
|
+
|
|
773
|
+
```javascript
|
|
774
|
+
// Native optional chaining (0 bytes, 0 dependencies)
|
|
775
|
+
const value = obj?.a?.b?.c?.d ?? 'default';
|
|
776
|
+
|
|
777
|
+
// Native Intl.DateTimeFormat (0 bytes, 0 dependencies)
|
|
778
|
+
const formatted = new Date().toISOString().split('T')[0];
|
|
779
|
+
|
|
780
|
+
// If you need a date library, use a lightweight alternative
|
|
781
|
+
// date-fns: tree-shakeable, import only what you use
|
|
782
|
+
import { format } from 'date-fns';
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
**Detection signals:**
|
|
786
|
+
- `npm ls --all | wc -l` disproportionate to project complexity
|
|
787
|
+
- Bundle analysis shows large packages contributing < 5% utilized exports
|
|
788
|
+
- `import-cost` VS Code extension showing large import sizes for simple operations
|
|
789
|
+
- `webpack-bundle-analyzer` showing dominant chunks from underused libraries
|
|
790
|
+
|
|
791
|
+
**Root cause:** Familiarity bias. Developers reach for the framework they know rather than
|
|
792
|
+
checking whether native APIs or lighter alternatives exist. Tutorial-driven development
|
|
793
|
+
reinforces framework defaults.
|
|
794
|
+
|
|
795
|
+
---
|
|
796
|
+
|
|
797
|
+
### AP-16: Not Checking Dependency Licenses
|
|
798
|
+
|
|
799
|
+
**One-line summary:** Using dependencies with incompatible or viral licenses that create
|
|
800
|
+
legal liability.
|
|
801
|
+
|
|
802
|
+
**Severity:** High
|
|
803
|
+
**Frequency:** High
|
|
804
|
+
**Detection difficulty:** Medium
|
|
805
|
+
|
|
806
|
+
**Description:**
|
|
807
|
+
Every npm package has a license. GPL-licensed dependencies in a proprietary product may legally
|
|
808
|
+
require releasing the entire application's source code. AGPL extends this obligation to
|
|
809
|
+
server-side usage. SSPL restricts cloud deployment. A single React app setup involves ~1,600
|
|
810
|
+
dependencies, each with its own license. Ignoring license compliance can result in litigation,
|
|
811
|
+
forced open-sourcing of proprietary code, or injunctions against distribution.
|
|
812
|
+
|
|
813
|
+
**Real-world consequence:**
|
|
814
|
+
Orange S.A. was ordered to pay over 900,000 EUR in damages for modifying and distributing
|
|
815
|
+
GPL-licensed Lasso software without complying with the GPL's copyleft requirements.
|
|
816
|
+
|
|
817
|
+
**What to do instead:**
|
|
818
|
+
|
|
819
|
+
```bash
|
|
820
|
+
# Audit licenses across all dependencies
|
|
821
|
+
npx license-checker --summary
|
|
822
|
+
npx license-checker --failOn "GPL-2.0;GPL-3.0;AGPL-3.0;SSPL-1.0"
|
|
823
|
+
|
|
824
|
+
# Use FOSSA or Snyk for continuous license compliance monitoring
|
|
825
|
+
# Define an approved license allowlist in CI
|
|
826
|
+
```
|
|
827
|
+
|
|
828
|
+
Maintain a license policy document. Classify licenses into: approved (MIT, BSD, Apache-2.0,
|
|
829
|
+
ISC), restricted (GPL, AGPL, SSPL -- require legal review), and banned. Automate enforcement
|
|
830
|
+
in CI.
|
|
831
|
+
|
|
832
|
+
**Detection signals:**
|
|
833
|
+
- No license audit step in CI pipeline
|
|
834
|
+
- `license-checker` output contains GPL/AGPL packages in a proprietary project
|
|
835
|
+
- No legal review process for new dependency additions
|
|
836
|
+
- `package.json` contains packages with `UNLICENSED` or missing license fields
|
|
837
|
+
|
|
838
|
+
**Root cause:** License compliance is perceived as a legal team responsibility, not a
|
|
839
|
+
development concern. Most developers never read the license field of the packages they install.
|
|
840
|
+
|
|
841
|
+
---
|
|
842
|
+
|
|
843
|
+
### AP-17: Running npm install with Elevated Privileges
|
|
844
|
+
|
|
845
|
+
**One-line summary:** Using `sudo npm install` gives untrusted package scripts root access
|
|
846
|
+
to the system.
|
|
847
|
+
|
|
848
|
+
**Severity:** Critical
|
|
849
|
+
**Frequency:** Medium
|
|
850
|
+
**Detection difficulty:** Low
|
|
851
|
+
|
|
852
|
+
**Description:**
|
|
853
|
+
When `npm install` runs, it executes any `preinstall`, `install`, and `postinstall` scripts
|
|
854
|
+
defined in each package. Running this as root means those scripts execute with full system
|
|
855
|
+
privileges. A malicious or compromised package can modify system files, install rootkits, create
|
|
856
|
+
new user accounts, or exfiltrate sensitive data from anywhere on the filesystem. Additionally,
|
|
857
|
+
`sudo npm install` creates root-owned files in the npm cache and `node_modules`, causing
|
|
858
|
+
EACCES permission errors on subsequent non-sudo installs.
|
|
859
|
+
|
|
860
|
+
**The anti-pattern in action:**
|
|
861
|
+
|
|
862
|
+
```bash
|
|
863
|
+
# NEVER do this
|
|
864
|
+
sudo npm install -g some-package
|
|
865
|
+
sudo npm install
|
|
866
|
+
```
|
|
867
|
+
|
|
868
|
+
**What to do instead:**
|
|
869
|
+
|
|
870
|
+
```bash
|
|
871
|
+
# Use a Node version manager -- no sudo needed
|
|
872
|
+
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
|
|
873
|
+
nvm install --lts
|
|
874
|
+
npm install -g some-package # no sudo required
|
|
875
|
+
|
|
876
|
+
# Or change npm's default directory
|
|
877
|
+
mkdir ~/.npm-global
|
|
878
|
+
npm config set prefix '~/.npm-global'
|
|
879
|
+
# Add ~/.npm-global/bin to PATH
|
|
880
|
+
```
|
|
881
|
+
|
|
882
|
+
**Detection signals:**
|
|
883
|
+
- CI/CD scripts containing `sudo npm`
|
|
884
|
+
- Developer documentation instructing `sudo npm install`
|
|
885
|
+
- Permission errors (EACCES) appearing on developer machines
|
|
886
|
+
- Root-owned files in `~/.npm` or project `node_modules`
|
|
887
|
+
|
|
888
|
+
**Root cause:** Default Node.js installations place global packages in system directories
|
|
889
|
+
(`/usr/local/lib`) requiring root access. Developers reach for `sudo` as the quick fix instead
|
|
890
|
+
of configuring proper directory ownership or using nvm.
|
|
891
|
+
|
|
892
|
+
---
|
|
893
|
+
|
|
894
|
+
### AP-18: Copy-Paste Dependency Adoption
|
|
895
|
+
|
|
896
|
+
**One-line summary:** Adding dependencies found in Stack Overflow answers or blog tutorials
|
|
897
|
+
without evaluating them.
|
|
898
|
+
|
|
899
|
+
**Severity:** Medium
|
|
900
|
+
**Frequency:** Very High
|
|
901
|
+
**Detection difficulty:** Low
|
|
902
|
+
|
|
903
|
+
**Description:**
|
|
904
|
+
A developer searches for "how to parse CSV in Node.js," finds a Stack Overflow answer
|
|
905
|
+
recommending `obscure-csv-parser`, runs `npm install`, and moves on. The package may be
|
|
906
|
+
unmaintained, have known vulnerabilities, or be a typosquatted version of the legitimate
|
|
907
|
+
package. Tutorial-driven development leads to dependency sprawl because each tutorial recommends
|
|
908
|
+
its own preferred packages, and developers accumulate them without deduplication.
|
|
909
|
+
|
|
910
|
+
**The anti-pattern in action:**
|
|
911
|
+
|
|
912
|
+
```bash
|
|
913
|
+
# From a 2019 Stack Overflow answer -- package abandoned since 2020
|
|
914
|
+
npm install csv-parse-easy
|
|
915
|
+
# From a blog post -- typosquatted name
|
|
916
|
+
npm install expresss-validator
|
|
917
|
+
# From a tutorial -- entire framework for one feature
|
|
918
|
+
npm install full-framework-x
|
|
919
|
+
```
|
|
920
|
+
|
|
921
|
+
**What to do instead:**
|
|
922
|
+
|
|
923
|
+
Before installing any new dependency, evaluate:
|
|
924
|
+
|
|
925
|
+
1. **Necessity:** Can this be done with native APIs or existing dependencies?
|
|
926
|
+
2. **Maintenance:** Last commit date? Open issues? Active maintainers?
|
|
927
|
+
3. **Popularity:** Weekly downloads? Dependents? Stars (as a rough signal)?
|
|
928
|
+
4. **Security:** `npm audit` results? Known CVEs? Socket.dev analysis?
|
|
929
|
+
5. **License:** Compatible with your project's license?
|
|
930
|
+
6. **Size:** What is the install size and transitive dependency count?
|
|
931
|
+
|
|
932
|
+
Use `npm info <package>` and check npmjs.com before every `npm install`.
|
|
933
|
+
|
|
934
|
+
**Detection signals:**
|
|
935
|
+
- Package additions with no corresponding evaluation comment in the PR
|
|
936
|
+
- Dependencies that duplicate functionality already available in the project
|
|
937
|
+
- Packages with < 100 weekly downloads in a production project
|
|
938
|
+
|
|
939
|
+
**Root cause:** Time pressure and the "someone else solved this" mindset. Evaluating a
|
|
940
|
+
dependency takes 5-10 minutes; copy-pasting an `npm install` command takes 5 seconds.
|
|
941
|
+
|
|
942
|
+
---
|
|
943
|
+
|
|
944
|
+
### AP-19: Not Reading Dependency Source Code
|
|
945
|
+
|
|
946
|
+
**One-line summary:** Trusting package code sight-unseen because it has many downloads or stars.
|
|
947
|
+
|
|
948
|
+
**Severity:** High
|
|
949
|
+
**Frequency:** Very High
|
|
950
|
+
**Detection difficulty:** High
|
|
951
|
+
|
|
952
|
+
**Description:**
|
|
953
|
+
Downloads and stars are vanity metrics, not security guarantees. The `event-stream` attack
|
|
954
|
+
succeeded because no one reviewed the `flatmap-stream` dependency that was added -- despite the
|
|
955
|
+
package having 2 million weekly downloads at the time. Reading the source code of direct
|
|
956
|
+
dependencies (at minimum) and auditing `install` scripts catches malicious code, unnecessary
|
|
957
|
+
complexity, and quality issues that no automated tool detects.
|
|
958
|
+
|
|
959
|
+
**Real-world incident:**
|
|
960
|
+
The `event-stream` malware went undetected for over two months (September to November 2018)
|
|
961
|
+
despite the package's enormous download numbers. The malicious code in `flatmap-stream` was
|
|
962
|
+
encrypted and only decrypted at runtime when specific conditions were met (the Copay Bitcoin
|
|
963
|
+
wallet was present), making static analysis detection difficult. It was eventually discovered
|
|
964
|
+
by a developer who happened to investigate a deprecation warning.
|
|
965
|
+
|
|
966
|
+
**What to do instead:**
|
|
967
|
+
|
|
968
|
+
```bash
|
|
969
|
+
# Review install scripts before installing
|
|
970
|
+
npm pack <package-name> # downloads tarball without executing scripts
|
|
971
|
+
tar -xzf <package>.tgz # extract and review contents
|
|
972
|
+
|
|
973
|
+
# Or view source on npm
|
|
974
|
+
npm view <package-name> repository.url
|
|
975
|
+
# Visit the repository and read the code
|
|
976
|
+
|
|
977
|
+
# Disable install scripts for untrusted packages
|
|
978
|
+
npm install --ignore-scripts <package-name>
|
|
979
|
+
# Then review and run scripts manually
|
|
980
|
+
```
|
|
981
|
+
|
|
982
|
+
**Detection signals:**
|
|
983
|
+
- New dependencies added to `package.json` without code review comments
|
|
984
|
+
- `install` scripts in `package.json` that download or execute remote code
|
|
985
|
+
- Minified or obfuscated source in published npm packages
|
|
986
|
+
- Package source on npm differs from source in the linked repository
|
|
987
|
+
|
|
988
|
+
**Root cause:** Scale makes manual review seem impractical. Teams rationalize that "if it had
|
|
989
|
+
malware, someone else would have found it by now," creating a bystander effect across millions
|
|
990
|
+
of users.
|
|
991
|
+
|
|
992
|
+
---
|
|
993
|
+
|
|
994
|
+
### AP-20: Too Many Dependencies for Simple Projects
|
|
995
|
+
|
|
996
|
+
**One-line summary:** A project with minimal business logic but hundreds of dependencies,
|
|
997
|
+
creating an outsized attack surface and maintenance burden.
|
|
998
|
+
|
|
999
|
+
**Severity:** Medium
|
|
1000
|
+
**Frequency:** High
|
|
1001
|
+
**Detection difficulty:** Low
|
|
1002
|
+
|
|
1003
|
+
**Description:**
|
|
1004
|
+
A simple REST API server with 5 endpoints should not have 1,200 transitive dependencies.
|
|
1005
|
+
Each dependency is a potential point of failure: a supply chain attack vector, a license
|
|
1006
|
+
obligation, a source of breaking changes, and a CI/CD performance drag. Dependency bloat
|
|
1007
|
+
often stems from framework defaults (create-react-app installs ~1,600 packages) and a culture
|
|
1008
|
+
of reaching for packages instead of writing code.
|
|
1009
|
+
|
|
1010
|
+
**The anti-pattern in numbers:**
|
|
1011
|
+
|
|
1012
|
+
```bash
|
|
1013
|
+
$ npm ls --all | wc -l
|
|
1014
|
+
1847
|
|
1015
|
+
$ wc -l src/**/*.js
|
|
1016
|
+
312 total
|
|
1017
|
+
# 1,847 dependencies for 312 lines of application code
|
|
1018
|
+
```
|
|
1019
|
+
|
|
1020
|
+
**What to do instead:**
|
|
1021
|
+
|
|
1022
|
+
- Start with zero dependencies and add them only when justified
|
|
1023
|
+
- Use native APIs: `fetch()` instead of `axios`, `URL` instead of `url-parse`,
|
|
1024
|
+
`crypto.randomUUID()` instead of `uuid`
|
|
1025
|
+
- Choose focused libraries over kitchen-sink frameworks
|
|
1026
|
+
- Periodically audit: `npx depcheck` identifies unused dependencies
|
|
1027
|
+
- Track dependency count as a project health metric
|
|
1028
|
+
|
|
1029
|
+
**Detection signals:**
|
|
1030
|
+
- Dependency-to-application-code ratio exceeding 100:1
|
|
1031
|
+
- `npx depcheck` listing multiple unused dependencies
|
|
1032
|
+
- `npm install` taking minutes for a project with a few source files
|
|
1033
|
+
- `node_modules` larger than the application source by orders of magnitude
|
|
1034
|
+
|
|
1035
|
+
**Root cause:** The npm ecosystem's culture of extreme modularity combined with
|
|
1036
|
+
framework scaffolding tools that install hundreds of packages by default. Teams never
|
|
1037
|
+
question the defaults.
|
|
1038
|
+
|
|
1039
|
+
---
|
|
1040
|
+
|
|
1041
|
+
## Root Cause Analysis
|
|
1042
|
+
|
|
1043
|
+
The twenty anti-patterns above cluster around five systemic root causes:
|
|
1044
|
+
|
|
1045
|
+
### 1. The Convenience Trap
|
|
1046
|
+
Package managers make installation frictionless (`npm install` takes seconds) but provide no
|
|
1047
|
+
friction for evaluation. The asymmetry between ease of adding and cost of maintaining creates
|
|
1048
|
+
an accumulation problem.
|
|
1049
|
+
|
|
1050
|
+
### 2. The Trust Assumption
|
|
1051
|
+
Developers treat the npm registry as a trusted source, but it is an open publishing platform
|
|
1052
|
+
with minimal vetting. The assumption that "popular means safe" has been disproven by
|
|
1053
|
+
event-stream (2M weekly downloads, compromised), ua-parser-js (8M weekly downloads, hijacked),
|
|
1054
|
+
and colors.js (3.3B lifetime downloads, sabotaged).
|
|
1055
|
+
|
|
1056
|
+
### 3. The Externality Problem
|
|
1057
|
+
The cost of a dependency is distributed across the entire team and lifetime of the project, but
|
|
1058
|
+
the benefit (saved developer time) is captured immediately by one individual. This creates a
|
|
1059
|
+
tragedy of the commons where everyone adds dependencies and no one audits or removes them.
|
|
1060
|
+
|
|
1061
|
+
### 4. The Sustainability Crisis
|
|
1062
|
+
Critical infrastructure packages are maintained by unpaid individuals with no governance
|
|
1063
|
+
structure. When a maintainer burns out, abandons the project, or acts unilaterally, the
|
|
1064
|
+
ecosystem has no fallback. The event-stream and colors.js incidents are symptoms of this
|
|
1065
|
+
structural problem.
|
|
1066
|
+
|
|
1067
|
+
### 5. The Visibility Gap
|
|
1068
|
+
Transitive dependencies are invisible to most developers. The packages they consciously chose
|
|
1069
|
+
represent a fraction of their actual dependency tree. Tools like `npm ls --all` exist but are
|
|
1070
|
+
rarely used, creating a false sense of control over a dependency surface that is orders of
|
|
1071
|
+
magnitude larger than perceived.
|
|
1072
|
+
|
|
1073
|
+
---
|
|
1074
|
+
|
|
1075
|
+
## Self-Check Questions
|
|
1076
|
+
|
|
1077
|
+
Use these questions during code review, architecture review, or dependency audit sessions:
|
|
1078
|
+
|
|
1079
|
+
### Before Adding a Dependency
|
|
1080
|
+
- [ ] Can this be done in < 20 lines with native APIs or existing dependencies?
|
|
1081
|
+
- [ ] Does this package have at least 2 active maintainers?
|
|
1082
|
+
- [ ] When was the last release? Is the package actively maintained?
|
|
1083
|
+
- [ ] What is the transitive dependency count? (`npm info <pkg> dependencies`)
|
|
1084
|
+
- [ ] What license does it use? Is it compatible with our project?
|
|
1085
|
+
- [ ] Have I checked `npm audit` after adding it?
|
|
1086
|
+
- [ ] Have I read the package's `install` scripts?
|
|
1087
|
+
- [ ] Does the package name exactly match what I intended? (typosquatting check)
|
|
1088
|
+
|
|
1089
|
+
### During Ongoing Maintenance
|
|
1090
|
+
- [ ] Is `npm audit` integrated into our CI pipeline with a fail threshold?
|
|
1091
|
+
- [ ] Are lock files committed and is CI using `npm ci`?
|
|
1092
|
+
- [ ] Do we have a process for triaging and resolving security advisories?
|
|
1093
|
+
- [ ] Are Dependabot/Renovate PRs being reviewed and merged regularly?
|
|
1094
|
+
- [ ] When did we last run `npx depcheck` to find unused dependencies?
|
|
1095
|
+
- [ ] Are any dependencies deprecated or unmaintained?
|
|
1096
|
+
- [ ] Do we have license compliance automation in CI?
|
|
1097
|
+
|
|
1098
|
+
### Architecture-Level Checks
|
|
1099
|
+
- [ ] Are internal packages scoped (`@org/package`) to prevent dependency confusion?
|
|
1100
|
+
- [ ] Is our `.npmrc` configured to route scoped packages to our private registry?
|
|
1101
|
+
- [ ] Do we have a phantom dependency detection mechanism (pnpm or ESLint rule)?
|
|
1102
|
+
- [ ] Is our dependency-to-code ratio reasonable for the project's complexity?
|
|
1103
|
+
- [ ] Are we vendoring anything? If so, is there a scheduled update cycle?
|
|
1104
|
+
- [ ] Are circular dependencies being detected and prevented?
|
|
1105
|
+
|
|
1106
|
+
---
|
|
1107
|
+
|
|
1108
|
+
## Code Smell Quick Reference
|
|
1109
|
+
|
|
1110
|
+
| Smell | Anti-Pattern | Severity | Quick Check |
|
|
1111
|
+
|---|---|---|---|
|
|
1112
|
+
| `node_modules` > 500MB for a simple project | AP-20: Too Many Dependencies | Medium | `du -sh node_modules` |
|
|
1113
|
+
| `*` or `latest` in version field | AP-02: Unpinned Versions | High | `grep '"*"\|"latest"' package.json` |
|
|
1114
|
+
| Lock file in `.gitignore` | AP-03: Missing Lock Files | High | `grep lock .gitignore` |
|
|
1115
|
+
| `sudo npm install` in docs or scripts | AP-17: Elevated Privileges | Critical | `grep -r "sudo npm" .` |
|
|
1116
|
+
| Packages with < 20 lines of source | AP-01: Left-Pad Syndrome | Medium | Manual review of small deps |
|
|
1117
|
+
| `require()` of undeclared package | AP-09: Phantom Dependencies | Medium | `npx depcheck` or ESLint rule |
|
|
1118
|
+
| Internal package without `@scope` | AP-04: Dependency Confusion | Critical | Review `.npmrc` and `package.json` |
|
|
1119
|
+
| `npm audit` showing ignored criticals | AP-10: Ignoring Advisories | Critical | `npm audit --audit-level=critical` |
|
|
1120
|
+
| Same package at multiple versions in tree | AP-08: Diamond Dependency | High | `npm ls <pkg>` |
|
|
1121
|
+
| `madge --circular` reporting cycles | AP-14: Circular Dependencies | Medium | `npx madge --circular src/` |
|
|
1122
|
+
| Lodash/Moment for one function | AP-15: Heavy Framework | Medium | Bundle analyzer |
|
|
1123
|
+
| GPL/AGPL in proprietary project | AP-16: License Non-Compliance | High | `npx license-checker --summary` |
|
|
1124
|
+
| Vendored dir with no update log | AP-13: Stale Vendors | High | `git log --oneline vendor/` |
|
|
1125
|
+
| Sole maintainer on critical dep | AP-11: Protestware Risk | Critical | Check npm/GitHub maintainer list |
|
|
1126
|
+
| Auto-merge on major versions | AP-12: Auto-Update Majors | High | Review Renovate/Dependabot config |
|
|
1127
|
+
| Dependency added without PR discussion | AP-18: Copy-Paste Adoption | Medium | PR review process |
|
|
1128
|
+
| Package with obfuscated source | AP-19: Unreviewed Source | High | `npm pack` and inspect |
|
|
1129
|
+
| Near-homograph package name | AP-07: Typosquatting | Critical | Verify name on npmjs.com |
|
|
1130
|
+
| Deprecated packages in `npm ls` | AP-06: Unmaintained Packages | High | `npm outdated` |
|
|
1131
|
+
| Blanket `automerge: true` in Renovate | AP-12: Auto-Update Majors | High | Review bot config |
|
|
1132
|
+
|
|
1133
|
+
---
|
|
1134
|
+
|
|
1135
|
+
## Recommended Tooling
|
|
1136
|
+
|
|
1137
|
+
| Tool | Purpose | Integration |
|
|
1138
|
+
|---|---|---|
|
|
1139
|
+
| `npm audit` | Known vulnerability detection | CLI, CI |
|
|
1140
|
+
| `npm ci` | Reproducible installs from lock file | CI |
|
|
1141
|
+
| `npx depcheck` | Detect unused dependencies | CLI, CI |
|
|
1142
|
+
| `npx license-checker` | License compliance auditing | CLI, CI |
|
|
1143
|
+
| `npx madge --circular` | Circular dependency detection | CLI, CI |
|
|
1144
|
+
| `socket.dev` | Supply chain attack detection | GitHub App |
|
|
1145
|
+
| Snyk | Vulnerability and license scanning | CLI, CI, GitHub |
|
|
1146
|
+
| Dependabot | Automated dependency update PRs | GitHub native |
|
|
1147
|
+
| Renovate | Configurable automated updates | GitHub App, self-hosted |
|
|
1148
|
+
| pnpm | Strict dependency isolation (prevents phantoms) | Package manager |
|
|
1149
|
+
| `import-cost` (VS Code) | Inline dependency size display | IDE |
|
|
1150
|
+
| `webpack-bundle-analyzer` | Visual bundle composition analysis | Build tool |
|
|
1151
|
+
| FOSSA | Enterprise license compliance | CI, SaaS |
|
|
1152
|
+
| `npm-merge-driver` | Automatic lock file conflict resolution | Git driver |
|
|
1153
|
+
|
|
1154
|
+
---
|
|
1155
|
+
|
|
1156
|
+
## Key Takeaways
|
|
1157
|
+
|
|
1158
|
+
1. **Every dependency is a liability.** It is code you did not write, do not control, and are
|
|
1159
|
+
responsible for. Treat `npm install` with the same scrutiny as a `git merge` from an
|
|
1160
|
+
unknown contributor.
|
|
1161
|
+
|
|
1162
|
+
2. **Supply chain attacks are escalating.** From event-stream (2018) to ua-parser-js (2021)
|
|
1163
|
+
to SANDWORM_MODE (2026), the frequency and sophistication of attacks through package
|
|
1164
|
+
registries is increasing. Defense requires active auditing, not passive trust.
|
|
1165
|
+
|
|
1166
|
+
3. **The ecosystem's strengths are its weaknesses.** Easy publishing enables innovation but
|
|
1167
|
+
also enables typosquatting, dependency confusion, and protestware. Flat `node_modules`
|
|
1168
|
+
enables convenience but enables phantom dependencies. Semantic versioning enables
|
|
1169
|
+
compatibility ranges but enables untested code in production.
|
|
1170
|
+
|
|
1171
|
+
4. **Automation is necessary but insufficient.** `npm audit`, Dependabot, and Snyk catch known
|
|
1172
|
+
vulnerabilities. They do not catch social engineering, protestware, or zero-day supply chain
|
|
1173
|
+
attacks. Human review of new dependencies and major updates remains essential.
|
|
1174
|
+
|
|
1175
|
+
5. **Dependency management is a team discipline, not an individual task.** It requires policy
|
|
1176
|
+
(approved licenses, maximum dependency count), process (audit triage rotation, update
|
|
1177
|
+
cadence), and tooling (CI gates, automated scanning) working together.
|
|
1178
|
+
|
|
1179
|
+
---
|
|
1180
|
+
|
|
1181
|
+
## Sources
|
|
1182
|
+
|
|
1183
|
+
- [npm left-pad incident -- Wikipedia](https://en.wikipedia.org/wiki/Npm_left-pad_incident)
|
|
1184
|
+
- [How one developer broke Node, Babel and thousands of projects -- The Register](https://www.theregister.com/2016/03/23/npm_left_pad_chaos/)
|
|
1185
|
+
- [kik, left-pad, and npm -- npm Blog](https://blog.npmjs.org/post/141577284765/kik-left-pad-and-npm)
|
|
1186
|
+
- [Details about the event-stream incident -- npm Blog](https://blog.npmjs.org/post/180565383195/details-about-the-event-stream-incident)
|
|
1187
|
+
- [Dependency Confusion: How I Hacked Into Apple, Microsoft -- Alex Birsan](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610)
|
|
1188
|
+
- [Understanding and Preventing Dependency Confusion Attacks -- FOSSA](https://fossa.com/blog/dependency-confusion-understanding-preventing-attacks/)
|
|
1189
|
+
- [Typosquatting attacks -- Snyk Blog](https://snyk.io/blog/typosquatting-attacks/)
|
|
1190
|
+
- [SANDWORM_MODE: Typosquatted npm Packages -- Wiz](https://threats.wiz.io/all-incidents/sandwormmode-typosquatted-npm-packages-used-to-hijack-ci-workflows)
|
|
1191
|
+
- [npm Libraries colors and faker Sabotaged -- Sonatype](https://www.sonatype.com/blog/npm-libraries-colors-and-faker-sabotaged-in-protest-by-their-maintainer-what-to-do-now)
|
|
1192
|
+
- [Open source maintainer pulls the plug on colors and faker -- Snyk](https://snyk.io/blog/open-source-npm-packages-colors-faker/)
|
|
1193
|
+
- [NPM Library ua-parser-js Hijacked -- Rapid7](https://www.rapid7.com/blog/post/2021/10/25/npm-library-ua-parser-js-hijacked-what-you-need-to-know/)
|
|
1194
|
+
- [Malware Discovered in Popular NPM Package ua-parser-js -- CISA](https://www.cisa.gov/news-events/alerts/2021/10/22/malware-discovered-popular-npm-package-ua-parser-js)
|
|
1195
|
+
- [Phantom dependencies -- Rush](https://rushjs.io/pages/advanced/phantom_deps/)
|
|
1196
|
+
- [Phantom Dependencies -- Socket.dev](https://docs.socket.dev/docs/phantom-dependencies)
|
|
1197
|
+
- [A Solution to the Diamond Dependency Problem -- The Solution Space](https://solutionspace.blog/2023/02/20/a-solution-to-the-diamond-dependency-problem/)
|
|
1198
|
+
- [What is a diamond dependency conflict? -- JLBP](http://jlbp.dev/what-is-a-diamond-dependency-conflict)
|
|
1199
|
+
- [The Nine Circles of Dependency Hell -- Sourcegraph](https://sourcegraph.com/blog/nine-circles-of-dependency-hell)
|
|
1200
|
+
- [Dependency hell -- Wikipedia](https://en.wikipedia.org/wiki/Dependency_hell)
|
|
1201
|
+
- [Software Engineering at Google: Dependency Management](https://abseil.io/resources/swe-book/html/ch21.html)
|
|
1202
|
+
- [Open Source License Compliance Lessons -- FOSSID](https://fossid.com/articles/open-source-license-compliance-lessons-from-two-landmark-court-cases/)
|
|
1203
|
+
- [Open Source Licenses: Understanding the Risk Factors -- Checkmarx](https://checkmarx.com/blog/open-source-licenses-understanding-the-risk-factors/)
|
|
1204
|
+
- [Lockfiles Killed Vendoring -- Andrew Nesbitt](https://nesbitt.io/2026/02/10/lockfiles-killed-vendoring.html)
|
|
1205
|
+
- [Vulnerabilities in Vendored Dependencies -- OpenSSF](https://best.openssf.org/Vendored-Dependencies-Guide.html)
|
|
1206
|
+
- [Don't use sudo with npm install -- DEV Community](https://dev.to/brylie/don-t-use-sudo-with-npm-install-56p9)
|
|
1207
|
+
- [npm Threats and Mitigations -- npm Docs](https://docs.npmjs.com/threats-and-mitigations/)
|
|
1208
|
+
- [Solving conflicts in package-lock.json -- TkDodo](https://tkdodo.eu/blog/solving-conflicts-in-package-lock-json)
|
|
1209
|
+
- [Detect and prevent dependency confusion attacks -- Snyk](https://snyk.io/blog/detect-prevent-dependency-confusion-attacks-npm-supply-chain-security/)
|