Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

Dependency Scanning (Software Composition Analysis)

By Kokil Thapa | Last reviewed: September 2026

Your application code may be clean, yet a single outdated package can still expose customer data. Dependency Scanning (Software Composition Analysis) maps every third-party library in your stack to published CVE records before deploy. On production Laravel and PHP projects I maintain, SCA catches issues that code review and unit tests never touch. This guide covers lockfile scanning, CI wiring, triage, and fixes you can run today.

What is Dependency Scanning (Software Composition Analysis)?

SCA answers one question: do the libraries you import contain known security flaws? Modern apps rarely ship without dependencies. A typical custom Laravel application pulls in hundreds of transitive packages through Composer alone. You did not write that code, but you own the risk when it lands in production.

Software Composition Analysis tools read your dependency manifests and lockfiles. They match package names and exact versions against advisory feeds such as the GitHub Advisory Database and the National Vulnerability Database (NVD). The output is a report ranked by severity—critical, high, medium, low—with CVE identifiers and recommended fixed versions.

This is not the same as scanning your own source for bugs. SCA looks outward at supply-chain risk. On a legal-tech portal or eCommerce site, one vulnerable JWT library or file-upload helper can compromise the entire platform. I treat SCA as non-negotiable for any client project that handles payments, documents, or personal data.

SCA Scan PipelineApp RepolockfilesSCA Scanneraudit CLICVE FeedsNVD + GHSASeverity ReportCVE ID, fix version, reachabilityCI Gate or Ticketblock, warn, or waiveSBOM ExportCycloneDX or SPDX JSON
Dependency Scanning (Software Composition Analysis) matches lockfile versions to CVE databases and produces actionable severity reports for CI gates.

Core inputs SCA tools require

Every scanner needs deterministic version pins. Without a lockfile, two developers can install different patch levels and get different scan results. For PHP projects, commit composer.lock. For front-end assets built with Vite 8.x and npm 12, commit package-lock.json or pnpm-lock.yaml.

  • composer.lock — PHP and Laravel 12/13 dependencies installed via Composer 2.10
  • package-lock.json — Node.js build tooling and JavaScript libraries
  • Container images — OS packages layered on top of application deps; pair with container image scanning
  • SBOM files — machine-readable inventories from tools covered in our SBOM generation guide

How do you set up dependency scanning in a Laravel or PHP project?

Start with the native tools before adding SaaS platforms. Composer ships composer audit since Composer 2.4. On PHP 8.3+ Laravel 13 projects, this is the fastest baseline. Run it locally, then enforce it in CI.

Composer audit for PHP dependencies

# Install deps exactly as production will
composer install --no-dev --prefer-dist --no-interaction

# Fail the command when advisories exist
composer audit --format=json

# Human-readable summary
composer audit

The JSON output integrates cleanly with GitLab CI artifacts or custom parsers. Store it beside your JSON formatter output during local debugging so you can read CVE blocks without squinting at terminal walls.

For development dependencies, run a separate audit pass with dev packages included. A vulnerable PHPUnit or Debugbar version rarely affects production, but it can compromise developer machines and CI runners.

npm audit for Vite and front-end packages

Laravel apps using Vite 8.x typically maintain a package.json at the project root. After npm ci, run:

npm ci
npm audit --audit-level=high
npm audit fix --dry-run

Never blindly run npm audit fix --force on a production branch. Major semver jumps break builds. Review each advisory, check whether the vulnerable code path is reachable, then bump intentionally.

OWASP Dependency-Check for polyglot repos

When a project mixes PHP, JavaScript, and WordPress 7.1 plugins, a unified scanner helps. OWASP Dependency-Check supports Composer, npm, and several other ecosystems in one CLI pass. It is heavier than native audits but produces HTML and JSON reports suitable for compliance folders.

  1. Install the CLI or use the official Docker image in CI.
  2. Point it at the project root with --scan.
  3. Configure suppression XML for false positives you have verified.
  4. Archive reports per release tag for audit trails.

