Cyberlium

Web › Module 3 › Lesson 1

BeginnerModule 3Lesson 1/5

Dependencies as Attack Surface

A03:2025 — inventory deps YOU own.

15 min+40 XP3 quiz
Module progress1 of 5

Visual · deps_attack_surface

Software Supply Chain Failures (A03:2025): Inventory packages you own — do not hydra the LAN.

Opening

You did not write the vulnerability — you installed it. That is still your risk.

OWASP Top 10:2025 elevates Software Supply Chain Failures as A03: compromised packages, poisoned pipelines, unsigned updates, and blind trust in registries. Attackers aim at maintainers, typosquat names, or CI secrets so victims pull malicious code through normal install. Your goal as a defender: know what you depend on, pin what you trust, verify what you can. This is ORIGINAL Cyberlium teaching — attack literacy first.

1. A03 in one sentence: trust in someone else’s code or build was misplaced

Supply chain failure means the integrity or authenticity of software you consume (libraries, containers, plugins, CI actions) was broken — or never established. Attacker goals: run code in your build or runtime, steal secrets from CI, persist via updates. Victims often “just npm installed” or “just docker pulled.” Finding language: “Unpinned deps; no SBOM; CI can publish with overbroad token.” Fix language: “Inventory; pin; verify checksums/signatures when available; least privilege in CI; review diffs on upgrades.”

Command guide

A03 Supply chain — A03 in one sentence

═══ INSTALL ═══

Linux (Debian/Ubuntu):

Command — copy this

sudo apt install curl

macOS: Built-in

Windows: Built-in (PowerShell: Invoke-WebRequest)

═══ COMMANDS ═══

Command — copy this

SAFE="http://127.0.0.1:8770"

Command — copy this

curl -sS -m 3 -I "$SAFE/" | head -n 12

2. Direct vs transitive: the graph you did not read

Direct dependencies are what you declared. Transitive ones arrive because those packages depend on others. Attackers love deep graphs: one compromised leaf reaches thousands of apps. Literacy: generate a lockfile/tree for a project YOU own (pip freeze, npm ls --depth=0) and notice how wide it is. Do not “prove A03” by uploading malware to a public registry.

Command guide

A03 Supply chain — Direct vs transitive

═══ COMMANDS ═══

Command — copy this

