Dev.to Security 🔐 Cybersecurity 👁 0 📖 10 min read

Software Supply Chain Security for Web Apps: A Developer's Threat-to-Control Guide

A web application is rarely built from source code written entirely by one team. It also depends on packages, container images, development tools, CI/CD workflows, cloud services, build systems, and credentials. That ex

A web application is rarely built from source code written entirely by one team. It also depends on packages, container images, development tools, CI/CD workflows, cloud services, build systems, and credentials.

That extended chain makes development faster, but it also creates more places where an attacker, unsafe change, or configuration mistake can affect the final application.

Software supply chain security is the practice of protecting that entire path. It covers what enters the codebase, who can change it, how it is built, what gets deployed, and how the team verifies the result.

The goal is not to make every component perfectly safe. The goal is to know what you trust, reduce unnecessary access, detect meaningful changes, and retain enough evidence to investigate a problem.

This guide organizes the work around five questions:

  1. Can we trust our dependencies?
  2. Can we trust changes to the repository?
  3. Can we trust the build process?
  4. Can we verify the artifact we deploy?
  5. Can we confirm that production matches our security expectations?

For each question, we will look at the threat, the useful controls, and the evidence a team should be able to produce.

1. Can you trust your dependencies?

Third-party packages save enormous amounts of development time. They also introduce code that your team did not write and may not review line by line.

The threat

Dependency risk is broader than an old package with a known vulnerability. A project may also be exposed through:

  • A compromised maintainer account
  • A malicious new release
  • A package name that closely resembles a legitimate dependency
  • An abandoned library that no longer receives fixes
  • A transitive dependency that developers did not select directly
  • An install script that performs unexpected actions
  • A public package replacing an internal package because of resolution order

A dependency can therefore be risky even when its direct API looks harmless.

Useful controls

Start by making dependency changes visible and repeatable.

  • Commit lockfiles and review their changes.
  • Pin versions where reproducibility matters.
  • Use an approved package registry or proxy for sensitive projects.
  • Run dependency analysis on pull requests and on a recurring schedule.
  • Review new direct dependencies before adoption.
  • Remove unused packages instead of carrying them indefinitely.
  • Restrict or inspect package lifecycle scripts.
  • Define a response time for critical vulnerabilities.

Automated update tools are helpful, but automation should not automatically mean approval. A version bump can change maintainers, scripts, transitive packages, or runtime behavior.

Evidence to retain

A team should be able to answer:

  • Which package version is in production?
  • Why was the package introduced?
  • Who approved the latest major upgrade?
  • Which transitive dependencies arrived with it?
  • When was it last checked for known vulnerabilities?
  • Is the vulnerable component actually reachable in the application?

A software bill of materials, or SBOM, can help inventory components. It does not prove that every component is safe. It provides a record that makes investigation and response faster.

2. Can you trust changes to the repository?

Strong dependency controls will not help if an attacker can modify source code or pipeline configuration through a compromised account.

The threat

Repository attacks often target identity and workflow rather than application logic. Examples include:

  • A stolen developer token
  • An overprivileged service account
  • A branch protection rule that can be bypassed
  • A malicious pull request that changes both code and security checks
  • A workflow file that exposes a secret to untrusted code
  • A former employee whose access was not removed
  • A bot credential with permission to write to the repository

The dangerous change may be small. A single modified workflow step can download a malicious script, leak a token, or publish a substituted artifact.

Useful controls

Protect the path by which code becomes trusted.

  • Require multi-factor authentication for repository access.
  • Protect production and release branches.
  • Require pull requests and independent review for sensitive changes.
  • Apply ownership rules to workflow, infrastructure, and authentication files.
  • Block direct pushes to protected branches.
  • Use short-lived credentials where the platform supports them.
  • Review user, bot, and integration permissions regularly.
  • Remove access promptly during employee offboarding.
  • Keep audit logs long enough to support an investigation.

Not every file needs the same review policy. A documentation edit does not carry the same risk as a change to a deployment workflow, access policy, or authentication module.

Evidence to retain