On sister sites I deploy with Deployer 7 and GitLab CI, I run Composer audit on every pipeline. OWASP Dependency-Check runs nightly because it takes longer. That split keeps pull request feedback fast without losing depth.

How does dependency scanning differ from static code analysis and secrets scanning?

Teams often conflate three security layers. Each covers a different attack surface. Running only one leaves obvious gaps.

Scan typeWhat it inspectsTypical toolsFinds
Dependency Scanning (SCA)Third-party packages via lockfilescomposer audit, npm audit, Snyk, DependabotKnown CVEs in libraries you did not write
Static code analysis (SAST)Your source code patternsPHPStan, SonarQube, PsalmSQL injection risk, type errors, dead paths
Secrets scanningGit history and working treegitleaks, GitHub secret scanningCommitted API keys, tokens, passwords

Pair SCA with PHPStan static analysis and secrets scanning in Git. On a client portal like Mijar Law Associates, document uploads and payment callbacks need clean application code and clean dependencies. One layer alone is not enough.

SonarQube in CI excels at code smells and coverage. It does not replace checking whether symfony/http-kernel at a pinned version has an open advisory. Keep both jobs in the pipeline with separate failure thresholds.

Three Security Scan LayersSCAcomposer.lockpackage-lock.jsonCVE databasesSASTapp/ and routes/PHPStan rulescode patternsSecretsgit log.env leaksAPI keysCI Pipeline runs all three before deployProduction deploy blocked on critical findingsunless documented waiver approved
Software Composition Analysis complements static analysis and secrets scanning—each layer covers a different part of the attack surface.

How do you integrate SCA into GitLab CI or GitHub Actions?

Scanning locally is useful. Blocking vulnerable merges is what changes behaviour. Wire dependency scans into the same pipeline that runs tests and linting. Fail fast on critical CVEs; warn on medium findings until the backlog clears.

GitLab CI example for Laravel

stages:
  - test
  - security

composer_audit:
  stage: security
  image: php:8.3-cli
  script:
    - curl -sS https://getcomposer.org/installer | php -- --2
    - php composer.phar install --no-dev --prefer-dist --no-interaction
    - php composer.phar audit --format=plain
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

npm_audit:
  stage: security
  image: node:26-bookworm
  script:
    - npm ci
    - npm audit --audit-level=high
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

Cache vendor/ and node_modules/ between jobs to keep pipeline times sane. On shared EC2 runners I manage, a cold Composer install adds two to four minutes. Caching cuts that sharply.

For deeper coverage, add a scheduled job using Snyk developer-first scanning or OWASP Dependency-Check. Scheduled scans catch new CVEs published after your last merge.

GitHub Dependabot and advisory alerts

GitHub repositories can enable Dependabot security updates and version bumps via .github/dependabot.yml. Dependabot opens pull requests when advisories affect your lockfiles. Review each PR like any other dependency upgrade—run tests, check changelogs, confirm Laravel compatibility.

version: 2
updates:
  - package-ecosystem: "composer"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 5

  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"

Dependabot is not a substitute for CI gates. It proposes fixes. Your pipeline still must prove the upgrade passes. See our dependency vulnerability scanning setup article for a full baseline configuration.

CI Security PipelinePull RequestUnit TestsSCA Scanaudit jobsMerge OKFail: open CVE ticketDeployer 7 releasePHP-FPM reload on UbuntuNightly rescannew CVEs since merge
Run Dependency Scanning (Software Composition Analysis) on every pull request and schedule nightly rescans to catch newly published CVEs.

What should you do when a scan finds a critical CVE?

A red pipeline is only useful if the team has a triage playbook. Panic-merging a major version bump breaks more than it fixes. Work through severity, reachability, and available patches in that order.

