# Secure Development in Practice — Supply Chain, Secrets, Logging, Error Handling and Security Careers

Source: https://skills101.in/learn/web-security/secure-development-security-careers — Skills101 free tutorial (Web Security (OWASP Top 10)). Updated 2026-11-09.

Fixing individual bugs is half the job. The other half is a **process** that stops them reaching production. This lesson covers the OWASP Top 10:2025 risks that live in your **pipeline and operations**, and how to build a career from these skills.

## 1. Software supply chain (A03:2025)

A typical Node.js project pulls in **hundreds** of packages, most of them dependencies of dependencies. Each is code that runs with your app's permissions.

![Supply chain: your app depends on direct packages, which pull in many indirect packages, plus build tools and CI; an attacker who compromises any one of them reaches your users](https://skills101.in/learn-img/web-security/supply-chain.svg)

| Threat | Real-world pattern | Defence |
|---|---|---|
| Known-vulnerable package | an old library with a published CVE | `npm audit`, `pip-audit`, Dependabot/Renovate alerts; update regularly |
| Typosquatting | `reqeusts` instead of `requests` | check names carefully; prefer well-known packages |
| Compromised maintainer | a popular package publishes a malicious version | **lockfiles**, pinned versions, review diffs of updates |
| Malicious install scripts | `postinstall` runs code on your machine | `npm ci --ignore-scripts` where possible; CI isolation |
| Compromised build/CI | secrets stolen from the pipeline | least-privilege CI tokens, pin CI actions to versions, protect main branch |

**Habits:** commit your lockfile (`package-lock.json`, `poetry.lock`); install with `npm ci` in CI; remove unused packages; keep an inventory (an **SBOM**, software bill of materials) for production apps.

## 2. Software and data integrity (A08:2025)

Don't trust code or data whose origin you haven't verified:

- auto-updates and plugins should be **signed** and checked;
- **don't deserialize** untrusted data with formats that can execute code — Python `pickle`, Java native serialization. Use JSON plus validation instead;
- webhooks: verify the provider's **signature** (e.g. Razorpay and Stripe sign every webhook with HMAC — exactly the technique from the CSRF and JWT lessons).

## 3. Secrets management

```python
import os

# BAD: secret in code -> it ends up in Git history, screenshots and every copy of the repo
# RAZORPAY_SECRET = "rzp_live_4fG..."

# GOOD: read from the environment (set on the server, never committed)
secret = os.environ.get("RAZORPAY_SECRET")
print("configured" if secret else "missing RAZORPAY_SECRET - refusing to start payments")
```

```text
missing RAZORPAY_SECRET - refusing to start payments
```

- `.env` files go in `.gitignore`; commit a `.env.example` with empty values.
- If a secret is ever committed: **rotate it immediately** (deleting the commit isn't enough — it's in clones and forks), then clean history.
- Use a secret scanner (`gitleaks`, GitHub secret scanning) in CI.
- Different keys for test and production; least-privilege API keys.

## 4. Logging and alerting (A09:2025)

Breaches often go unnoticed for months. Log **security events** and alert on unusual patterns:

| Log this | Never log this |
|---|---|
| logins (success/failure), password and email changes | passwords, OTPs, full card numbers |
| permission denials (403s), admin actions | session tokens, API keys |
| payment events, data exports | full personal data unless required |
| rate-limit hits, validation failures spikes | |

```python
import json
from datetime import datetime, timezone

def security_log(event, user, ip, **details):
    entry = {"ts": datetime(2026, 11, 10, 9, 30, tzinfo=timezone.utc).isoformat(),
             "event": event, "user": user, "ip": ip, **details}
    return json.dumps(entry)

print(security_log("login_failed", "asha@example.com", "203.0.113.7", reason="bad_password", attempt=4))
print(security_log("admin_action", "meera", "198.51.100.2", action="publish_project", target="p_91"))
```

```text
{"ts": "2026-11-10T09:30:00+00:00", "event": "login_failed", "user": "asha@example.com", "ip": "203.0.113.7", "reason": "bad_password", "attempt": 4}
{"ts": "2026-11-10T09:30:00+00:00", "event": "admin_action", "user": "meera", "ip": "198.51.100.2", "action": "publish_project", "target": "p_91"}
```

Structured (JSON) logs are easy to search and alert on: *"more than 50 failed logins from one IP in 5 minutes"*, *"admin login from a new country"*. An **activity log of admin actions** (like Skills101's) also answers "who changed this?" — the **R** (repudiation) in STRIDE.

## 5. Mishandling exceptional conditions (A10:2025)

New in 2025: what your app does **when things go wrong**.

```python
def is_allowed_unsafe(user, permissions_service):
    try:
        return permissions_service(user)
    except Exception:
        return True                      # "fail open": an outage gives everyone access

def is_allowed_safe(user, permissions_service):
    try:
        return permissions_service(user)
    except Exception:
        return False                     # "fail closed": deny when unsure, log the error

def broken_service(user):
    raise TimeoutError("permissions DB down")

print("unsafe:", is_allowed_unsafe("asha", broken_service))
print("safe:  ", is_allowed_safe("asha", broken_service))
```

```text
unsafe: True
safe:   False
```

Rules: **fail closed** for security decisions; show users a generic error with a reference ID; send details to logs; don't leave half-finished transactions (use database transactions); handle timeouts and unexpected input sizes explicitly.

## 6. Security testing in your workflow

| Technique | What it does | Free tools |
|---|---|---|
| **SAST** (static analysis) | scans source code for risky patterns | Semgrep, CodeQL (GitHub), SonarQube Community |
| **SCA** (dependency scanning) | finds vulnerable packages | `npm audit`, `pip-audit`, OWASP Dependency-Check, Dependabot |
| **Secret scanning** | finds committed keys | gitleaks, GitHub secret scanning |
| **DAST** (dynamic) | attacks a running test copy of the app | OWASP ZAP |
| **Manual testing** | logic flaws tools miss (IDOR, business logic) | Burp Suite Community, browser DevTools |
| **Code review** | a second pair of eyes with a checklist | — |

Run SAST, SCA and secret scanning automatically on every pull request; run DAST against staging.

## 7. Pre-deploy security checklist

1. HTTPS + HSTS; secure cookie flags; security headers incl. CSP.
2. Debug off; default accounts removed; generic error pages.
3. All SQL parameterised; templates auto-escaping; no unsafe `innerHTML`.
4. Every endpoint checks auth **and** ownership; admin actions logged.
5. Passwords hashed with Argon2id/bcrypt; login rate-limited; MFA for staff.
6. CSRF protection on; CORS allow-list only.
7. Dependencies audited; lockfile committed; no secrets in the repo.
8. Backups tested; alerts on suspicious activity.

## 8. Careers in application security

India has strong demand for security skills across IT services, product companies, banks and fintech, and the government sector.

| Role | What you do | Start with |
|---|---|---|
| **Secure software developer** | build features safely (every developer!) | this track + your main stack |
| **Application security (AppSec) engineer** | reviews, threat models, security tooling for dev teams | development experience + OWASP + tools above |
| **Penetration tester** | authorised testing of apps and networks | web fundamentals, Burp, practice labs |
| **SOC analyst** | monitoring alerts, investigating incidents | logs, networking, SIEM basics |
| **Bug bounty hunter** | finding bugs in programmes that invite testing | strong web skills + patience |

**How to practise legally:** deliberately vulnerable apps you run yourself (OWASP Juice Shop, DVWA), PortSwigger Web Security Academy's free labs, CTF competitions, and bug bounty platforms (HackerOne, Bugcrowd, Intigriti) — **only within each programme's published scope**. Certifications such as CompTIA Security+, CEH, eJPT or OSCP can help with HR filters; projects and write-ups show real skill.

**Portfolio idea:** take one of your own projects, threat-model it, run Semgrep + ZAP, fix what you find, and write a short "security review" README. That single document stands out in interviews.

## Quick recap

- Supply chain: lockfiles, audits, few and well-known dependencies, protected CI.
- Integrity: verify signatures; never deserialize untrusted data with pickle/Java serialization.
- Secrets in environment/secret managers; rotate if leaked.
- Log security events (not secrets) and alert; **fail closed** on errors.
- Automate SAST, SCA, secret scanning; DAST on staging; use a pre-deploy checklist.


Practice quiz and free certificate: https://skills101.in/learn/web-security/secure-development-security-careers