ls -1 package-lock.json yarn.lock pnpm-lock.yaml requirements.txt poetry.lock go.sum Cargo.lock
ls -1 "$HOME/cyberlium-lab"/*lock*
find "$HOME/cyberlium-lab" . -maxdepth 3 \( -name "package-lock.json" -o -name "requirements.txt" -o -name "go.sum" -o -name "poetry.lock" \) | head -n 20

3. Typosquats and abandoned packages — named risks, not a how-to

Lookalike names and unmaintained packages are common failure stories. Defender habits: spell package names carefully; prefer maintained projects; watch sudden maintainer changes; read release notes on bumps. This course does not teach how to publish malicious lookalikes. Naming the risk is enough.

Command guide

A03 Supply chain — Typosquats and abandoned packages - named risks, not a how-to

═══ COMMANDS ═══

Command — copy this

printf "typosquat_named: lookalike names
abandoned_named: unmaintained with old CVEs
refuse: poisoning registries
" >> "$HOME/cyberlium-lab/a03-deps-mid-h3.txt"

4. What you ship before SBOM lesson

Start an inventory habit: lockfiles committed; dependency review in PRs; no blind latest tags in production. Secrets out of install scripts. CI tokens scoped. Identify DEMO first so writeups use http://192.168.0.1/ as the demo asset (or note SAFE if that IP is a router). Record the habit in notes even if your toy project is tiny.

5. What you record

Date (UTC). A03 = Software Supply Chain Failures (OWASP Top 10:2025). Identify banner of http://192.168.0.1/ or STOP if router. Direct vs transitive one line. pip freeze / npm ls snippet (redacted). Ethics: NEVER publish malware packages; NEVER hydra/nmap the LAN. Path: $HOME/cyberlium-lab/a03-deps-notes.txt, chmod 600. Legal: original Cyberlium — not official OWASP certification.

6. Wrong vs right: poisoning registries vs inventory you own

Worked failure — same word “supply chain,” opposite action. Right never needs a malicious publish.

  • Wrong

    Typosquat a popular name. Hydra 192.168.0.1. Steal CI tokens as “research.” Install random unknown packages to “see what happens.”

  • Right

    Identify DEMO with curl -I; list deps on a project you own; lock a03-deps-notes.txt chmod 600. Next: SBOM Pinning and Trust Boundaries.

If you have a local package.json/requirements.txt/pubspec.yaml you own, copy a redacted name list into notes. Otherwise create a tiny toy manifest under cyberlium-lab. Identify DEMO first.

Command guide

a03_deps_inventory.sh — DEMO curl -I + list YOUR toy deps

═══ INSTALL ═══

Linux (Debian/Ubuntu):

Command — copy this

sudo apt install curl
sudo apt install nmap
sudo apt install python3

macOS:

Command — copy this

brew install nmap
brew install python3

Windows: Built-in (PowerShell: Invoke-WebRequest)

Command — copy this

choco install nmap  # or download https://nmap.org/download.html

Download https://python.org/downloads/

═══ COMMANDS ═══

Command — copy this

cd "$HOME/cyberlium-lab/a03-toy"

Command — copy this

cat > requirements-toy.txt << 'REQ'
demo-left-pad==1.0.0
demo-http-client==2.3.1
REQ

Command — copy this

cat > list_deps.py << 'PY'
from pathlib import Path
text = Path("requirements-toy.txt").read_text(encoding="utf-8")
lines = [l.strip() for l in text.splitlines() if l.strip() and not l.startswith("#")]
print("direct_deps_count", len(lines))
for l in lines:
print("dep:", l)
print("a03: dependencies are attack surface you chose to trust")
print("ethics: NEVER publish typosquats / malware packages; NEVER hydra/nmap the LAN")
print("legal: original Cyberlium — not official OWASP certification")
PY

Command — copy this

python3 list_deps.py || python list_deps.py

Command — copy this

(pip freeze || pip3 freeze || true) | head -n 15

Command — copy this

cat > a03_optional_echo.py << 'PY'
"""Optional identify echo. Bind loopback only."""
from http.server import BaseHTTPRequestHandler, HTTPServer

HOST = "127.0.0.1"
PORT = 8770
if HOST != "127.0.0.1":
raise SystemExit("refusing non-loopback bind")

class H(BaseHTTPRequestHandler):
def do_GET(self):
    body = b"Cyberlium A03 inventory lab. DEMO writeup: http://192.168.0.1/
"
    self.send_response(200)
    self.send_header("Content-Type", "text/plain; charset=utf-8")
    self.send_header("Content-Length", str(len(body)))
    self.end_headers()
    self.wfile.write(body)

print("optional bind", HOST, PORT)
HTTPServer((HOST, PORT), H).serve_forever()
PY

Command — copy this

cat > a03_deps_practical.sh << 'SH'

SH

Command — copy this

{

Mission: a03-deps-notes.txt in cyberlium-lab (mode 600)

1) curl -sS -I http://192.168.0.1/ —2) Inventory a toy or owned project dependency list (pip freeze / npm ls / toy manifest). 3) Fill $HOME/cyberlium-lab/a03-deps-notes.txt, chmod 600. No malicious publishes.

Stuck? Ask Cyberlium AI Mentor

If “supply chain only counts if I compromise a package” still feels true, ask for a hint — not a typosquat guide. Try: "Hint only: why deps are attack surface, which curl -I identifies MY lab vs a router, and where locked a03-deps-notes.txt lives?"

You now treat dependencies as A03 attack surface — identify the demo, inventory first, no malicious publishes — with locked notes. Original Cyberlium — not official OWASP certification. Next — SBOM Pinning and Trust Boundaries.

Knowledge Check

1

APPLY: Your app has 8 direct deps and 140 transitive. What A03 literacy follows?

Multiple choice

Knowledge Check

2

APPLY: True or False: “npm install latest” on every build is fine because registries are always safe.

True or False

Knowledge Check

3

APPLY: curl http://192.168.0.1/ shows a Netgear Router Admin page. What do you do?

Multiple choice

← Previous

Answer all 3 knowledge checks to continue. (0/3 answered)