Triage steps that work in production

  1. Confirm reachability. Does your app call the vulnerable function or code path? A flaw in an unused CLI subcommand may not affect your web routes.
  2. Check upstream fixes. Run composer update vendor/package --with-dependencies on a branch. Read the changelog for breaking changes.
  3. Run your test suite. Include integration tests for affected modules—auth, file upload, payment callbacks.
  4. Document waivers. If no fix exists yet, record the CVE, business risk, compensating controls, and review date in a security/exceptions.md file.
  5. Deploy and verify. After merge, confirm production lockfiles match CI. Stale vendor/ on a server is a classic post-deploy gap.

For WooCommerce 11.1 or WordPress plugin stacks, vendor updates sometimes lag weeks behind core advisories. In those cases, disable affected features temporarily, add WAF rules, or restrict admin access until the plugin author ships a patch.

On a Laravel eCommerce project like Quick And Easy Nepalese Grocery, payment gateway packages and cart libraries sit on the critical path. I bump those first and run checkout smoke tests before anything else merges.

Common mistakes I see on client codebases

  • Scanning composer.json ranges instead of the committed lockfile—results drift between machines.
  • Ignoring devDependency CVEs on CI runners that execute untrusted test code.
  • Treating npm audit fix output as gospel without reading semver impact.
  • Skipping scans on long-lived maintenance branches that still receive hotfixes.
  • Deploying built assets without re-scanning after npm ci on the release runner.

Pair dependency work with broader hardening. Rate limiting and abuse prevention reduce exploit impact even when a patch is pending. Our guide on API rate limiting and abuse prevention covers practical middleware patterns for Laravel.

CVE Triage Decision TreeCritical CVE foundIs code path reachable?NoDocument waiverreview in 30 daysYesPatch available?Upgrade and testmerge when greenMitigate nowWAF, disable feature
Critical CVE triage for Dependency Scanning (Software Composition Analysis): confirm reachability, patch when possible, or mitigate and document until a fix ships.

How do you choose between SCA tools for a small team?

Budget and workflow matter as much as feature lists. A five-person agency in Kathmandu does not need the same stack as a regulated fintech. Start free, enforce in CI, then add paid reachability analysis if noise becomes unbearable.

ToolBest forCost profileTrade-off
composer audit + npm auditLaravel/PHP shops, fast CIFree, built-inNo reachability analysis; you triage manually
GitHub DependabotGitHub-hosted reposFree tier availablePR volume can overwhelm small teams
OWASP Dependency-CheckPolyglot, compliance reportsFree, self-hostedSlower scans; false positives need tuning
Snyk / similar SaaSReachability, dashboards, policiesPaid per developerCost scales with headcount (~USD 25–50/dev/month)

For ongoing maintenance contracts, bundle SCA into your release checklist. Clients on support and maintenance plans expect you to catch CVEs before attackers do. Monthly scan reports take thirty minutes and prevent expensive emergency patches.

Server hardening complements dependency hygiene. An unpatched libssl on Ubuntu undermines even a clean Composer lockfile. Include OS-level updates in your Linux system administration routine and scan container images separately.

AI-assisted review tools can summarise long advisory threads, but they do not replace lockfile scans. Treat AI code review in CI as a helper for human triage, not a substitute for testing and optimization gates you already trust.

Key Takeaways

  • Commit lockfiles and run composer audit plus npm audit on every pull request—SCA without deterministic pins is unreliable.
  • Treat Dependency Scanning (Software Composition Analysis) as a separate layer from SAST and secrets scanning; you need all three.
  • Block merges on critical CVEs with a written triage path: patch, mitigate, or time-boxed waiver.
  • Schedule nightly or weekly rescans because new advisories appear after your last green build.
  • Export SBOMs per release so compliance and incident response teams know exactly what shipped.
  • Pair dependency updates with integration tests on payment, auth, and upload flows before deploy.

People Also Ask

Is Software Composition Analysis the same as dependency scanning?