For a production change, you should be able to identify:

  • The commit that introduced it
  • The pull request and reviewers
  • The checks that ran
  • Any exceptions or bypasses
  • The identity that merged the change
  • The branch and tag used for release

This creates traceability. When something unexpected appears in production, the team can work backward without guessing.

3. Can you trust the build process?

CI/CD systems often have access to source code, registries, cloud environments, signing keys, and deployment targets. That makes the build pipeline part of the security boundary.

The threat

A build can be compromised without changing the application's normal source files. An attacker might:

  • Alter a workflow definition
  • Replace a referenced action or plugin
  • Inject commands through untrusted input
  • Extract secrets from logs or environment variables
  • Run a pull request with excessive permissions
  • Reuse an unprotected runner
  • publish an artifact from an unreviewed branch
  • Disable a security check while keeping the pipeline green

The result may look like a normal build even though the process that created it was not trustworthy.

Useful controls

Treat pipeline code like production code.

  • Pin third-party CI actions to trusted versions or immutable references.
  • Review workflow changes through designated code owners.
  • Give each job only the permissions it needs.
  • Separate build and deployment permissions.
  • Avoid exposing production secrets to untrusted pull requests.
  • Prefer temporary identity tokens over long-lived cloud keys.
  • Isolate runners and clean their state after jobs.
  • Prevent secrets from being printed in logs.
  • Require approval before production deployment when risk warrants it.
  • Record the exact source revision and inputs used by each build.

Security checks should fail clearly. A scanner that crashes, times out, or never receives the intended files should not be reported as a successful security result.

Evidence to retain

For each release, preserve enough information to show:

  • Which workflow version ran
  • Which source revision it used
  • Which runner or environment performed the build
  • Which checks completed successfully
  • Which dependencies and build tools were present
  • Who approved the deployment
  • Whether an exception was granted

This evidence matters during an incident, but it also helps diagnose ordinary release failures.

4. Can you verify the artifact you deploy?

Passing tests on source code does not guarantee that the resulting container, package, or static bundle is the artifact that reaches production.

The threat

Artifact risk appears when there is a gap between build and deployment. Common problems include:

  • Mutable tags such as latest
  • Images pulled from an untrusted registry
  • A package overwritten after approval
  • A release rebuilt differently in another environment
  • A manual file copied outside the normal pipeline
  • Missing provenance for the production artifact
  • Build output that contains secrets or development files

If the team cannot connect a deployed artifact to its reviewed source, it cannot confidently explain what is running.

Useful controls

Make artifacts identifiable and difficult to replace silently.

  • Use immutable artifact identifiers or digests.
  • Store artifacts in controlled registries.
  • Restrict who and what can publish releases.
  • Scan the final artifact, not only the repository.
  • Generate checksums, signatures, or attestations where appropriate.
  • Record build provenance.
  • Promote the same approved artifact between environments instead of rebuilding it.
  • Apply retention policies that support rollback and investigation.
  • Reject artifacts that do not meet the expected origin or integrity checks.

The principle is simple: build once, identify the result, verify it, and deploy that exact result.

Evidence to retain

A release record should connect:

  • Source commit
  • Build workflow
  • Dependency set
  • Test and scan results
  • Artifact digest
  • Registry location
  • Deployment event
  • Production environment

This chain of evidence turns a vague statement like "the pipeline deployed it" into a verifiable record.

5. Can you confirm production matches your expectations?

Supply chain security does not end when an artifact is deployed. Configuration, infrastructure, domains, certificates, exposed client-side code, and runtime services can change what users actually receive.

The threat

A secure build can still become an unsafe deployment. Examples include:

  • A production environment using an unexpected image
  • A debug endpoint left publicly accessible
  • A secret embedded in browser-delivered JavaScript
  • A storage bucket or administrative service exposed to the internet
  • Missing browser security headers
  • A weak TLS or DNS configuration
  • A third-party script added outside the reviewed release process
  • A stale environment that continues running an old vulnerable component

Source review alone cannot confirm all of these conditions because some risks appear only after deployment.

Useful controls

