Add compliance-staging folder, gitignore agents, update docs and kiro config

This commit is contained in:
jramos
2026-04-16 14:41:52 -06:00
parent f141fa58a1
commit a214393723
9 changed files with 396 additions and 44 deletions

Binary file not shown.

7
.gitignore vendored
View File

@@ -52,5 +52,12 @@ backend/fix_multivendor_constraint.js
backend/server.js-backup backend/server.js-backup
backend/setup.js-backup backend/setup.js-backup
# Compliance staging — keep folder, ignore contents
.compliance-staging/*
!.compliance-staging/.gitkeep
# Kiro agents (local only)
.kiro/agents/
# Kiro implementation summary (internal only) # Kiro implementation summary (internal only)
docs/kiro-implementation-summary.md docs/kiro-implementation-summary.md

View File

@@ -0,0 +1,13 @@
{
"enabled": true,
"name": "Doc Review",
"description": "Manually triggered after merging to master. Reads the recent git diff, classifies the changes, and proposes documentation updates following the doc-updater decision tree and doc-standards.md conventions.",
"version": "1",
"when": {
"type": "userTriggered"
},
"then": {
"type": "askAgent",
"prompt": "Run a documentation review against the latest changes on master. Follow these steps exactly:\n\n1. Run `git log --oneline -10` to see recent commits. If any commit message contains `[skip-docs]`, stop and report NO_DOC_UPDATE_NEEDED.\n\n2. Run `git diff HEAD~1 --stat` to get the list of changed files, then `git diff HEAD~1` to get the full diff. If the diff is larger than 500 lines, report NEEDS_HUMAN_REVIEW with a summary of which areas likely need docs.\n\n3. Read `.kiro/agents/doc-updater.md` for the full decision tree and `.kiro/steering/doc-standards.md` for formatting conventions.\n\n4. Follow the doc-updater decision tree: triage the change, decide if docs need updating, survey existing docs (README.md, docs/ folder), and propose surgical edits.\n\n5. For any proposed changes, apply them directly to the doc files. Only touch README.md and files under docs/. Never touch code files.\n\n6. After applying changes, output the SUMMARY block from the decision tree so Jordan can review what was changed and why."
}
}

View File

@@ -0,0 +1,13 @@
{
"enabled": true,
"name": "Ivanti API Debugger",
"description": "Manually triggered when debugging a failing Ivanti API call. Prompts for the endpoint, request payload, and error response, then invokes the ivanti-api-debugger agent to diagnose the issue and update ivanti-api-reference.md with any findings.",
"version": "1",
"when": {
"type": "userTriggered"
},
"then": {
"type": "askAgent",
"prompt": "You are the Ivanti API Debugger agent. Follow the instructions in `.kiro/agents/ivanti-api-debugger.md` exactly.\n\nAsk the user to provide the following (one clarifying question, not five — accept whatever they paste and infer the rest):\n\n1. The failing endpoint or route — either the Ivanti API path (e.g. `/workflowBatch/falsePositive/request`) or the backend route file/handler that makes the call (e.g. `backend/routes/ivantiWorkflows.js`)\n2. The request payload they sent (curl, JSON body, or code snippet)\n3. The response or error they got back (HTTP status, response body, or error message)\n\nOnce you have that context, follow the full diagnostic workflow described in `.kiro/agents/ivanti-api-debugger.md`: read the relevant route/service code, cross-reference `docs/ivanti-api-reference.md`, check for common Ivanti failure modes, form a hypothesis, and propose a concrete next request to try. If the user confirms a finding, update `docs/ivanti-api-reference.md` using its existing structure."
}
}

View File

@@ -0,0 +1,13 @@
{
"enabled": true,
"name": "Security Audit Tracker",
"description": "Manually triggered to scan the codebase for security issues and maintain a living audit tracker document. Prompts for scan scope (full repo or specific path) and mode (report only or report + update tracker). Invokes the security-audit-tracker agent for static analysis and doc tracking.",
"version": "1",
"when": {
"type": "userTriggered"
},
"then": {
"type": "askAgent",
"prompt": "You are the Security Audit Tracker agent. Follow the instructions in `.kiro/agents/security-audit-tracker.md` exactly.\n\nAsk the user to provide the following two inputs:\n\n1. **Scope:** \"full repo\" to scan the entire codebase, or a specific path/module to focus on (e.g. `backend/routes/`, `frontend/src/components/`, `backend/helpers/ivantiApi.js`)\n2. **Mode:** \"scan only\" (report findings to chat, no file writes) or \"scan + update tracker\" (report findings and merge them into the tracker doc at `docs/security-audit-tracker.md`)\n\nOnce you have both inputs, follow the full diagnostic and tracking workflow described in `.kiro/agents/security-audit-tracker.md`: determine scope, check for the tracker doc (create it if missing), scan for the security failure modes listed in the agent spec, cross-reference against previously tracked findings, and output a prioritised report. In \"scan + update tracker\" mode, also merge findings into the tracker doc and update its metadata."
}
}

View File

@@ -0,0 +1,190 @@
# Documentation Standards — CVE Dashboard
These standards are reverse-engineered from the existing README.md and should be treated as the canonical style guide for all documentation in this repository. When updating docs, match these conventions exactly — consistency matters more than any individual stylistic preference.
---
## Language and Style
- Write in **present tense, active voice**. "The sync fetches findings" — not "Findings will be fetched by the sync."
- Do not use marketing language. No "powerful", "seamless", "robust", "cutting-edge", "unleash". Describe what the thing does, not how great it is.
- No emoji anywhere in documentation. None.
- Prefer precise technical vocabulary over casual phrasing. "Session tokens are stored in `httpOnly` cookies" — not "we keep the login thing in a secure cookie."
- **Spelling:** match whatever spelling variant already appears in the surrounding prose. Do not rewrite existing words to switch between US and British English — consistency within a section matters more than which variant is used.
---
## Punctuation and Formatting
- **Em-dashes (—)** for mid-sentence clarifications or appositives, surrounded by spaces: `sync requires Admin or Standard_User group — the sync then fetches findings`.
- **En-dashes ()** for numeric ranges: `8.59.9 VRR`, `20 attempts per 15-minute window`.
- Use **inline backticks** for: file paths, environment variables, CLI flags, function names, field names, HTTP status codes, and any literal value the reader should type or recognise verbatim.
- Use **bold** (`**text**`) for UI element names (button labels, tab names, form fields) and for label-style emphasis at the start of a sub-point.
- Avoid italics except for rare genuine emphasis. Do not use italics decoratively.
---
## Heading Hierarchy
Use a strict three-tier hierarchy per document:
```
# Document Title (one per file, matches repo/feature name)
## Top-Level Section (Overview, Features, Architecture, etc.)
### Subsection (a named feature, page, or concept)
**Sub-subsection label** (bold paragraph labels — NOT an #### heading)
```
- Do **not** use `####` or deeper headings. If you need a fourth level, it should be a bold inline label followed by content, matching the existing README pattern.
- Separate top-level `##` sections with a horizontal rule (`---`) on its own line, with blank lines above and below.
- Do not place horizontal rules between `###` subsections unless visually necessary.
---
## Table of Contents
- Any document over ~200 lines should open with a Table of Contents using markdown anchor links.
- Nest TOC entries to match heading depth (`##` entries flush-left, `###` entries indented two spaces).
- Anchor slugs: lowercase, spaces become hyphens, em-dashes become `--` (two hyphens). Example: `## Home — CVE Management` becomes `#home--cve-management`.
---
## Tables
Use tables for any reference material with two or more parallel attributes. This includes:
- Permission matrices (group → capabilities)
- Tech stack listings (layer → technology)
- Column descriptions (column → meaning)
- Environment variable references (name → purpose → default)
- Route references (method + path → description → auth requirement)
Table format:
```markdown
| Column | Description |
|---|---|
| `field_name` | What it does |
```
- Always use `---` separators (not `:---:` centred alignment) unless centring is specifically warranted.
- Keep cell content on a single line. If a value is long, prefer prose above or below the table.
- Use inline backticks for literal values inside cells.
---
## Code Blocks
- **Always include a language tag** on fenced code blocks: ` ```bash `, ` ```javascript `, ` ```json `, ` ```python `, ` ```sql `. Bare ` ``` ` is not acceptable.
- Shell commands use `bash` — even for single-line commands.
- Place code blocks on their own line, with blank lines before and after.
- Inside code blocks, do not use markdown formatting (no bold, no italics). Treat them as literal terminal/file content.
- Prefer showing the actual command over describing what to do. "Run `node setup.js` from `backend/`" with a code block — not "initialize the database."
---
## Callouts and Warnings
- Use a blockquote (`>`) for callouts, notes, and warnings. Do not use GitHub-flavoured admonition syntax (`> [!NOTE]`), Docusaurus admonitions, or custom HTML.
- Keep callouts to one or two sentences. If longer, promote to prose.
- Example: `> IVANTI_API_KEY must be set in backend/.env for sync to work.`
Bold prefixes for emphasis are acceptable inside a blockquote: `> **Warning:** This deletes all audit records older than 90 days.`
---
## Feature Documentation Pattern
When documenting a feature or page, follow this structure:
1. **One-sentence summary** of what the feature is and who uses it.
2. **Capability bullets** — what a user can do, grouped by role if access-controlled.
3. **Workflow or interaction details** — how the feature is used in practice (inline editing behaviour, filter semantics, persistence rules).
4. **Integration notes** — what external systems it touches, what credentials it needs, what it caches.
5. **Edge cases and restrictions** — delete rules, rate limits, role requirements.
Bold paragraph labels (`**Inline editing:**`, `**CVE Tooltips:**`, `**Filtering:**`) are the preferred pattern for calling out sub-behaviours within a feature section.
---
## Troubleshooting Entries
Every troubleshooting entry uses the **Symptom → Cause → Fix** triad:
```markdown
### Short description of the problem
**Symptom:** What the user sees or experiences. Be specific about error messages, console output, and observed behaviour.
**Cause:** The underlying reason, explained in one or two sentences. Include the technical mechanism (cookie flag, rate limiter, missing migration) — not just "it's broken."
**Fix:** Either:
1. Concrete action with a command or config change, **or**
2. Alternative action.
```
- Short entries (fix is one command) may collapse Cause into Fix, but Symptom must always appear explicitly.
- Use **Fix:** as the label, not "Solution" or "Resolution."
---
## CHANGELOG
This project does not currently maintain a `CHANGELOG.md`. The doc-updater agent should **not** create one unless explicitly instructed.
When a change ships, rely instead on:
- **Git commit messages** as the primary change history. Write them as complete sentences describing user-observable behaviour, not implementation detail. "Add inline editing to CVE reporting table" — not "fix table.jsx."
- **README updates** as the user-facing record of what the app does now. The README is the source of truth for current behaviour; git log is the source of truth for when and why it changed.
If a `CHANGELOG.md` is introduced later, this section should be rewritten to declare the chosen format. Until then, the agent should leave changelog concerns out of scope.
---
## Migration Documentation
When a feature requires a new database migration:
1. Add the migration filename to the README's **Migrations** section in the order it must be run.
2. If the migration is required for an existing deployment (not just fresh installs), add a Troubleshooting entry using the Symptom → Cause → Fix pattern for the error users will see if they skip it.
3. Note any data-transforming migrations explicitly — users need to know whether the migration is additive (safe to re-run) or transformative (destructive if re-run).
---
## API Reference Documentation
- Document routes as: `METHOD /path/with/:params`
- Group routes by resource or page (CVE routes, Ivanti routes, Audit routes).
- For each route, specify: purpose, required group, request body or query params, response shape summary. Keep it to 24 lines per route.
- Do not duplicate route implementation details. Link to the source file if deeper reference is needed.
- When a route enforces group-based authorisation, state the required group explicitly — do not imply it from context.
---
## What to Update When a Feature Ships
A new feature or meaningful change to existing behaviour should touch:
1. **README.md — Features section:** add or update the relevant `###` subsection, matching the Feature Documentation Pattern above.
2. **README.md — Table of Contents:** if a new feature added a new heading, update the TOC to match.
3. **README.md — Configuration:** if new env vars were introduced, add them to the Configuration table.
4. **README.md — API Reference:** if new routes were added, document them under the appropriate resource group.
5. **README.md — Database Schema:** if tables or columns changed, update the schema section.
6. **README.md — Migrations:** if a new migration was added, append it to the ordered list.
7. **docs/**: if the feature has its own standalone guide (setup guide, integration guide), create or update the relevant file in `docs/`.
If a change does not alter user-observable behaviour, configuration, data model, or API surface, it does not require doc changes. Internal refactors, test additions, and dependency bumps are exempt unless they change how the app is run or deployed.
---
## What NOT to Change
The doc-updater agent and human contributors alike should **leave alone**:
- Tone, voice, and spelling conventions of existing prose. Match, do not rewrite.
- Section ordering in the README — the current order is deliberate and reader-tested.
- Heading wording, unless the underlying feature has genuinely been renamed.
- Examples and command snippets that still work, even if they could be "more elegant."
- The overall shape of the Troubleshooting section — append new entries, do not reorganise existing ones.
Documentation churn is a cost. Only change what the code change requires.

View File

@@ -60,9 +60,8 @@ The application provides:
| Database | SQLite3 | | Database | SQLite3 |
| File uploads | Multer 2 | | File uploads | Multer 2 |
| Auth | bcryptjs, cookie-based sessions, express-rate-limit | | Auth | bcryptjs, cookie-based sessions, express-rate-limit |
| Frontend | React 19, lucide-react, xlsx, rehype-sanitize | | Frontend | React 19, lucide-react, recharts, xlsx, react-markdown, rehype-sanitize, mermaid |
| Compliance xlsx parsing | Python 3, pandas, openpyxl | | Compliance xlsx parsing | Python 3, pandas, openpyxl |
| Bulk notes import | Python 3 (stdlib only) |
--- ---
@@ -106,7 +105,7 @@ apt install -y python3-pandas python3-openpyxl
> If apt packages are unavailable or you need a specific version, see `docs/python-venv-setup.md` for the venv fallback approach. > If apt packages are unavailable or you need a specific version, see `docs/python-venv-setup.md` for the venv fallback approach.
> The bulk notes import script (`import_notes_from_csv.py`) uses only Python stdlib and does **not** require these packages. > A bulk notes import script (`import_notes_from_csv.py`) is also available in `backend/scripts/` for maintenance tasks like backfilling notes from a CSV. It uses only Python stdlib.
### 5. Configure environment variables ### 5. Configure environment variables
@@ -362,7 +361,9 @@ Each row represents a single Ivanti host finding.
**Column management:** Toggle visibility and drag to reorder via the **Columns** button. Order and visibility persist to `localStorage`. **Column management:** Toggle visibility and drag to reorder via the **Columns** button. Order and visibility persist to `localStorage`.
**Export:** Click **Export** to download the current filtered view as CSV or XLSX. Requires Admin, Standard_User, or Leadership group. **Row visibility:** Hide individual rows by clicking the `EyeOff` icon on any row, or select multiple rows via checkboxes and click **Hide Selected** in the bulk action toolbar. Hidden rows are excluded from the table, the Action Coverage chart, and exports. Use the **Hidden (N)** button in the toolbar to view and restore hidden rows individually or all at once. Hidden row state persists to `localStorage` across sessions. Row hiding is a personal view preference available to all user groups.
**Export:** Click **Export** to download the current filtered view as CSV or XLSX. Hidden rows and filtered rows are both excluded from exports. Requires Admin, Standard_User, or Leadership group.
--- ---
@@ -509,45 +510,6 @@ Called automatically by the compliance upload flow. Parses the NTS_AEO xlsx repo
--- ---
### `backend/scripts/import_notes_from_csv.py`
Bulk-import notes into the findings cache from a CSV file. Useful for onboarding existing notes or migrating from a spreadsheet.
**CSV format:**
```csv
ID,NOTES
12345678,EXC-5754
87654321,Patched in Feb maintenance window
```
**Usage:**
```bash
cd backend/scripts
# Preview what would be imported (no writes)
python3 import_notes_from_csv.py input.csv --dry-run
# Import against the default database path
python3 import_notes_from_csv.py input.csv
# Import against a specific database
python3 import_notes_from_csv.py input.csv --db /path/to/cve_database.db
```
| Argument | Description |
|---|---|
| `csv_file` | Path to the input CSV (required) |
| `--db` | Path to the SQLite database (default: `../cve_database.db`) |
| `--dry-run` | Preview changes without writing to the database |
- Notes longer than 255 characters are truncated with a warning
- Finding IDs not present in the active Ivanti cache are skipped
- Uses UPSERT — running the same CSV twice is safe
**Dependencies:** Python stdlib only (no pip install required).
---
## API Reference ## API Reference
All endpoints are prefixed with `/api`. All endpoints except `/api/auth/login` and `/api/auth/logout` require a valid session cookie. Group requirements are listed per endpoint. All endpoints are prefixed with `/api`. All endpoints except `/api/auth/login` and `/api/auth/logout` require a valid session cookie. Group requirements are listed per endpoint.

View File

@@ -1,4 +1,4 @@
# CVE Tracking & NVD Sync Guide # CVE Tracking & NVD Sync Spec
## Overview ## Overview

View File

@@ -0,0 +1,154 @@
# Security Remediation Plan
Based on the External Data Handling security audit (April 2026). 17 findings total — 0 Critical, 2 High, 6 Medium, 6 Low, 3 Informational. Ordered by priority based on real-world exploitability and effort.
---
## Phase 1 — Data Exposure & XSS (High Priority)
### 1. L-4: Authenticate /uploads static file access
**Location:** `server.js:127`
**Risk:** Uploaded documents (vulnerability data, compliance files) served without authentication. Anyone with the URL can access them.
**Fix:** Replace `express.static('/uploads')` with a route handler that runs `requireAuth(db)` before streaming the file. Use `res.sendFile()` with the validated path.
**Effort:** Small — single route change.
### 2. M-6: Sanitize Mermaid SVG output with DOMPurify
**Location:** `frontend/src/components/KnowledgeBaseViewer.js:38`
**Risk:** Mermaid renders SVG which is injected via `innerHTML`. If KB content contains malicious markup, this is a stored XSS vector.
**Fix:** Install `dompurify`, sanitize the SVG string before assigning to `innerHTML`. Use `DOMPurify.sanitize(svgString, { USE_PROFILES: { svg: true } })`.
**Effort:** Small — add dependency, wrap one line.
### 3. M-4: Strip server file paths from compliance preview response
**Location:** `backend/routes/compliance.js:278`
**Risk:** Full server-side file path returned to client. Helps attackers map the filesystem.
**Fix:** Return only the filename (use `path.basename()`) instead of the full path. Or return a reference ID that maps to the file server-side.
**Effort:** Small — one-line change.
---
## Phase 2 — Deployment & Setup Hygiene
### 4. H-2: Add SESSION_SECRET to .env.example and setup-env.sh
**Location:** `backend/.env.example`, `backend/setup-env.sh`
**Risk:** Fresh deployments fail with no guidance on required env vars.
**Fix:** Add `SESSION_SECRET=` to `.env.example` with a comment explaining it should be a random 64+ character string. Add generation logic to `setup-env.sh` (e.g., `openssl rand -hex 32`).
**Effort:** Small.
### 5. I-3: Set user_group on default admin in setup.js
**Location:** `backend/setup.js:180`
**Risk:** Default admin created without `user_group`, potentially locked out of `requireGroup`-protected routes on fresh install.
**Fix:** Set `user_group = 'Admin'` in the INSERT statement for the default admin user.
**Effort:** Trivial — one column added to the INSERT.
---
## Phase 3 — Error Message Sanitization (Batch)
### 6. L-2: Sanitize Python parser error messages
**Location:** `backend/routes/compliance.js:284`
**Risk:** Stack traces and server paths leaked to client when Python parser fails.
**Fix:** Catch the error, log the full details server-side, return a generic "Compliance file parsing failed" message to the client.
**Effort:** Small.
### 7. L-3: Sanitize Ivanti API error responses
**Location:** `backend/routes/ivantiFpWorkflow.js:393`
**Risk:** Raw Ivanti API error body forwarded to client, potentially exposing internal API details.
**Fix:** Log the raw error server-side, return a generic "Ivanti API request failed" message to the client.
**Effort:** Small.
### 8. L-6: Remove group name from requireGroup error response
**Location:** `backend/middleware/auth.js:60`
**Risk:** Error response leaks the user's current group name, which is minor info disclosure.
**Fix:** Change the error message from something like "User group 'Viewer' not authorized" to "Insufficient permissions."
**Effort:** Trivial.
---
## Phase 4 — Security Headers
### 9. M-1: Add Content-Security-Policy header
**Location:** `server.js:107-113`
**Risk:** No CSP means no browser-side XSS mitigation layer.
**Fix:** Add a CSP header via middleware. Start with a report-only policy to avoid breaking things, then tighten. Suggested baseline:
```
default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'
```
Note: `'unsafe-inline'` for styles is needed because the app uses inline style objects extensively. Evaluate whether `script-src 'self'` breaks anything (it shouldn't with CRA).
**Effort:** Medium — needs testing to ensure nothing breaks.
### 10. M-2: Add Strict-Transport-Security (HSTS) header
**Location:** `server.js:107-113`
**Risk:** No HSTS means browsers don't enforce HTTPS on subsequent visits.
**Fix:** Add `Strict-Transport-Security: max-age=31536000; includeSubDomains` header. Only apply when running behind HTTPS (check `req.secure` or a trusted proxy header). Do NOT enable if the app is accessed over plain HTTP.
**Effort:** Small, but verify deployment is HTTPS-only first.
---
## Phase 5 — Operational Maintenance
### 11. L-5: Add expired session cleanup
**Location:** `backend/middleware/auth.js:271`
**Risk:** Sessions table grows indefinitely. Not a security exploit, but degrades performance over time.
**Fix:** Add a cleanup function that runs on server startup (and optionally on a setInterval) to DELETE sessions where `expires_at < CURRENT_TIMESTAMP`. Run once at boot, then every 6 hours.
**Effort:** Small.
---
## Phase 6 — Session Signing (Larger Effort)
### 12. H-1: Use SESSION_SECRET for HMAC-signed session tokens
**Location:** `server.js:33`
**Risk:** Session tokens are random bytes stored in DB with no signing. An attacker with DB read access can replay any session. For self-hosted SQLite, DB access already implies full compromise, so this is a defense-in-depth measure.
**Fix:** When creating a session, generate a random token and store its HMAC (using SESSION_SECRET) in the DB. On validation, recompute the HMAC and compare. This means a DB dump alone isn't enough to forge sessions — the attacker also needs the secret.
**Effort:** Medium — touches session creation, validation, and requires SESSION_SECRET to actually be wired in.
---
## Phase 7 — Investigate Before Changing
### 13. M-3: Review application/octet-stream in MIME allowlist
**Location:** `server.js:62`
**Risk:** Allows uploads that bypass MIME type checking. May be intentional for specific file types.
**Action:** Check what file types are uploaded that resolve to `application/octet-stream`. If none are legitimate, remove it from the allowlist. If some are (e.g., `.db` files, binary exports), consider adding those specific MIME types instead.
**Effort:** Investigation first, then trivial change.
### 14. M-5: Evaluate CORS HTTP origin policy
**Location:** `server.js:38-40`
**Risk:** CORS allows HTTP origins, no HTTPS enforcement.
**Action:** Check if production runs behind a reverse proxy with HTTPS termination. If yes, the backend legitimately sees HTTP origins from the proxy. If production traffic is ever plain HTTP end-to-end, restrict CORS to HTTPS origins only.
**Effort:** Investigation first, then small config change.
---
## Phase 8 — Low Priority / Monitor
### 15. L-1: Add startup warning for IVANTI_SKIP_TLS=true
**Location:** `backend/helpers/ivantiApi.js:28`
**Risk:** TLS validation disabled silently. Acceptable in dev, risky if accidentally left on in production.
**Fix:** Add a `console.warn('⚠ IVANTI_SKIP_TLS is enabled — TLS certificate validation is disabled')` at startup when the flag is set.
**Effort:** Trivial.
### 16. I-1: Monitor react-scripts version
**Location:** `frontend/package.json`
**Risk:** Build-time only, not runtime. No immediate action needed.
**Action:** Upgrade to latest react-scripts when convenient. Consider migrating to Vite if a major frontend overhaul is planned.
### 17. I-2: Monitor xlsx dependency
**Location:** `frontend/package.json`
**Risk:** Community fork, unmaintained since 2022. Used for spreadsheet parsing.
**Action:** Monitor for security advisories. If a vulnerability is found, evaluate alternatives (e.g., `exceljs`, `sheetjs` pro). No immediate action needed unless a CVE is published against it.
---
## Summary
| Phase | Items | Effort | Impact |
|-------|-------|--------|--------|
| 1 — Data Exposure & XSS | L-4, M-6, M-4 | Small | High |
| 2 — Deployment Hygiene | H-2, I-3 | Small | Medium |
| 3 — Error Sanitization | L-2, L-3, L-6 | Small | Low-Medium |
| 4 — Security Headers | M-1, M-2 | Medium | Medium |
| 5 — Session Cleanup | L-5 | Small | Low |
| 6 — Session Signing | H-1 | Medium | Medium |
| 7 — Investigate | M-3, M-5 | Investigation | TBD |
| 8 — Monitor | L-1, I-1, I-2 | Trivial | Low |