Yes. SCA and dependency scanning refer to the same practice: identifying known vulnerabilities in third-party libraries by comparing locked versions against CVE databases. "Composition" emphasises that modern apps are assembled from many external parts, not written entirely in-house.

Does Laravel include built-in dependency scanning?

Laravel itself does not ship an SCA engine. You rely on Composer 2.10's composer audit, CI integrations, GitHub Dependabot, or third-party scanners. Laravel 12 and 13 projects benefit from the same workflow—what changes is PHP version requirements and package compatibility during upgrades.

How often should you run dependency scans?

Run scans on every pull request and on the default branch after merge. Add a nightly scheduled job to catch CVEs published overnight. Before major releases—Dashain-season eCommerce peaks in Nepal, for example—run a manual audit and archive the report.

Can dependency scanning slow down CI pipelines?

Native composer audit and npm audit calls usually add under sixty seconds with cached dependencies. Heavier tools like OWASP Dependency-Check belong in nightly jobs. Split fast gates from deep scans so developers get feedback within minutes, not half an hour.

Ship safer releases with dependency scanning in your pipeline

Dependency Scanning (Software Composition Analysis) turns supply-chain risk into a checklist item you can enforce before deploy. Lock your manifests, wire audits into CI, triage findings with reachability in mind, and keep SBOMs for every release. That workflow has saved me from shipping known CVEs on production Laravel apps more than once.

If you want SCA wired into an existing pipeline—or a full security review of a legacy PHP codebase—contact us for a practical plan. You can also read more on the blog or learn about my background on about me.

Frequently Asked Questions

Dependency Scanning, also called Software Composition Analysis, answers one question: do the third-party libraries your application imports contain known security flaws? SCA tools read dependency manifests and lockfiles, then match exact package names and versions against advisory feeds such as the GitHub Advisory Database and the National Vulnerability Database. Output is a severity-ranked report with CVE identifiers and recommended fixed versions. This inspects supply-chain risk in code you did not write, not bugs in your own source.

Yes. SCA and dependency scanning mean the same thing: comparing locked dependency versions against CVE databases to find known library vulnerabilities.

No. Laravel does not ship an SCA engine. Use Composer 2.10 composer audit, CI integration, Dependabot, or third-party scanners on Laravel 12 and 13 projects.

Every pull request, after merges to the default branch, and on a nightly schedule for newly published CVEs. Run a manual audit before major releases.

Start with native tools before adding SaaS platforms. On PHP 8.3+ Laravel 13 projects, run composer install --no-dev --prefer-dist --no-interaction followed by composer audit. Use --format=json for CI artifacts or plain text locally. Run a separate audit pass including dev dependencies because vulnerable PHPUnit or Debugbar versions can compromise developer machines and CI runners. For Vite 8.x front-end assets, run npm ci then npm audit --audit-level=high. Commit composer.lock and package-lock.json so every environment scans the same versions.

SCA needs deterministic version pins. Without a committed lockfile, two developers can install different patch levels and produce different scan results. For PHP and Laravel projects, commit composer.lock from Composer 2.10 installs. For Node.js build tooling with npm 12 and Vite 8.x, commit package-lock.json or pnpm-lock.yaml. Container images add OS-layer packages that application scans miss, so pair lockfile scanning with container image scanning. SBOM files from machine-readable inventories help compliance teams and incident response know exactly what shipped per release.

Each layer covers a different attack surface and none replaces the others. Dependency Scanning matches third-party packages in lockfiles to known CVEs using tools like composer audit, npm audit, Snyk, or Dependabot. Static analysis inspects your source for patterns such as SQL injection risks using PHPStan, SonarQube, or Psalm. Secrets scanning searches git history and the working tree for committed API keys and tokens with gitleaks or GitHub secret scanning. SonarQube excels at code smells but will not flag an open advisory on symfony/http-kernel at a pinned version. Keep separate pipeline jobs with separate failure thresholds.