Combine internal build evidence with external verification.

  • Maintain an inventory of production applications, domains, and services.
  • Compare deployed artifact identifiers with approved release records.
  • Scan public endpoints after meaningful releases.
  • Monitor certificates, DNS records, and internet-facing services.
  • Review client-side bundles for exposed secrets and unexpected scripts.
  • Check important security headers and transport settings.
  • Remove abandoned staging systems and temporary services.
  • Recheck high-risk issues after remediation.
  • Monitor production dependencies continuously, not only at release time.

This is where application security and website security meet. Internal controls explain how the software was produced. External checks show what the deployed system exposes.

Evidence to retain

Keep records that answer:

  • What artifact is currently deployed?
  • When was the public application last checked?
  • Which findings were accepted, fixed, or deferred?
  • Who owns each unresolved issue?
  • Was the fix verified after deployment?
  • Are any temporary exceptions still active?

Turn findings into owned work

A long security report is not a remediation plan. Findings need context, ownership, and a deadline.

For each meaningful issue, record:

  • Asset: What repository, package, pipeline, artifact, or application is affected?
  • Exposure: Can an attacker reach or influence it?
  • Impact: What could happen if it were exploited?
  • Confidence: Is the finding confirmed, likely, or still under investigation?
  • Owner: Which person or team can make the change?
  • Action: What specific control or fix is required?
  • Deadline: When should the risk be reduced?
  • Verification: How will the team prove the fix worked?

Severity labels are useful, but they are not enough. A critical issue in unreachable test code may be less urgent than a lower-rated secret exposed in a live browser bundle. Prioritization should account for actual exposure and business impact.

A compact release review

Before a production release, verify the following:

Dependencies

  • New direct dependencies were reviewed.
  • Lockfiles match the approved change.
  • Known critical issues were assessed for reachability and impact.
  • An inventory or SBOM can be generated for the release.

Repository

  • The release commit came through the approved review path.
  • Sensitive files received the required reviewers.
  • No unexplained branch protection bypass occurred.
  • Human and machine access is current.

Pipeline

  • Workflow dependencies are pinned appropriately.
  • Jobs use minimum required permissions.
  • Untrusted code cannot access production secrets.
  • Required checks ran successfully and produced usable results.

Artifact

  • The deployed artifact has an immutable identifier.
  • Its source and build are traceable.
  • The final artifact was scanned.
  • Promotion does not rebuild or silently replace it.

Production

  • The deployed version matches the approved artifact.
  • Public endpoints were checked after deployment.
  • No secret or administrative interface is unintentionally exposed.
  • Important findings have owners and verification steps.

This review does not need to become a large meeting. Mature teams automate the evidence collection and reserve human attention for exceptions, high-impact changes, and risk decisions.

If a supply chain incident occurs

Preparation determines how quickly a team can respond. During an incident, start with containment and traceability.

Ask:

  1. Which component, account, workflow, or artifact is affected?
  2. Which releases include the affected component?
  3. Can publishing or deployment access be revoked immediately?
  4. Are credentials exposed or potentially compromised?
  5. Can the team identify every environment running the artifact?
  6. Is a known-good version available for rollback?
  7. What evidence must be preserved before systems are changed?
  8. How will the repaired release be verified internally and externally?

Do not assume that upgrading a package closes the incident. A compromise may also require credential rotation, artifact replacement, log review, environment cleanup, and confirmation that unauthorized persistence was not added.

Start with five proofs

If a complete program feels too large, begin by requiring five pieces of evidence for every important production release:

  1. The reviewed source commit
  2. The dependency inventory
  3. The completed pipeline checks
  4. The immutable artifact identifier
  5. The verified production deployment

These proofs create a foundation for stronger controls. They also expose weak points quickly. If the team cannot produce one of them, that missing link becomes a practical improvement target.

Software supply chain security is not a single scanner, checklist, or compliance document. It is the ability to explain and verify how software moved from an idea to a live system.

Know what entered the build. Protect who can change it. Record how it was produced. Verify what was deployed. Then keep checking the system that users can actually reach.

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.