> ## Documentation Index
> Fetch the complete documentation index at: https://roadtocybersec.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Secure Coding Practices

> Build secure software with input validation, output encoding, authorization, secrets management, dependency security, CI/CD hardening, provenance, and threat modeling.

# Secure Coding Practices

Secure coding is the discipline of building software so that common attacks fail by design. It covers input handling, authorization, secrets, dependencies, CI/CD, logging, and the release process.

Recent supply chain incidents show that secure coding no longer stops at application code. Your packages, editor extensions, build scripts, tokens, and deployment pipeline are also part of the product's security boundary.

## 1. Input Validation

**Never trust data from users, clients, webhooks, files, APIs, queues, or third-party systems.**

Every input can be an attack path:

* Form fields
* URL parameters
* HTTP headers
* Cookies
* File uploads
* API payloads
* Webhook events
* CSV imports
* AI tool outputs
* Messages from queues or workers

### Validation Strategies

| Strategy              | Description                        | Example                                 |
| --------------------- | ---------------------------------- | --------------------------------------- |
| **Allowlisting**      | Define exactly what is allowed     | Username matches `^[a-zA-Z0-9_]{3,20}$` |
| **Type checking**     | Confirm expected type              | `age` must be an integer                |
| **Length limits**     | Restrict size                      | Comment maximum 5000 characters         |
| **Range checks**      | Verify numerical boundaries        | Quantity must be 1 to 100               |
| **Schema validation** | Validate complete object structure | API payload must match a JSON schema    |

<Warning>
  Prefer allowlists over blocklists. Attackers can bypass blocklists with encoding tricks, Unicode confusables, alternate syntax, and unexpected parser behavior.
</Warning>

## 2. Output Encoding

Output encoding prevents untrusted data from becoming executable content in a browser.

| Output context    | Defense                                |
| ----------------- | -------------------------------------- |
| HTML body         | HTML entity encoding                   |
| HTML attribute    | Attribute encoding                     |
| JavaScript string | JavaScript encoding or avoid inline JS |
| URL parameter     | Percent encoding                       |
| CSS               | CSS escaping or avoid untrusted CSS    |

Modern frameworks such as React, Angular, Vue, and Svelte escape output by default in normal templates. The risk returns when developers bypass those protections.

<Tip>
  If you use APIs such as `dangerouslySetInnerHTML`, `innerHTML`, or `v-html`, sanitize first with a trusted HTML sanitizer such as DOMPurify.
</Tip>

## 3. Parameterized Queries

Parameterized queries separate SQL code from user data.

```python theme={null}
# Vulnerable: user input changes query syntax
query = f"SELECT * FROM users WHERE email = '{email}'"

# Safer: user input is passed as data
cursor.execute("SELECT * FROM users WHERE email = %s", (email,))
```

```javascript theme={null}
// Vulnerable
const query = `SELECT * FROM users WHERE id = ${userId}`;

// Safer with node-postgres
const result = await pool.query(
  "SELECT * FROM users WHERE id = $1",
  [userId]
);
```

ORMs help, but raw query APIs can still be dangerous. Treat raw SQL as a sharp tool.

## 4. Authorization by Default

Authentication asks "who are you?" Authorization asks "what are you allowed to do?"

Secure systems enforce authorization on the server for every sensitive object and action.

### Patterns

* Deny by default.
* Centralize authorization checks where practical.
* Check object ownership, not just route access.
* Use least privilege roles.
* Re-check authorization after state changes.
* Log authorization failures.

### Anti-Pattern

Hiding an admin button in the UI but leaving the API endpoint unprotected is not authorization. Attackers can call the API directly.

## 5. Secrets Management

Secrets include passwords, tokens, API keys, SSH private keys, signing keys, database URLs, webhooks secrets, and cloud credentials.

### Where Secrets Belong

| Environment        | Better storage                                                        |
| ------------------ | --------------------------------------------------------------------- |
| Local development  | `.env` files excluded from Git, or local secret stores                |
| CI/CD              | Platform secret storage with least privilege                          |
| Production         | Cloud KMS, managed secret manager, Vault, or platform equivalent      |
| Kubernetes         | External secrets operators or encrypted secret storage                |
| Developer machines | Password manager, SSH agent, hardware key, or short-lived credentials |

### Secret Hygiene

* Never hardcode secrets.
* Never commit `.env` files.
* Scan commits with tools such as gitleaks, trufflehog, or detect-secrets.
* Use short-lived credentials where possible.
* Scope tokens narrowly.
* Rotate secrets after exposure.
* Separate development, staging, and production secrets.

<Warning>
  In a developer tool compromise, assume secrets available to that tool may be exposed. Rotate GitHub, package registry, cloud, SSH, CI/CD, and Vault tokens as needed.
</Warning>

## 6. Dependency Security

Modern applications depend on open-source packages, containers, build plugins, editor extensions, and SaaS SDKs. Each one can introduce vulnerabilities or malicious behavior.

### Supply Chain Risks

* Known vulnerable dependency versions.
* Typosquatted packages.
* Compromised maintainer accounts.
* Malicious install scripts.
* Dependency confusion between public and private package names.
* Auto-updates that pull unreviewed code.
* Abandoned packages with no security fixes.