Add a security stage beside test and lint jobs. In GitLab CI, run composer install --no-dev on a php:8.3-cli image, then composer audit --format=plain on merge requests and the default branch. Add a parallel npm_audit job on node:26-bookworm with npm ci and npm audit --audit-level=high. Cache vendor and node_modules between jobs to avoid two-to-four-minute cold installs. Fail fast on critical CVEs and warn on medium findings until the backlog clears. On GitHub, enable Dependabot via dependabot.yml for weekly composer and npm updates, but still enforce passing audits in CI before merge.

Work through severity, reachability, and available patches in that order rather than panic-merging a major bump. Confirm whether your app calls the vulnerable code path. On a branch, run composer update vendor/package --with-dependencies, read the changelog for breaking changes, and run your full test suite including auth, file upload, and payment callback flows. If no fix exists, record the CVE, business risk, compensating controls, and review date in security/exceptions.md. After deploy, verify production lockfiles match CI because stale vendor directories on the server are a common post-deploy gap.

Native composer audit and npm audit usually add under sixty seconds when vendor and node_modules are cached. Heavier tools like OWASP Dependency-Check belong in nightly scheduled jobs, not pull-request gates.

Start free, enforce in CI, then add paid reachability analysis only if noise becomes unbearable. composer audit plus npm audit suits Laravel and PHP shops needing fast, free CI gates but requires manual triage. GitHub Dependabot works well for GitHub-hosted repos but PR volume can overwhelm small teams. OWASP Dependency-Check helps polyglot or compliance-heavy repos mixing PHP, JavaScript, and WordPress 7.1 plugins, though scans are slower and need suppression tuning. Snyk and similar SaaS add reachability and policy dashboards at roughly USD 25-50 per developer per month (Rs 3,500-7,000), which scales with headcount.

No. Never blindly run npm audit fix --force on a production branch because major semver jumps break builds. Review each advisory first. Check whether the vulnerable code path is reachable in your application. Use npm audit fix --dry-run to preview changes, then bump versions intentionally after reading changelogs and confirming Laravel and Vite 8.x compatibility. Treat npm audit output as guidance, not a command to auto-merge. The same discipline applies when reviewing Dependabot pull requests: run tests and confirm semver impact before merge.

Scanning composer.json version ranges instead of the committed lockfile causes results to drift between machines. Ignoring devDependency CVEs overlooks risks on CI runners that execute untrusted test code. Treating npm audit fix output as gospel without reading semver impact breaks builds. Skipping scans on long-lived maintenance branches that still receive hotfixes leaves hotfix releases exposed. Deploying built assets without re-scanning after npm ci on the release runner misses vulnerabilities introduced during the build step. Pair dependency work with server hardening because an unpatched libssl on Ubuntu undermines even a clean Composer lockfile.

No. Dependabot proposes fixes by opening pull requests when advisories affect your lockfiles, but your pipeline must still prove each upgrade passes tests and linting. Configure weekly composer and npm updates in dependabot.yml with a sensible open-pull-requests-limit such as five. Review each Dependabot PR like any other dependency upgrade: check changelogs, confirm Laravel 12 or 13 compatibility, and run the full test suite. Dependabot catches new advisories and suggests bumps. CI gates with composer audit and npm audit block merges until critical findings are patched, mitigated, or documented.

Reach for OWASP Dependency-Check when a project mixes PHP, JavaScript, and WordPress 7.1 plugins and you want one unified CLI pass instead of separate ecosystem audits. Install the CLI or use the official Docker image in CI, point it at the project root with --scan, and configure suppression XML for verified false positives. It is heavier than native composer audit and npm audit but produces HTML and JSON reports suitable for compliance folders. On Deployer 7 and GitLab CI pipelines I maintain, composer audit runs every pull request while Dependency-Check runs nightly because deeper scans take longer.

Share this article

0 Comments

Leave a comment

Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

Quick Contact Options
Choose how you want to connect me: