# Interpreting Results This guide explains how to read Purplemet analysis results, prioritize remediation, and configure security gates for your context. ## Security Rating and Severity Levels Every analysis returns a **rating** (`A`, `B`, `C`, `D`, `E`, `F`) and classifies issues by **severity** (`CRITICAL`, `HIGH`, `MEDIUM`, `LOW`, `INFO`). Both are computed and defined by the Purplemet platform — the CLI only consumes these values. Refer to the [official Purplemet documentation](https://cloud.purplemet.com/docs/#/web%20applications/security-rating) for authoritative definitions, scoring rules, and examples. ## Output Formats Four output formats are available, each designed for a different audience: - **Human** — developer in a terminal (default) - **JSON** — CI/CD pipelines and automated processing - **SARIF** — security tool integrations (GitHub Code Scanning, Defect Dojo, VS Code) - **HTML** — everyone (stakeholders, managers, auditors, clients) ### Human-readable (default) The terminal output shows a color-coded summary. The format below is illustrative — actual values (rating, severities, CVE counts, technology categories, gate messages) come from the Purplemet API: ``` Purplemet • https://your-app.com • DONE ──────────────────────────────────────────────────────────── Analysis: Title: IP: HTTP: Duration: Rating: (score: <0-100>) Issues: — broken down by severity CVEs: Tech: technologies ( unsafe) WAF: Issues (...) ──────────────────────────────────────────────────────────── • CWE- • CVSS • EPSS ... Technologies (...) ──────────────────────────────────────────────────────────── Certificates ──────────────────────────────────────────────────────────── expires ( left) Gates (N configured) ──────────────────────────────────────────────────────────── ✓ passed ✗ failed X passed, Y failed / N gates ``` ### JSON The JSON output is designed for CI/CD pipelines and automated processing. JSON goes to stdout; progress updates and gate summaries go to stderr. During analysis, the CLI emits periodic status updates to stderr so CI logs show progress: ``` [purplemet] Waiting for analysis... [purplemet] Scanning — 25% (30s) [purplemet] Analyzing — 75% (1m15s) [purplemet] Analysis complete (2m05s) ``` ```bash purplemet-cli analyze https://your-app.com --json ``` **Top-level structure:** | Field | Type | Description | |-------|------|-------------| | `meta.version` | string | CLI version that generated the report | | `meta.timestamp` | string | ISO 8601 timestamp | | `analysis` | object | Full analysis data (see below) | | `gates` | object | Per-gate evaluation results | | `ignoredCount` | int | Number of IGNORED issues excluded from `analysis.issues` (always present, `0` when none) | | `error` | string | Error message (only on failure) | > **Fields are omitted when empty.** The JSON is encoded with `omitempty`: a > field appears only when it holds a non-zero / non-empty value. A trivial site > (no CVEs, no end-of-life technology, no exposed services) therefore emits a > subset of the fields below — e.g. `cveCnt`, `kevCnt` and `unsafeCnt` are > absent when `0`, and `certificates` / `services` when empty. The tables below > list the key fields the CLI emits, not a guaranteed-present set. **`analysis` object — key fields:** | Field | Type | Description | |-------|------|-------------| | `id` | string | Analysis UUID | | `site.id` | string | Site UUID | | `url` | string | Analyzed URL | | `status` | string | `DONE`, `ERROR`, `WARNING`, `ABORTED` | | `rating` | string | Letter grade A–F | | `score` | int | Numeric score (0–100, lower is better) | | `issueCnt` | int | Total issue count | | `issueCnts` | object | `{"CRITICAL": 0, "HIGH": 2, "MEDIUM": 3, ...}` | | `cveCnt` | int | Number of CVEs | | `kevCnt` | int | CISA Known Exploited Vulnerabilities count | | `technologyCnt` | int | Technologies detected | | `unsafeCnt` | int | Unsafe components count | | `waf` | string | WAF product name (empty if none) | | `duration` | string | ISO 8601 duration | | `remoteIp` | string | Origin IP address | | `httpResponseCode` | int | HTTP status code | | `issues` | array | Detailed issue list | | `technologies` | array | Technology details | | `certificates` | array | SSL certificate details | | `services` | array | Exposed services | **`issues[]` — each issue:** | Field | Type | Description | |-------|------|-------------| | `id` | string | Issue ID | | `severity` | string | `CRITICAL`, `HIGH`, `MEDIUM`, `LOW`, `INFO` | | `type` | string | Category: `SSL_TLS_PROTOCOLS`, `CERTIFICATES`, `HTTP_HEADERS`, `COOKIES`, etc. | | `name` | string | CVE identifier or vulnerability name | | `description` | string | Detailed description | | `reference` | string | External reference URL | | `cweId` | int | CWE number | | `cweName` | string | CWE name | | `exploitMaturity` | string | `ATTACKED` if actively exploited | | `status` | string | `OPEN`, `FIXED`, `REJECTED`, `IGNORED` | | `weight` | int | Internal weight used to compute the score | | `technology.name` | string | Affected technology | | `technology.version` | string | Affected version | | `details.cvss3Score` | float | CVSS v3 score (0–10) | | `details.cvss3Vector` | string | CVSS v3 vector string | | `details.epssScore` | float | EPSS score (0–1) | | `details.epssPercentile` | string | EPSS percentile | | `details.cisaAdditionDate` | string | Date added to CISA KEV catalog | | `details.cisaRequiredAction` | string | CISA recommended action | **`technologies[]` — each technology:** | Field | Type | Description | |-------|------|-------------| | `id` | string | Technology UUID | | `name` | string | Product name | | `version` | string | Detected version | | `category` | string | Technology category as defined by the Purplemet platform | | `cveCnt` | int | Known CVE count | | `endOfLife` | int | End-of-life date as a unix-ms timestamp (omitted when the component is not end-of-life) | | `latestVersion` | string | Latest available version | | `ossfScorecard.score` | float | OpenSSF Scorecard score (0–10) | **`gates` object:** Each gate key (e.g. `severity`, `rating`, `cvss`, `eol`, `waf`) maps to: | Field | Type | Description | |-------|------|-------------| | `name` | string | Gate identifier | | `passed` | bool | `true` if gate passed or was skipped | | `skipped` | bool | `true` if gate was not enabled | | `message` | string | Failure reason (empty if passed) | **Gate summary on stderr (CI-friendly):** In JSON/SARIF mode, the CLI also prints a human-readable gate summary to stderr so CI logs show which gates failed without parsing JSON: ``` [purplemet] FAILED severity: severity gate: 1 critical (threshold: high) [purplemet] FAILED eol: EOL gate: 2 end-of-life component(s) (jQuery 2.1.4, PHP 7.4) [purplemet] 2/4 gate(s) failed ``` **Example — parsing gates in CI:** ```bash # Check if any gate failed FAILED=$(echo "$RESULT" | jq '[.gates[] | select(.skipped == false and .passed == false)] | length') if [ "$FAILED" -gt 0 ]; then echo "Failed gates:" echo "$RESULT" | jq -r '.gates[] | select(.passed == false and .skipped == false) | " \(.name): \(.message)"' fi ``` ### SARIF SARIF 2.1.0 output is compatible with GitHub Code Scanning, Azure DevOps Advanced Security, and any SARIF viewer. ```bash purplemet-cli analyze https://your-app.com --format sarif --output-file results.sarif ``` **Structure:** - Each unique issue type becomes a SARIF **rule** with its severity, CWE, and description - Each finding becomes a SARIF **result** referencing that rule - The analyzed URL is used as the artifact location - Analysis metadata and gate results are in `runs[].properties` **Severity mapping to SARIF levels:** | Purplemet Severity | SARIF Level | |-------------------|-------------| | Critical, High | `error` | | Medium | `warning` | | Low, Info | `note` | **`runs[].properties` — analysis metadata:** | Field | Type | Description | |-------|------|-------------| | `rating` | string | Letter grade A–F | | `score` | int | Numeric score (0–100, lower is better) | | `url` | string | Analyzed URL | | `issueCnt` | int | Total issue count | | `issueCnts` | object | Issues by severity | | `cveCnt` | int | CVE count | | `kevCnt` | int | KEV count | | `gates` | object | Per-gate pass/fail results (only configured gates) | These custom properties follow the SARIF 2.1.0 specification and are accessible by tools like GitHub Code Scanning, Defect Dojo, and any SARIF viewer that supports `properties`. ### HTML Generates a standalone HTML report suitable for sharing with stakeholders, archiving as audit evidence, or publishing as a CI/CD pipeline artifact. ```bash purplemet-cli analyze https://your-app.com --format html --output-file report.html ``` The report is a self-contained `.html` file (no external dependencies) with a dark theme. It includes: - **Security rating** with color-coded badge (A–F) - **Issue summary** by severity (critical, high, medium, low, info) - **Issue details table** — severity, name, type, technology, CVSS, EPSS, CWE, description - **Technologies table** — name, version, category, flags (EOL, CVE count, latest version) - **Certificates table** — common name, issuer, expiry date, status - **Sensitive services table** — service name, port, protocol, IP address - **Gates summary** — configured gates with pass/fail status and failure messages - **Overview metrics** — total issues, CVE count, technology count, KEV count - **Analysis details** — ID, status, duration, WAF, remote IP, HTTP code, redirect URL, CLI version ## Prioritizing Remediation > General security guidance — not Purplemet-specific. Refer to your organization's policies and the [official Purplemet documentation](https://cloud.purplemet.com/docs) for authoritative remediation workflows. Common industry signals for prioritization: - **CISA KEV catalog** — vulnerabilities listed by CISA as actively exploited - **EPSS score** — probability of exploitation in the next 30 days (maintained by FIRST.org) - **CVSS score** — severity rating of a vulnerability (maintained by FIRST.org) - **Public exploit availability** - **End-of-life status** of affected components Combine these with your context (internal vs public, data sensitivity, compensating controls) to set remediation priorities. ### CVSS and EPSS in a nutshell - **CVSS** measures the *severity* of a vulnerability (how bad it is if exploited) - **EPSS** measures the *probability* of exploitation (how likely it will be exploited in the wild) A high CVSS + high EPSS issue is typically the highest priority. See [first.org/cvss](https://www.first.org/cvss/) and [first.org/epss](https://www.first.org/epss/) for authoritative definitions. ## Recommended Gate Configurations ### Staging / Pre-production Start strict to catch issues before production: ```bash purplemet-cli analyze https://staging.example.com --json \ --fail-on-severity high \ --fail-on-eol \ --fail-on-kev \ --fail-on-ssl \ --fail-on-cert ``` ### Production Monitoring Add broader checks for runtime concerns: ```bash purplemet-cli analyze https://app.example.com --json \ --fail-on-severity high \ --fail-on-eol \ --fail-on-kev \ --fail-on-active-exploits \ --fail-on-cert-expiry 30 \ --require-waf \ --fail-on-sensitive-services ``` ### Compliance-oriented Combine severity with specific policy gates: ```bash purplemet-cli analyze https://app.example.com --json \ --fail-on-severity medium \ --fail-on-cvss 7.0 \ --fail-on-epss 0.5 \ --fail-on-eol \ --fail-on-ssl \ --fail-on-headers \ --fail-on-cookies \ --fail-on-ossf-score 5.0 \ --exclude-tech "php" ``` ### Progressive Rollout Start permissive, tighten over time: 1. **Week 1**: `--fail-on-severity critical` — block only critical issues 2. **Week 2**: `--fail-on-severity high --fail-on-kev` — add high severity + known exploits 3. **Month 2**: Add `--fail-on-eol --fail-on-ssl --fail-on-cert` 4. **Month 3**: Add `--fail-on-headers --fail-on-cookies --require-waf` This avoids overwhelming teams with hundreds of findings on day one. ## Tracking Progress Over Time Use the `diff` command to compare two analyses and measure improvement: ```bash purplemet-cli diff --site-id ``` Output shows the delta for rating, score, issues, CVEs, and technologies: ``` Rating: C → B Score: 45 → 18 (-27) Issues: 25 → 12 (-13) CVEs: 5 → 1 (-4) ``` Use scheduled analyses (`sites schedule` or CI/CD cron) to monitor security posture continuously.