### Controls

* Use lockfiles for reproducible installs.
* Review dependency diffs in pull requests.
* Run dependency scanning in CI.
* Remove unused packages.
* Prefer packages with active maintainers and clear ownership.
* Use private package namespaces to reduce dependency confusion.
* Restrict install scripts where possible.
* Monitor package publishes for unexpected releases.

## 7. Software Provenance and Build Integrity

Software provenance answers: where did this artifact come from, what source produced it, and what workflow built it?

### Practices

* Use protected branches.
* Require code review for critical paths.
* Require signed commits or signed releases where appropriate.
* Generate SBOMs for releases.
* Produce build attestations for important artifacts.
* Keep build logs.
* Isolate CI runners.
* Do not expose production secrets to untrusted pull request workflows.
* Pin third-party CI actions to specific versions or commits.

<Tip>
  Cryptographic signatures prove that a key signed something. They do not prove the signer, build system, or maintainer account was not compromised. Combine signing with access control, review, monitoring, and incident response.
</Tip>

## 8. CI/CD Security

CI/CD systems are high-value targets because they can access source code, secrets, deployments, containers, cloud accounts, and package registries.

### CI/CD Controls

* Require branch protection on main branches.
* Use least-privilege service accounts.
* Separate build, test, staging, and production permissions.
* Avoid long-lived deployment tokens.
* Restrict who can modify workflows.
* Protect self-hosted runners.
* Require manual approval for production deploys when risk is high.
* Log secret access and deployment activity.
* Scan artifacts before release.

### Pull Request Safety

Be careful when CI runs code from forks or untrusted contributors. That code may try to print secrets, modify workflows, or abuse runner permissions.

Safer options:

* Do not expose secrets to untrusted PRs.
* Use read-only tokens for validation jobs.
* Require maintainer approval before running privileged jobs.
* Review workflow changes carefully.

## 9. Secure Error Handling

Applications should fail safely and avoid leaking internal details.

```python theme={null}
# Bad: leaks internals to users
except Exception as e:
    return {"error": str(e)}

# Better: log details server-side, return a generic message
except Exception as e:
    logger.exception("Database operation failed")
    return {"error": "An internal error occurred. Please try again later."}
```

Principles:

* Never show stack traces to end users.
* Do not return database URLs, file paths, secrets, or internal hostnames.
* Log enough detail for investigation.
* Use correlation IDs so support can connect user reports to logs.
* Fail closed for authentication and authorization errors.

## 10. Security Logging and Detection

Secure coding includes creating the evidence defenders need.

Log security-relevant events:

* Login success and failure
* MFA enrollment and disablement
* Password reset requests and completion
* Session revocation
* Role changes
* Permission changes
* API key creation and use
* OAuth app approvals
* Data exports
* Webhook failures
* Package publish events
* CI/CD workflow changes

Avoid logging:

* Passwords
* Session cookies
* MFA codes
* API tokens
* Full payment details
* Sensitive personal data unless there is a clear need and protection

## 11. Threat Modeling

Threat modeling identifies what can go wrong before code is shipped.

Use **STRIDE**:

| Letter | Threat                 | Question                                           |
| ------ | ---------------------- | -------------------------------------------------- |
| S      | Spoofing               | Can someone pretend to be another user or service? |
| T      | Tampering              | Can someone modify data, code, or configuration?   |
| R      | Repudiation            | Can someone deny performing an action?             |
| I      | Information disclosure | Can sensitive data leak?                           |
| D      | Denial of service      | Can the system be made unavailable?                |
| E      | Elevation of privilege | Can someone gain more access than intended?        |

Apply STRIDE to:

* Authentication flows
* Admin panels
* Data export features
* Webhooks
* AI agent tools
* CI/CD workflows
* Package publishing
* Third-party integrations

## Secure Coding Checklist

* [ ] Validate input server-side.
* [ ] Encode output by context.
* [ ] Use parameterized queries.
* [ ] Enforce authorization on the server.
* [ ] Store secrets outside code.
* [ ] Use least-privilege tokens.
* [ ] Scan for secrets before commit.
* [ ] Review dependency changes.
* [ ] Protect CI/CD workflows and runners.
* [ ] Log security events.
* [ ] Threat model sensitive workflows.

## Practical Lab Ideas

1. Add server-side validation to an API route.
2. Fix an XSS bug by using contextual output encoding.
3. Replace a vulnerable SQL query with a parameterized query.
4. Add object-level authorization to an endpoint.
5. Run a secret scanner on a sample repository.
6. Create an SBOM and inspect transitive dependencies.
7. Harden a CI workflow so untrusted PRs cannot access secrets.
8. Threat model a package publishing workflow.

## Key Takeaways

1. **Secure coding includes the build and release path**.
2. **Authorization must be server-side and object-aware**.
3. **Secrets need lifecycle management, not just hiding**.
4. **Dependencies and extensions are attack surface**.
5. **CI/CD deserves the same security attention as production**.
6. **Good logs make response possible**.
7. **Threat modeling catches missing controls before attackers do**.
