From 550ed5c9eee332ed15551074f05973bada926a1a Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 28 Oct 2026 11:26:08 +0000 Subject: [PATCH 01/10] Add the risk register: threats per asset, a risk matrix, requirements from baselines Each asset gets the threats of a 30-entry catalogue (MITRE ATT&CK, ENISA Threat Landscape, EBIOS RM risk sources) that fit its type, exposure, criticality, ports, system and vulnerabilities, and the threat landscape of its IS. Each risk sits on a configurable matrix (3x3 to 5x5) before and after the requirements applied from the ANSSI hygiene guide, NIST CSF 2.0, CIS Controls v8.1, ISO 27001 Annex A or custom baselines, with a decision per risk. A Risks view shows the register of an IS. The risk settings are a new shared document kind (PUT /api/risk), kept in the history, proposals, export and import. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Ke7yEW5dhDYFVpV2cdgs87 Signed-off-by: Claude --- CHANGELOG.md | 9 ++ README.md | 6 +- docs/api.html | 29 +++- package.json | 2 +- public/app.css | 59 +++++++- public/app.js | 295 ++++++++++++++++++++++++++++++++++++--- public/baselines.js | 13 ++ public/index.html | 4 +- public/risk.js | 261 ++++++++++++++++++++++++++++++++++ scripts/build-online.mjs | 10 +- server/server.js | 30 ++-- tests/api.test.mjs | 22 +++ tests/e2e.mjs | 35 +++++ tests/risk.test.mjs | 138 ++++++++++++++++++ 14 files changed, 869 insertions(+), 44 deletions(-) create mode 100644 public/baselines.js create mode 100644 public/risk.js create mode 100644 tests/risk.test.mjs diff --git a/CHANGELOG.md b/CHANGELOG.md index 54946e0..23ea58f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,15 @@ All notable changes to Strata. Versions follow [Semantic Versioning](https://sem - **Anonymised AI prompts per asset** (*AI prompts* on an asset sheet): one prompt for the major risks of the asset, one guide that has the AI list plausible incidents and write their response playbooks in Muster's `muster/v1` YAML, with `targets`. Names, addresses, subnets, contacts and the IS name are replaced by placeholders (`ASSET-T`, `ASSET-01`, `SEG-1`, `SVC-B1`); a leak check lists anything identifying left in the text, with your own terms to never send; the answer pasted back gets your names again, in the page only. French or English. - **The connection to Muster** (`MUSTER_URL`, `MUSTER_USER`, `MUSTER_PASSWORD`). This server signs in to Muster with an analyst account and lists its responses; the incident sheet of an IS shows those linked to it (declared in Muster with this IS, or naming its assets), and the others with *Open on this IS*. Opening one marks the assets it names, then the playbook runs from the map: answering a decision or finishing a step moves the response in Muster, the tasks ticked go both ways, and what Muster's analysts do shows on the map within seconds. A decision answered anywhere marks the assets its `effects` name. Every mark and every flow cut goes to Muster's timeline, so its report keeps them, written by the Strata account with the name of the person who did it. Each incident is its own situation: opening another one on the same IS puts the marks and cuts of the previous one aside (marks made by hand before any incident stay). A decision answered in Muster marks the assets as soon as a contributor has the IS open in Strata. Muster's report gets an *Assets hit (Strata)* section. Without `MUSTER_URL`, the two example incidents stay. - **API**: `GET /api/incidents`, `PUT /api/incidents/{IS id}` (contributors and up, no proposal), `GET /api/muster`, `GET /api/muster/incidents/{id}`, `POST /api/muster/incidents/{id}/advance`, `/tasks`, `/strata`, and the `incidents` and `muster` events on `/api/events`. Kept in `incidents.json`, outside the map and its history. +- **Risk register** (*Risks*, the fourth view of an IS, next to Physical, Application and Business; and *Risks* on every asset sheet): + - **a threat landscape per asset**: 30 threats, each with its MITRE ATT&CK techniques, ENISA Threat Landscape families and EBIOS RM risk sources, apply to an asset from its type, exposure, criticality (its own or that of the business services it would hit), listening ports, system, vulnerabilities (CISA KEV, titles), role and Internet services. The sheet of a risk says why it applies. A threat can be added by hand or set aside with a justification; + - **the threat landscape of an IS**: how relevant each of the 8 risk sources is to it (0 to 3; cybercrime first by default, as in the ENISA Threat Landscape). A source rated 0 takes its threats away; + - **a risk matrix of its own for each asset**: likelihood from the threat, the exposure and reachability of the asset, its vulnerabilities (CVSS, EPSS, KEV) and its risk sources; impact from the threat and the criticality. Shown before requirements, with those applied, and once the planned ones are too; + - **requirements from baselines**: for each risk, the requirements that address it, each *applied*, *planned* or *not applicable*; each one applied removes its share of the likelihood or of the impact. Shipped: ANSSI *Guide d'hygiène informatique* (42 measures), NIST CSF 2.0 (106 subcategories), CIS Controls v8.1 (153 safeguards, numbering and paraphrased titles) and ISO/IEC 27001:2022 Annex A (93 controls, numbering and paraphrased titles); ANSSI is on by default. Import your own as JSON or CSV; + - **a decision for each risk**: treat, accept, transfer or avoid, with a justification; + - **the register of an IS**: two heatmaps (before and with the requirements; click a cell to list its risks), the table of every risk, and a CSV export; + - **risk settings** shared by every IS (*Risks › Settings*): the matrix (3 to 5 levels each way, labels, the level of each cell, the acceptance threshold), the baselines in use, the threat catalogue (disable a threat, add your own), export and import as JSON. Saved like the rest of the map: in the history, through proposals for contributors, in exports and imports. +- **API**: `PUT /api/risk` (approvers), `risk` in `GET /api/state`, the export, the import and proposals; `landscape` on IS documents, `risk` on asset documents. - **One-page build**: `npm run build:online` writes `dist-online/strata.html`, the whole interface without a server (map kept in the browser, three.js from jsDelivr). ## [0.9.0] - 2026-10-26 diff --git a/README.md b/README.md index cba8c7f..a4cc23c 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ Connectors are now **modules**: a folder with a manifest (`strata-module.json`: - **Blast radius**: pick an asset (in the panel, or *Blast radius* on its sheet) and see everything an attacker holding it could reach, the most likely way to each asset, and the business services hit. - A step counts for the highest of: the vulnerabilities of the asset taken over (as for the risk score), 50% on a remote administration port (SSH, RDP, SMB, WinRM, VNC, Telnet, RPC), 10% on any other service; a path for the product of its steps. Both lists export as CSV. - **Incident mode, with Muster** (*Incident* in the controls of an IS): mark assets compromised, suspected or contained; the incident sheet lists who to call, the flows to cut and the firewall where to cut each, the business services and assets that depend on them, what the attacker reaches next. A Muster incident opens on the map and its playbook decisions point at the assets. Each asset also has anonymised *AI prompts*: its major risks, and a guide for an AI to write the response playbooks of its plausible incidents in Muster's format. +- **Risk register** (the *Risks* view of an IS, and *Risks* on each asset sheet): each asset gets the threats that fit it, from its exposure, criticality, ports, system and vulnerabilities and from the threat landscape of its IS (EBIOS RM risk sources, ENISA Threat Landscape, MITRE ATT&CK). Each risk sits on a risk matrix of its own, 3×3 to 5×5 and configurable, before and after the requirements applied. For each risk, apply, plan or set aside the requirements of the ANSSI hygiene guide, NIST CSF 2.0, CIS Controls v8.1, ISO 27001 Annex A or your own baselines, or accept, transfer or avoid the risk. The register exports as CSV. - **Architecture file**: one document per IS (*Analysis › Architecture file*, or the IS summary), in the shape audits and security accreditation expect: cover and sign-off table, summary, scope, network diagram, zones and VLANs, applications, asset inventory, flow matrix, the rules each firewall needs, exposure, vulnerabilities and remediation order, attack paths, plans of the exposed and critical assets, incident contacts, change history and method. *Download* saves it as one HTML file, with no outside resource, that prints to A4 PDF from the browser. - **Nix and NixOS**: the repository is a flake, with a package and a hardened `services.strata` module (section 6, *Nix and NixOS*). - **Failed sign-ins are limited** per account and per client address (`429`), and passwords can be read from files (`EDIT_PASS_FILE`, `VIEW_PASS_FILE`): section 3. @@ -454,20 +455,21 @@ Every route needs the same credentials as the interface (a local account with Ba | Method and route | What it does | |---|---| -| `GET /api/state` | The whole map: `{si, assets, wan, services, rev, updatedAt}` | +| `GET /api/state` | The whole map: `{si, assets, wan, services, risk, rev, updatedAt}` | | `GET /api/export` | The same content, as a file to download | | `PUT /api/si/{id}` | Creates or replaces an IS (zones, VLANs, flows, contacts) | | `DELETE /api/si/{id}` | Deletes an IS (not its assets) | | `PUT /api/assets/{id}` | Creates or replaces an asset | | `DELETE /api/assets/{id}` | Deletes an asset | | `PUT /api/wan` | Replaces the links between IS: `{"links": [...]}` | -| `POST /api/import` | Replaces the whole map: `{si, assets, wan, services}` | +| `POST /api/import` | Replaces the whole map: `{si, assets, wan, services, risk}` | | `GET /api/incidents` | Incident mode of every IS: `{incidents: {: {on, marks, cuts, run, log}}}` | | `GET /api/muster` | Muster's incidents and whether Muster answers (`{url, ok, error, incidents}`), when `MUSTER_URL` is set | | `GET /api/muster/incidents/{id}` | One Muster incident: its frozen playbook, the steps taken, the link to Strata | | `POST /api/muster/incidents/{id}/advance`, `/tasks`, `/strata` | Passed on to Muster (`contributor` and up): answer a step `{edgeId}`, tick a task `{nodeId, index, done}`, report the assets and what was done `{site, marks, names, log}` | | `PUT /api/incidents/{IS id}` | Replaces the incident of an IS (`contributor` and up, no proposal): marks are `compromised`, `suspected` or `contained` | | `PUT /api/services` | Replaces the common catalogue of Internet services: `{"services": [...]}` | +| `PUT /api/risk` | Replaces the risk settings shared by every IS: `{"risk": {matrix, baselines, custom, threats}}` | | `GET /api/history` | Latest changes (`?before=REV&limit=N`); `GET /api/history/{rev}`: the before/after details | | `GET /api/state?at=REV` | The map as it was right after version REV | | `POST /api/rollback` | `{"rev": N}`: puts the map back to version N (approver) | diff --git a/docs/api.html b/docs/api.html index 4310a6e..434106f 100644 --- a/docs/api.html +++ b/docs/api.html @@ -109,13 +109,13 @@

Account

The map

-

The map is four parts: the IS documents (si, by id), the assets (by id), the links between IS (wan) and the shared Internet services (services). Their content is in Data format. Every change makes a new revision and an entry in the history.

+

The map is four parts: the IS documents (si, by id), the assets (by id), the links between IS (wan), the shared Internet services (services) and the risk settings (risk). Their content is in Data format. Every change makes a new revision and an entry in the history.

- + - + @@ -123,7 +123,8 @@

The map

- + +
RouteRoleRequest → answer
GET /api/stateviewer→ {si, assets, wan, services, rev, updatedAt}
GET /api/stateviewer→ {si, assets, wan, services, risk, rev, updatedAt}
GET /api/state?at=REVviewer→ the same, as it was right after revision REV
GET /api/exportviewer→ an export file (Content-Disposition: attachment): {format: "strata", version: 3, exportedAt, si, assets, wan, services}
GET /api/exportviewer→ an export file (Content-Disposition: attachment): {format: "strata", version: 3, exportedAt, si, assets, wan, services, risk}
GET /api/si/{id}, GET /api/assets/{id}viewer→ the document, or 404
PUT /api/si/{id}approverthe IS document → {ok, rev}. Creates or replaces it whole.
DELETE /api/si/{id}approver→ {ok, rev}. Its assets stay.
DELETE /api/assets/{id}approver→ {ok, rev}
PUT /api/wanapprover{links: [...]} → {ok, rev}. Replaces all the links.
PUT /api/servicesapprover{services: [...]} → {ok, rev}. Replaces the shared catalogue.
POST /api/importapprover{si, assets, wan?, services?} (an export file works as is) → {ok, rev}. Replaces the whole map; a backup is taken first.
PUT /api/riskapprover{risk: {...}} → {ok, rev}. Replaces the risk settings shared by every IS (see Data format).
POST /api/importapprover{si, assets, wan?, services?, risk?} (an export file works as is) → {ok, rev}. Replaces the whole map; a backup is taken first.

Documents are replaced whole: to change one field, read the document, change it, send it back. To add a flow or a VLAN, change the IS document (si.flows, si.vlans).

@@ -138,14 +139,14 @@

History

- +
RouteRoleRequest → answer
GET /api/history?before=REV&limit=Nviewer→ {rev, oldest, entries}, newest first, older than before if given; limit 120 by default, 500 at most. Each entry: {rev, at, user, batch, label, kind, id, op, name, site}; kind: si, assets, wan, services or all; op: created, updated or deleted. oldest: the oldest revision the history still holds.
GET /api/history?before=REV&limit=Nviewer→ {rev, oldest, entries}, newest first, older than before if given; limit 120 by default, 500 at most. Each entry: {rev, at, user, batch, label, kind, id, op, name, site}; kind: si, assets, wan, services, risk or all; op: created, updated or deleted. oldest: the oldest revision the history still holds.
GET /api/history/{rev}viewer→ {rev, entries}: the changes of that revision, each with its before and after document
POST /api/rollbackapprover{rev} → {ok, rev}. Puts the map back as it was at rev, as a new revision (nothing is erased); a backup is taken first.

Proposals

-

A proposal is a set of changes that an approver merges into the map, or not. Its changes are {si: {id: doc}, assets: {id: doc}, wan?: [...], services?: [...]}, where a document set to null deletes it. Its status goes draft → submitted → approved or rejected; a submitted proposal can be withdrawn back to draft, and editing a rejected one makes it a draft again.

+

A proposal is a set of changes that an approver merges into the map, or not. Its changes are {si: {id: doc}, assets: {id: doc}, wan?: [...], services?: [...], risk?: {...}}, where a document set to null deletes it. Its status goes draft → submitted → approved or rejected; a submitted proposal can be withdrawn back to draft, and editing a rejected one makes it a draft again.

@@ -239,7 +240,8 @@

Data format

"si": { "<IS id>": { IS document } }, "assets": { "<asset id>": { asset document } }, "wan": [ { link } ], - "services": [ { Internet service } ] + "services": [ { Internet service } ], + "risk": { risk settings } }

The export of a single IS (Export this IS (JSON)) adds "scope": "si" and holds that IS, its assets and the shared services. The interface imports it by replacing that IS only; POST /api/import always replaces the whole map, so to load one IS from a script, send its documents with PUT /api/si/{id} and PUT /api/assets/{id}.

@@ -255,6 +257,7 @@

IS document

+
RouteRoleRequest → answer
contacts[{name, role, phone, email, dispo, src?}], who to call for the IS
business[{id, name, crit, owner, notes, assets}]: business services and the assets they run on
servicesInternet services used by this IS only, as below
landscape{actors: {id: 0-3}}: how relevant each risk source is to this IS (crime-gain, amateur, activist, state-spy, state-prepo, competitor, insider, supplier); missing: the default
@@ -271,6 +274,18 @@

Asset document

apps[{name, version, ports, src?}], software and the ports it listens on contactsAs for the IS extIds in connected tools: {"glpi": "Computer/12", "cyberwatch": 101} + riskThe treatment of its risks: {threats: {threatId: {reqs: {"baselineId/reqId": "applied"|"planned"|"na"}, decision?, note?}}, excluded?: [threatIds], added?: [threatIds]}; decision: accept, transfer or avoid (missing: treat) + + + +

Risk settings

+
+ + + + + +
FieldContent
matrix{likelihood: [labels], impact: [labels], cells: [[0-3]], accept: 0-3, lEdges?, iEdges?}: 3 to 5 levels each way, lowest first; cells[l][i]: low, moderate, high or critical; accept: the highest level acceptable without a decision. Missing or out of shape: the 4×4 default
baselinesIds of the enabled baselines: anssi, nist-csf, cis-v8, iso27001, custom:…. Missing: ANSSI and every custom one
customCustom baselines: [{id, name, version?, requirements: [{id, ref?, title, text?, threats: [[threatId, share 0.05-0.9, "likelihood"|"impact"]]}]}]
threats{custom: [{id, name, desc, base 1-4, severity 1-4, when, attack?, actors?}], disabled: [threatIds]}. when: types, exposure, critMin, ports, kev, vulnTitle, role, os (patterns), outbound, svcCat; all must hold, or one with any: true

src on a vulnerability, application or contact names the connector it came from; entries without one were typed by hand.

diff --git a/package.json b/package.json index de9dbf5..513d00e 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "scripts": { "vendor": "node scripts/vendor.mjs", "start": "node server/server.js", - "test": "node --test tests/api.test.mjs tests/analysis.test.mjs tests/incident.test.mjs tests/muster.test.mjs tests/secrets.test.mjs tests/signin.test.mjs tests/hardening.test.mjs tests/readonly.test.mjs tests/modules.test.mjs tests/sso.test.mjs", + "test": "node --test tests/api.test.mjs tests/analysis.test.mjs tests/incident.test.mjs tests/risk.test.mjs tests/muster.test.mjs tests/secrets.test.mjs tests/signin.test.mjs tests/hardening.test.mjs tests/readonly.test.mjs tests/modules.test.mjs tests/sso.test.mjs", "test:e2e": "node --test tests/e2e.mjs", "setup": "npm ci && npm run vendor", "build:online": "node scripts/build-online.mjs" diff --git a/public/app.css b/public/app.css index 3c9b40f..dea6e4d 100644 --- a/public/app.css +++ b/public/app.css @@ -103,7 +103,7 @@ body.readonly .edit-only{display:none!important} .seg.three{grid-template-columns:repeat(3,1fr)} .seg.four{grid-template-columns:repeat(4,1fr)} .seg button{background:none;border:0;padding:8px 0;font-size:11px;color:var(--muted);border-right:1px solid var(--line);min-height:34px} -.seg.two button,.seg.three button{font-size:12px} +.seg.two button,.seg.three button,.seg.four button{font-size:12px} .seg button:last-child{border-right:0} .seg button[aria-pressed="true"]{background:var(--fg);color:var(--panel)} .row{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:4px 0} @@ -560,3 +560,60 @@ button.chip:hover{border-color:var(--accent);color:var(--accent)} .ai-p pre{margin:0;border-radius:0} .ai-map{border-collapse:collapse;width:100%;font-size:12px} .ai-map td{border-top:1px solid var(--line);padding:3px 6px} + +/* Risk register */ +.rmx-pair{display:flex;flex-wrap:wrap;gap:18px;margin:10px 0} +.rmx-f{margin:0} +.rmx-f figcaption{margin-bottom:6px} +.rmx{border-collapse:separate;border-spacing:3px;font-size:11px} +.rmx th{font-weight:500;color:var(--muted);text-align:right;padding:0 6px 0 0;max-width:90px;line-height:1.2} +.rmx th[scope=col]{text-align:center;padding:4px 0 0;width:44px} +.rmx td{width:44px;height:30px;text-align:center;font-family:var(--f-mono);font-weight:600;border-radius:3px;color:var(--fg)} +.rmx td.lv-low{background:color-mix(in srgb,var(--low) 30%,transparent)} +.rmx td.lv-med{background:color-mix(in srgb,var(--med) 34%,transparent)} +.rmx td.lv-high{background:color-mix(in srgb,var(--high) 38%,transparent)} +.rmx td.lv-crit{background:color-mix(in srgb,var(--crit) 42%,transparent)} +.rmx td[data-cell]{cursor:pointer} +.rmx td[data-cell]:hover,.rmx td.on{outline:2px solid var(--accent);outline-offset:-2px} +.rmx-ax{display:flex;justify-content:space-between;margin:2px 0 0;font-size:10.5px;color:var(--muted)} +.rmx.edit td{width:auto;min-width:46px;height:30px;padding:0} +.rmx.edit td button{width:100%;height:100%;border:0;background:none;font:inherit;font-size:10.5px;color:inherit;cursor:pointer} +.rmx.edit input{width:76px;font:inherit;font-size:11px;padding:2px 4px;border:1px solid var(--line);border-radius:3px;background:var(--panel);color:var(--fg)} +.rmx.edit th[scope=col] input{width:100%;min-width:0;box-sizing:border-box} +#det .rmx td{width:34px;height:22px} +#det .rmx th{font-size:9.5px;max-width:70px} +#det .rmx th[scope=col]{width:34px;overflow-wrap:normal} +#det .rmx-pair{gap:10px} +#det .rmx.edit td{width:auto} +#det .rmx.edit th{max-width:none} +li.rk{display:flex;align-items:center;gap:10px} +li.rk>button{flex:1;min-width:0} +.rk-lv{display:flex;align-items:center;gap:4px;flex-shrink:0} +.rk-lv .ar{color:var(--muted)} +.rk-ex,.rk-why,.rs-new{margin:10px 0;font-size:12.5px} +.rk-ex summary,.rk-why summary,.rs-new summary{cursor:pointer;color:var(--muted)} +.rk-add{margin-top:10px} +.rk-b{margin:14px 0 4px;font-size:12px;font-weight:600} +li.req{display:flex;align-items:flex-start;gap:10px;font-size:12.5px;padding:6px 0;border-bottom:1px solid var(--line)} +li.req>div{flex:1;min-width:0} +li.req small{display:block;color:var(--muted);margin-top:2px} +li.req select{flex-shrink:0;max-width:130px} +li.req.st-applied{box-shadow:inset 3px 0 0 var(--low);padding-left:8px} +li.req.st-planned{box-shadow:inset 3px 0 0 var(--med);padding-left:8px} +li.req.st-na{opacity:.6} +.rk-tools{flex-direction:row;flex-wrap:wrap} +.rk-tools .btn{width:auto} +.rk-tab{border-collapse:collapse;width:100%;max-width:1100px;font-size:12.5px;margin-top:8px} +.rk-tab th{text-align:left;font-weight:500;color:var(--muted);padding:6px 8px;border-bottom:1px solid var(--line)} +.rk-tab td{padding:6px 8px;border-bottom:1px solid var(--line);vertical-align:top} +.rk-tab td small{display:block;color:var(--muted)} +.rk-tab tbody tr{cursor:pointer} +.rk-tab tbody tr:hover,.rk-tab tbody tr:focus{background:color-mix(in srgb,var(--accent) 8%,transparent);outline:none} +.rk-tab tr.open td:first-child{box-shadow:inset 3px 0 0 var(--crit)} +.rk-src li,.rs-bl li,.rs-th li{display:flex;align-items:center;gap:10px;padding:6px 0;border-bottom:1px solid var(--line);font-size:12.5px} +.rk-src li>div,.rs-bl li>label,.rs-th li>label{flex:1;min-width:0} +.rk-src small,.rs-bl small,.rs-th small{display:block;color:var(--muted)} +.rs-bl label,.rs-th label{align-items:flex-start} +.rs-dims{display:flex;flex-wrap:wrap;gap:12px;font-size:12.5px;margin:6px 0} +.rs-mx{overflow-x:auto} +@media (max-width:760px){.rk-tab th:nth-child(5),.rk-tab td:nth-child(5),.rk-tab th:nth-child(7),.rk-tab td:nth-child(7){display:none}} diff --git a/public/app.js b/public/app.js index 6907dd5..03b313e 100644 --- a/public/app.js +++ b/public/app.js @@ -26,7 +26,10 @@ const F=(id,title,cvss,sev)=>Object.assign({id,title,cvss:cvss==null?null:cvss,s const TYPE_LABEL={server:'Server',dc:'Domain controller',db:'Database',hypervisor:'Hypervisor / storage',firewall:'Firewall',gateway:'VPN gateway',router:'Router / L3 core',switch:'Switch / load balancer',workstation:'Workstation',printer:'Printer',phone:'IP phone',ap:'Wi-Fi access point',camera:'IP camera',plc:'PLC',iot:'IoT device'}; // Interconnection equipment: flows can be routed through these const INTERCO=new Set(['firewall','router','switch','gateway']); -const SA=StrataAnalysis,IR=StrataIncident; +const SA=StrataAnalysis,IR=StrataIncident,RK=StrataRisk; +// Baselines shipped with Strata (baselines.js), and the risk settings shared by every IS, read at each compile +const BASELINES=()=>(typeof StrataBaselines!=='undefined'&&Array.isArray(StrataBaselines))?StrataBaselines:[]; +let RS=null; // Colours of the "Per flow" mode: --f0 to --f9 in app.css const FLOW_PAL=10; // Internet endpoints: the Internet as a whole, or a named service (ESET updates, Ubuntu mirrors…) as "svc:" @@ -333,16 +336,16 @@ function buildDemo(){ /* ================= Storage ================= 'api' : served by the Strata server (shared data, live updates over SSE) 'local' : page opened on its own; data kept in this browser only */ -let raw={si:{},assets:{},wan:[],services:[]}; +let raw={si:{},assets:{},wan:[],services:[],risk:{}}; const LS_KEY='strata-v1'; // The live map, then what is shown: the live map, a draft applied over it, a proposal under review, // or an older version (read-only) let liveRaw=raw; function overlay(base,ch){ - const o={si:Object.assign({},base.si),assets:Object.assign({},base.assets),wan:base.wan,services:base.services}; + const o={si:Object.assign({},base.si),assets:Object.assign({},base.assets),wan:base.wan,services:base.services,risk:base.risk||{}}; if(!ch)return o; ['si','assets'].forEach(k=>Object.entries(ch[k]||{}).forEach(([id,doc])=>{if(doc==null)delete o[k][id];else o[k][id]=doc;})); - if(ch.wan)o.wan=ch.wan;if(ch.services)o.services=ch.services; + if(ch.wan)o.wan=ch.wan;if(ch.services)o.services=ch.services;if(ch.risk)o.risk=ch.risk; return o; } const Store={ @@ -363,7 +366,7 @@ const Store={ await this.pull();this.listen();return; } this.mode='local'; - try{const s=localStorage.getItem(LS_KEY);if(s){const o=JSON.parse(s);liveRaw={si:o.si||{},assets:o.assets||{},wan:o.wan||[],services:o.services||[]};}}catch(e){} + try{const s=localStorage.getItem(LS_KEY);if(s){const o=JSON.parse(s);liveRaw={si:o.si||{},assets:o.assets||{},wan:o.wan||[],services:o.services||[],risk:o.risk||{}};}}catch(e){} this.loaded=true;this.applyView(); }, applyView(delay){ @@ -375,7 +378,7 @@ const Store={ const r=await fetch('api/state',{cache:'no-store',credentials:'same-origin'}); if(!r.ok)throw new Error('HTTP '+r.status); const s=await r.json(); - liveRaw={si:s.si||{},assets:s.assets||{},wan:Array.isArray(s.wan)?s.wan:[],services:Array.isArray(s.services)?s.services:[]};this.rev=s.rev||0; + liveRaw={si:s.si||{},assets:s.assets||{},wan:Array.isArray(s.wan)?s.wan:[],services:Array.isArray(s.services)?s.services:[],risk:s.risk&&typeof s.risk==='object'?s.risk:{}};this.rev=s.rev||0; this.loaded=true;this.applyView(this.bulk?null:0); }catch(e){toast('Could not read the saved data. Check that the server is running, then reload.',true);} }, @@ -402,20 +405,20 @@ const Store={ return j; }, saveLocal(){try{localStorage.setItem(LS_KEY,JSON.stringify(liveRaw));}catch(e){toast('This browser refused to save the data (storage full or disabled).',true);}}, - // kind: si | assets | wan | services ; value null = delete + // kind: si | assets | wan | services | risk ; value null = delete async write(kind,id,value){ if(this.view==='preview'||this.view==='review'){toast(this.view==='preview'?'You are looking at an older version: it is read-only.':'A proposal under review is read-only.',true);throw new Error('readonly');} if(this.view==='draft')return this.writeDraft(kind,id,value); if(!this.liveWrite){toast(this.features.proposals?'Your role cannot change the map directly: start a proposal (Proposals › New).':'You have read-only access.',true);throw new Error('readonly');} const local=()=>{ if(kind==='si'||kind==='assets'){liveRaw[kind]=Object.assign({},liveRaw[kind]);if(value==null)delete liveRaw[kind][id];else liveRaw[kind][id]=clone(value);} - else liveRaw[kind]=clone(value||[]); + else liveRaw[kind]=clone(value||(kind==='risk'?{}:[])); }; if(this.mode==='local'){local();this.saveLocal();this.applyView(0);return;} - const url=kind==='wan'?'api/wan':kind==='services'?'api/services':`api/${kind}/${encodeURIComponent(id)}`; + const url=kind==='wan'?'api/wan':kind==='services'?'api/services':kind==='risk'?'api/risk':`api/${kind}/${encodeURIComponent(id)}`; try{ if(value==null&&(kind==='si'||kind==='assets'))await this.api('DELETE',url); - else await this.api('PUT',url,kind==='wan'?{links:value}:kind==='services'?{services:value}:value); + else await this.api('PUT',url,kind==='wan'?{links:value}:kind==='services'?{services:value}:kind==='risk'?{risk:value||{}}:value); local();this.applyView(this.bulk?null:0); }catch(e){ if(e.status===403)toast(e.message||'You cannot change this.',true); @@ -430,7 +433,7 @@ const Store={ if(kind==='si'||kind==='assets'){ // a document brought back to its live state leaves the change set if(JSON.stringify(liveRaw[kind][id]??null)===JSON.stringify(value??null))delete ch[kind][id];else ch[kind][id]=value==null?null:clone(value); - }else{if(JSON.stringify(liveRaw[kind]||[])===JSON.stringify(value||[]))delete ch[kind];else ch[kind]=clone(value||[]);} + }else{const e=kind==='risk'?{}:[];if(JSON.stringify(liveRaw[kind]||e)===JSON.stringify(value||e))delete ch[kind];else ch[kind]=clone(value||e);} this.applyView(this.bulk?null:0); clearTimeout(this._dt);this._dt=setTimeout(()=>this.saveDraft(),this.bulk?900:350); return Promise.resolve(); @@ -446,6 +449,7 @@ const Store={ delAsset(id){return this.write('assets',id,null);}, putWan(links){return this.write('wan',null,links);}, putServices(list){return this.write('services',null,list);}, + putRisk(doc){return this.write('risk',null,doc);}, async many(tasks,label){ this.bulk=true;this.batch={id:'b'+Date.now().toString(36)+Math.random().toString(36).slice(2,6),label};let done=0;const total=tasks.length; toast(`${label}: 0 / ${total}`,false,true); @@ -456,7 +460,7 @@ const Store={ }; // Replace the whole map (demo, import, delete everything) in one request async function replaceAll(data,label){ - const next={si:clone(data.si||{}),assets:clone(data.assets||{}),wan:clone(data.wan||[]),services:clone(data.services||[])}; + const next={si:clone(data.si||{}),assets:clone(data.assets||{}),wan:clone(data.wan||[]),services:clone(data.services||[]),risk:clone(data.risk||{})}; if(Store.view){toast('Leave the draft, review or older version first.',true);return;} if(!Store.liveWrite){toast('You cannot replace the map with your role.',true);return;} if(Store.mode==='local'){liveRaw=next;Store.saveLocal();Store.applyView(0);toast(`${label}: done.`);return;} @@ -514,6 +518,7 @@ const maxExp=(a,b)=>EXP[a].rank>=EXP[b].rank?a:b; const epssOf=v=>{if(v==null||v==='')return null;const n=parseFloat(String(v).trim().replace(/,/g,'.'));return isFinite(n)&&n>=0?(n>1?Math.min(1,n/100):n):null;}; function compile(){ const list=Object.entries(raw.si).map(([id,d])=>({id,d})).sort((a,b)=>(a.d.order||0)-(b.d.order||0)||String(a.d.name).localeCompare(String(b.d.name))); + RS=RK.settings(raw.risk,BASELINES()); SITES=list.map(({id,d},si)=>{ const s={id,name:d.name||'Untitled IS',kind:d.kind||'',order:d.order||0,planche:pad(si+1),contacts:(d.contacts||[]).map(c=>Object.assign({},c,{role:roleEn(c.role)})),raw:d}; s.zones=(d.zones&&d.zones.length?d.zones:[{id:'z-def',name:'Main zone'}]).map(z=>({id:z.id,name:z.name,vlans:[]})); @@ -569,6 +574,12 @@ function compile(){ // Attack paths: the critical assets (their own criticality, or that of a business service they // would hit) and what an attacker coming from the Internet could reach s.bizCrit=bizCrit;s.critIds=s.assets.filter(a=>a.crit===3||bizCrit[a.id]===3).map(a=>a.id);s.atkOut=SA.blastRadius(s,SA.outside(s)); + // Risk register: the threats that apply to each asset, scored on the matrix of the risk settings + s.landscape=d.landscape&&typeof d.landscape==='object'?d.landscape:{};s.threats={};s.register=[]; + s.assets.forEach(a=>{s.threats[a.id]=RK.assess(s,a,{settings:RS,baselines:BASELINES(),landscape:s.landscape,hops:s.expo[a.id],bizCrit:bizCrit[a.id],labels:TYPE_LABEL}); + s.threats[a.id].forEach(r=>{if(!r.excluded)s.register.push(Object.assign({asset:a},r));});}); + const lv=c=>RK.LEVELS.indexOf(c.level); + s.register.sort((x,y)=>lv(y.residual)-lv(x.residual)||y.pResidual*y.iResidual-x.pResidual*x.iResidual||x.asset.name.localeCompare(y.asset.name)); s.usedSvc=new Set(s.flows.flatMap(f=>[f.src,f.dst]).filter(id=>id!=='internet'&&isNet(id))); const cnt=k=>s.assets.filter(a=>a.exp===k).length; s.stats={vlans:s.vlans.length,assets:s.assets.length,crit:s.assets.reduce((n,a)=>n+a.vulns.filter(v=>v.sev==='crit').length,0), @@ -1119,7 +1130,7 @@ function placeSelRing(){ const det=$('#det'); const tag=k=>`${SEV[k].label}`; const xtag=k=>`${EXP[k].label}`; -function openDet(html,panel){det.classList.toggle('wide',panel==='incident'||panel==='ai');det.innerHTML=html;det.hidden=false;det.scrollTop=0;document.body.classList.add('has-det');const wasAtk=state.panel==='attack'&&panel!=='attack';state.panel=panel;renderEmpty();syncUI();placeLens();if(wasAtk&&state.view==='site')refresh();} +function openDet(html,panel){det.classList.toggle('wide',panel==='incident'||panel==='ai'||panel==='risksettings');det.innerHTML=html;det.hidden=false;det.scrollTop=0;document.body.classList.add('has-det');const wasAtk=state.panel==='attack'&&panel!=='attack';state.panel=panel;renderEmpty();syncUI();placeLens();if(wasAtk&&state.view==='site')refresh();} function closeDet(){const wasFlow=state.panel==='flow'||state.panel==='attack';det.hidden=true;document.body.classList.remove('has-det');state.panel=null;state.attackHl=null;renderEmpty();syncUI();placeLens();if(wasFlow&&state.view==='site')refresh();} function contactsHtml(list){ return `
    ${list.map(c=>`
  • ${esc(c.name||'Contact')}${esc(c.role||'')}${c.dispo?' · '+esc(c.dispo):''}
    @@ -1189,6 +1200,7 @@ function showAsset(a){

    Business services impacted · ${impactOf(a).length}

    ${impactHtml(a)} +

    Risks · ${(SITE.threats[a.id]||[]).filter(r=>!r.excluded).length}

    ${assetRiskHtml(a)}

    Inside · ${plural((a.apps||[]).length,'application')}

    ${insideHtml(a)}

    Incident contacts

    ${contacts} ${a.notes?`

    Notes

    ${esc(a.notes)}

    `:''} @@ -1574,7 +1586,7 @@ ${afTable(['Name','Role','Phone','Email','Availability'],s.contacts.map(c=>[esc( ${afTable(['Asset','Name','Role','Phone','Email','Availability'],ASSETS.flatMap(a=>a.contacts.filter(c=>c.name||c.phone||c.email).map((c,i)=>[i?'':`${esc(a.name)}`,esc(c.name),esc(c.role),`${esc(c.phone||'')}`,esc(c.email||''),esc(c.dispo||'')])))} ${H('hist')} -${hist?afTable(['Version','Date','By','Change'],hist.map(h=>[`v${esc(h.rev)}`,esc(new Date(h.at).toLocaleString()),esc(h.user||'—'),esc(h.label||`${{si:'IS',assets:'asset',wan:'inter-IS links',services:'Internet services',all:'whole map'}[h.kind]||h.kind} ${h.name?'“'+h.name+'” ':''}${h.op||''}`)])):'

    No history: this map is kept in a browser only. On a Strata server, every change is recorded with its author and date, and listed here.

    '} +${hist?afTable(['Version','Date','By','Change'],hist.map(h=>[`v${esc(h.rev)}`,esc(new Date(h.at).toLocaleString()),esc(h.user||'—'),esc(h.label||`${{si:'IS',assets:'asset',wan:'inter-IS links',services:'Internet services',risk:'risk settings',all:'whole map'}[h.kind]||h.kind} ${h.name?'“'+h.name+'” ':''}${h.op||''}`)])):'

    No history: this map is kept in a browser only. On a Strata server, every change is recorded with its author and date, and listed here.

    '} ${H('method')}

    Source. Everything in this file comes from the Strata map of the IS: entered by hand, imported, or read by the connectors (Cyberwatch, GLPI, phpIPAM, Palo Alto) and approved before publication. A flow missing from the map is missing here.

    @@ -1945,7 +1957,7 @@ function confirmArm(key){ } document.addEventListener('click',e=>{const b=e.target.closest('[data-act]');if(b&&!b.closest('#det'))act(b.dataset.act);}); async function exportJson(){ - const data=JSON.stringify({format:'strata',version:3,exportedAt:new Date().toISOString(),si:raw.si,assets:raw.assets,wan:raw.wan,services:raw.services||[]},null,2); + const data=JSON.stringify({format:'strata',version:3,exportedAt:new Date().toISOString(),si:raw.si,assets:raw.assets,wan:raw.wan,services:raw.services||[],risk:raw.risk||{}},null,2); await saveFile(`strata-${today()}.json`,'application/json',data); } $('#io').addEventListener('change',e=>{ @@ -1960,10 +1972,11 @@ $('#io').addEventListener('change',e=>{ Object.entries(ch.si).forEach(([id,d])=>tasks.push(()=>Store.putSite(id,d))); Object.entries(ch.assets).forEach(([id,d])=>tasks.push(()=>d?Store.putAsset(id,d):Store.delAsset(id))); if(ch.services)tasks.push(()=>Store.putServices(ch.services)); + if(ch.risk)tasks.push(()=>Store.putRisk(ch.risk)); if(!tasks.length){toast('This file is identical to the map.');return;} await Store.many(tasks,`Import of IS ${Object.values(o.si)[0].name||''}`);return; } - await replaceAll({si:o.si,assets:o.assets,wan:Array.isArray(o.wan)?o.wan:[],services:Array.isArray(o.services)?o.services:[]},'Import'); + await replaceAll({si:o.si,assets:o.assets,wan:Array.isArray(o.wan)?o.wan:[],services:Array.isArray(o.services)?o.services:[],risk:o.risk&&typeof o.risk==='object'?o.risk:{}},'Import'); }; r.readAsText(f); }); @@ -2614,7 +2627,7 @@ function placeLens(){ addEventListener('resize',placeLens); function renderLens(){ if(state.view!=='site'||state.lens==='physical')return; - if(state.lens==='app')renderAppLens();else renderBizLens(); + if(state.lens==='app')renderAppLens();else if(state.lens==='risk')renderRiskLens();else renderBizLens(); placeLens(); } const worstOf=ids=>ids.reduce((m,id)=>byId[id]&&SEV[byId[id].sev].rank>SEV[m].rank?byId[id].sev:m,'none'); @@ -2781,13 +2794,14 @@ function computeDiff(){ if(b){const f=changedFields(b,doc,['vlans','flows','services']);if(f.length)items.push({kind:'site',op:'modified',id:sid,site:sid,label:'IS '+doc.name,fields:f});}}); if(ch.services)diffList(liveRaw.services,ch.services,x=>x.name,'service',null,{},items); if(ch.wan)items.push({kind:'wan',op:'modified',label:'Inter-IS links'}); + if(ch.risk)items.push({kind:'risk',op:'modified',label:'Risk settings'}); DIFF={A,F,V,items}; } const DIFF_COL={added:'--low',modified:'--med',removed:'--crit'}; -const KIND_LBL={asset:'Asset',flow:'Flow',vlan:'VLAN',site:'IS',service:'Internet service',wan:'WAN'}; +const KIND_LBL={asset:'Asset',flow:'Flow',vlan:'VLAN',site:'IS',service:'Internet service',wan:'WAN',risk:'Risk'}; function diffHtml(){ if(!DIFF||!DIFF.items.length)return '

    No change yet. Edit the map (2D diagram, sheets, forms): every change goes into this draft.

    '; - const order={site:0,vlan:1,asset:2,flow:3,service:4,wan:5}; + const order={site:0,vlan:1,asset:2,flow:3,service:4,wan:5,risk:6}; return `
      ${DIFF.items.slice().sort((a,b)=>order[a.kind]-order[b.kind]).map(it=>`
    • ${it.op}${KIND_LBL[it.kind]}${it.kind==='asset'&&it.op!=='removed'?``:it.kind==='flow'&&it.op!=='removed'?``:esc(it.label)}${it.fields&&it.fields.length?`${esc(it.fields.join(', '))}`:''}
    • `).join('')}
    `; } let PROPS=[]; @@ -2827,7 +2841,7 @@ function proposalForm(){ let o;try{o=JSON.parse(await f.text());}catch(e){return formErr('This file is not valid JSON.');} if(!o||typeof o.si!=='object'||typeof o.assets!=='object')return formErr('Unexpected format: a Strata export has the “si” and “assets” keys.'); changes=changesFromFile(o);const ks=Object.keys(o.si);if(ks.length===1)siteId=ks[0]; - if(!Object.keys(changes.si).length&&!Object.keys(changes.assets).length&&!changes.services)return formErr('This file is identical to the map: nothing to propose.'); + if(!Object.keys(changes.si).length&&!Object.keys(changes.assets).length&&!changes.services&&!changes.risk)return formErr('This file is identical to the map: nothing to propose.'); } try{const j=await Store.api('POST','api/proposals',{title,description:$('#fDesc').value.trim(),siteId,changes,source:from}); onSave=null;toast(from==='file'?'Proposal created from the file: check it, then submit it.':'Draft opened: your changes now go into it.');enterProp(j.proposal,'draft');} @@ -2841,6 +2855,7 @@ function changesFromFile(o){ Object.entries(o.assets||{}).forEach(([id,a])=>{if(a&&sites.includes(a.site)&&J(liveRaw.assets[id])!==J(a))ch.assets[id]=a;}); Object.entries(liveRaw.assets).forEach(([id,a])=>{if(sites.includes(a.site)&&!(id in (o.assets||{})))ch.assets[id]=null;}); if(Array.isArray(o.services)&&J(o.services)!==J(liveRaw.services||[]))ch.services=o.services; + if(o.risk&&typeof o.risk==='object'&&J(o.risk)!==J(liveRaw.risk||{}))ch.risk=o.risk; return ch; } async function openProposal(id,keepView){ @@ -2918,7 +2933,7 @@ async function showHistory(more){ const siteOnly=state.view==='site'&&!HIST.all&&SITE; const list=HIST.entries.filter(h=>!siteOnly||h.site===SITE.id); const groups=[];list.forEach(h=>{const g=groups[groups.length-1];if(g&&g.batch===h.batch&&g.rev===h.rev||g&&g.batch===h.batch&&h.batch&&!/^r\d+$/.test(h.batch))g.items.push(h);else groups.push({batch:h.batch,rev:h.rev,at:h.at,user:h.user,label:h.label,items:[h]});}); - const KL={si:'IS',assets:'asset',wan:'inter-IS links',services:'Internet services',all:'whole map'}; + const KL={si:'IS',assets:'asset',wan:'inter-IS links',services:'Internet services',risk:'risk settings',all:'whole map'}; const sum=g=>g.label||(g.items.length===1?`${KL[g.items[0].kind]} ${g.items[0].name?'“'+g.items[0].name+'” ':''}${g.items[0].op}`:`${g.items.length} changes: ${[...new Set(g.items.map(h=>h.name).filter(Boolean))].slice(0,4).join(', ')}`); const canRestore=Store.liveWrite&&!Store.view; openDet(`
    Collaboration

    History

    Version ${HIST.rev}${siteOnly?` · IS ${esc(SITE.name)}`:' · whole map'}

    @@ -2933,7 +2948,7 @@ async function showHistory(more){ async function previewVersion(rev){ let s;try{s=await Store.api('GET','api/state?at='+rev);}catch(e){toast(e.message,true);return;} const g=HIST.entries.find(h=>h.rev===rev)||{}; - Store.view='preview';Store.prop=null;Store.preview={rev,at:g.at,user:g.user,raw:{si:s.si||{},assets:s.assets||{},wan:s.wan||[],services:s.services||[]}}; + Store.view='preview';Store.prop=null;Store.preview={rev,at:g.at,user:g.user,raw:{si:s.si||{},assets:s.assets||{},wan:s.wan||[],services:s.services||[],risk:s.risk||{}}}; Store.applyView(0);renderModeBar(); pendingAfterData=()=>{if(state.view==='site'&&!siteById[state.siteId])backToOverview();closeDet();}; } @@ -3546,6 +3561,238 @@ det.addEventListener('change',e=>{ if(t.hasAttribute('data-ai-answer')){AI_ANSWER=t.value;showPrompts(a,true);} }); +/* ================= Risk register ================= */ +// The threats that apply to each asset (its exposure, criticality, ports, system, vulnerabilities and the +// threat landscape of its IS), placed on the risk matrix of the settings before and after the requirements +// of the enabled baselines. Treatments are saved on the asset (field risk), settings in the shared document risk. +const lvTag=l=>`${RK.LEVEL_LBL[l]}`; +const REQ_ST={'':'Not applied',planned:'Planned',applied:'Applied',na:'Not applicable'}; +const DECISION={treat:'Treat (apply requirements)',accept:'Accept the risk',transfer:'Transfer (insurance, contract)',avoid:'Avoid (remove the cause)'}; +const pctR=x=>Math.round(x*100)+'%'; +// A risk matrix: likelihood upwards, impact rightwards, a count in each cell +function matrixHtml(M,counts,{click,on,title}={}){ + const n=M.likelihood.length,m=M.impact.length;let h=`
    ${title?`
    ${esc(title)}
    `:''}`; + for(let l=n-1;l>=0;l--){h+=``; + for(let i=0;i${c||''}`;} + h+='';} + return h+`${M.impact.map(x=>``).join('')}
    ${esc(M.likelihood[l])}
    ${esc(x)}

    ↑ LikelihoodImpact →

    `; +} +const gridOf=(rows,k)=>{const M=RS.matrix,g=M.cells.map(r=>r.map(()=>0));rows.forEach(r=>g[r[k].l][r[k].i]++);return g;}; +const reqCount=r=>{const ap=r.requirements.filter(x=>x.status==='applied').length,pl=r.requirements.filter(x=>x.status==='planned').length;return {ap,pl,n:r.requirements.filter(x=>x.status!=='na').length};}; +function riskRow(r,withAsset){ + const c=reqCount(r); + return `
  • + ${lvTag(r.inherent.level)}${r.residual.level!==r.inherent.level||r.inherent.l!==r.residual.l||r.inherent.i!==r.residual.i?`→${lvTag(r.residual.level)}`:''}
  • `; +} +// The asset sheet: its own matrix and its risks +function assetRiskHtml(a){ + const all=SITE.threats[a.id]||[],rows=all.filter(r=>!r.excluded).map(r=>Object.assign({asset:a},r)),ex=all.filter(r=>r.excluded); + const left=RK.THREATS.concat(RS.customThreats).filter(t=>!RS.disabled.has(t.id)&&!all.some(r=>r.threat.id===t.id)); + if(!rows.length&&!ex.length)return `

    No threat of the catalogue applies to this asset with what the map says about it (type, exposure, criticality, ports, system, vulnerabilities).

    ${addThreatHtml(a,left)}`; + const over=rows.filter(r=>!r.acceptable).length; + return `
    ${matrixHtml(RS.matrix,gridOf(rows,'inherent'),{title:'Before requirements'})}${matrixHtml(RS.matrix,gridOf(rows,'residual'),{title:'With the requirements applied'})}
    +

    ${over?`${over} ${over===1?'risk is':'risks are'} above the acceptance threshold (${RK.LEVEL_LBL[RK.LEVELS[RS.matrix.accept]]}) with no decision to accept it.`:'Every risk is at or below the acceptance threshold, or accepted.'} Open a risk to apply requirements.

    +
      ${rows.map(r=>riskRow(r,false)).join('')}
    + ${ex.length?`
    ${plural(ex.length,'threat')} set aside as not relevant
      ${ex.map(r=>`
    • `).join('')}
    `:''} + ${addThreatHtml(a,left)}`; +} +const addThreatHtml=(a,left)=>left.length?`
    `:''; +async function saveTreatment(aid,tid,change){ + const d=clone(raw.assets[aid]);if(!d)return; + const r=RK.setTreatment(d,tid,change);if(r)d.risk=r;else delete d.risk; + try{await Store.putAsset(aid,d);}catch(e){} +} + +// One risk of one asset: why it applies, how it is scored, the requirements against it and the decision +let THREAT_FOR=null; +function showThreat(aid,tid,keep){ + const a=byId[aid],r=a&&(SITE.threats[aid]||[]).find(x=>x.threat.id===tid);if(!r){if(a)showAsset(a);return;} + THREAT_FOR={aid,tid};const top=keep?det.scrollTop:0,t=r.threat,M=RS.matrix,ro=Store.canWrite?'':' disabled',F=r.factors; + const cell=c=>`${lvTag(c.level)} ${esc(M.likelihood[c.l])} × ${esc(M.impact[c.i])}`; + const byB={};r.requirements.forEach(q=>(byB[q.baseline]=byB[q.baseline]||{name:q.baselineName,list:[]}).list.push(q)); + const act=RK.ACTORS.filter(x=>t.actors.includes(x.id)),en=RK.ENISA.filter(x=>t.enisa.includes(x.id)); + const manual=Array.isArray((a.risk||{}).added)&&a.risk.added.includes(t.id); + openDet(`
    Risk · ${esc(a.name)}

    ${esc(t.name)}

    ${esc(t.desc)}

    +
    +
    +
    Applies because
    ${esc(r.why.join(' · '))}
    +
    Before requirements
    ${cell(r.inherent)}
    +
    Requirements applied
    ${cell(r.residual)}
    +
    Once planned ones too
    ${cell(r.target)}
    + ${act.length?`
    Risk sources
    ${act.map(x=>`${esc(x.name)} (relevance ${(SITE.landscape.actors||{})[x.id]??x.relevance}/3)`).join(', ')}
    `:''} + ${t.attack.length?`
    MITRE ATT&CK
    ${t.attack.map(x=>`${x}`).join(' ')}
    `:''} + ${en.length?`
    ENISA landscape
    ${en.map(x=>esc(x.name)).join(', ')}
    `:''} +
    +
    How it is scored
    +
    Likelihood
    ${t.base}/4 for the threat × ${pctR(0.4+0.6*F.context)} exposure and reachability${F.vuln!=null?` × ${pctR(0.5+0.5*F.vuln)} from its vulnerabilities`:''}${t.actors.length?` × ${pctR(F.actors)} from the relevance of its sources`:''} = ${pctR(r.p)}${r.pResidual!==r.p?`, ${pctR(r.pResidual)} with the requirements`:''}
    +
    Impact
    ${t.severity}/4 for the threat × ${pctR(F.crit)} criticality of the asset or of the business services it would hit = ${pctR(r.i)}${r.iResidual!==r.i?`, ${pctR(r.iResidual)} with the requirements`:''}
    +
    Requirements
    Each requirement applied lowers the likelihood or the impact by its share; planned ones count in the last line only.
    +

    Decision

    +
    +
    + + ${manual?`
    `:''} +

    Requirements · ${r.requirements.length}

    + ${!RS.baselines.length?'

    No baseline is enabled. Choose them in the risk settings (Risks view › Settings).

    ':!r.requirements.length?'

    No requirement of the enabled baselines addresses this threat.

    ': + Object.entries(byB).map(([id,b])=>`

    ${esc(b.name)}

      ${b.list.map(q=>`
    • ${esc(q.ref)} ${esc(q.title)}−${Math.round(q.strength*100)}% on the ${q.effect}${q.text?` · details`:''}
      +
    • `).join('')}
    `).join('')} +
    `,'threat'); + if(keep)det.scrollTop=top; +} +det.addEventListener('click',e=>{ + if(!SITE)return;const q=s=>e.target.closest(s); + if(q('[data-threat]')){const b=q('[data-threat]');showThreat(b.dataset.threatAsset||state.selId,b.dataset.threat);return;} + if(state.panel!=='threat'||!THREAT_FOR)return; + if(q('[data-threat-back]')){const a=byId[THREAT_FOR.aid];if(a)select(a);return;} + if(q('[data-threat-unadd]')){const {aid,tid}=THREAT_FOR;saveTreatment(aid,tid,{add:false}).then(()=>{if(byId[aid])select(byId[aid]);});} +}); +det.addEventListener('change',e=>{ + if(!SITE)return;const t=e.target; + if(t.dataset.threatAdd!==undefined&&t.value){const aid=t.dataset.threatAdd,tid=t.value;saveTreatment(aid,tid,{add:true}).then(()=>{state.panel='threat';THREAT_FOR={aid,tid};scheduleData(0);});return;} + if(state.panel!=='threat'||!THREAT_FOR)return;const {aid,tid}=THREAT_FOR; + if(t.dataset.req)saveTreatment(aid,tid,{req:t.dataset.req,status:t.value}); + else if(t.hasAttribute('data-threat-decision'))saveTreatment(aid,tid,{decision:t.value}); + else if(t.hasAttribute('data-threat-note'))saveTreatment(aid,tid,{note:t.value}); + else if(t.hasAttribute('data-threat-exclude'))saveTreatment(aid,tid,{exclude:t.checked}); +}); + +// The Risks view: the register of the IS +let RKF=null; // filter: {k: 'inherent'|'residual', l, i} +function renderRiskLens(){ + const rows=SITE.register,M=RS.matrix,shown=RKF?rows.filter(r=>r[RKF.k].l===RKF.l&&r[RKF.k].i===RKF.i):rows; + const by=k=>RK.LEVELS.slice().reverse().map(l=>`${rows.filter(r=>r[k].level===l).length} ${RK.LEVEL_LBL[l].toLowerCase()}`).join(' · '); + const open=rows.filter(r=>!r.acceptable).length,assets=new Set(rows.map(r=>r.asset.id)).size; + lensBody.innerHTML=`

    Risk register

    The threats that apply to each asset, from its exposure, criticality, ports, system and vulnerabilities, and from the threat landscape of this IS. Each is placed on the risk matrix before and after the requirements of the enabled baselines (${RS.baselines.length?esc(RS.baselines.map(id=>(BASELINES().concat(RS.custom).find(b=>b.id===id)||{}).name||id).join(', ')):'none yet'}).

    +
    + ${rows.length?`

    ${plural(rows.length,'risk')} on ${plural(assets,'asset')}. Before requirements: ${by('inherent')}. With the requirements applied: ${by('residual')}. ${open} above the acceptance threshold and not accepted.

    +
    ${matrixHtml(M,gridOf(rows,'inherent'),{title:'Before requirements',click:'inherent',on:(l,i)=>RKF&&RKF.k==='inherent'&&RKF.l===l&&RKF.i===i})}${matrixHtml(M,gridOf(rows,'residual'),{title:'With the requirements applied',click:'residual',on:(l,i)=>RKF&&RKF.k==='residual'&&RKF.l===l&&RKF.i===i})}
    + ${RKF?`

    Showing the ${plural(shown.length,'risk')} ${RKF.k==='inherent'?'before requirements':'with requirements applied'} at ${esc(M.likelihood[RKF.l])} likelihood × ${esc(M.impact[RKF.i])} impact.

    `:'

    Click a cell to list its risks.

    '} + + ${shown.map(r=>{const c=reqCount(r);return ``;}).join('')} +
    AssetThreatBeforeNowPlannedRequirementsDecision
    ${esc(r.asset.name)}${esc(TYPE_LABEL[r.asset.type]||'')}${esc(r.threat.name)}${lvTag(r.inherent.level)}${lvTag(r.residual.level)}${lvTag(r.target.level)}${r.requirements.length?`${c.ap}/${c.n}${c.pl?` +${c.pl}`:''}`:'—'}${esc(DECISION[r.decision].split(' (')[0])}
    `:`

    No risk yet: no threat of the catalogue applies to the assets of this IS with what the map says about them. Record flows (exposure), criticality, systems and vulnerabilities, or add threats by hand from an asset sheet.

    `}`; +} +lensEl.addEventListener('click',e=>{ + if(state.lens!=='risk'||!SITE)return;const q=s=>e.target.closest(s); + if(q('[data-cell]')){const [k,v]=q('[data-cell]').dataset.cell.split(':'),[l,i]=v.split(',').map(Number);RKF=RKF&&RKF.k===k&&RKF.l===l&&RKF.i===i?null:{k,l,i};renderRiskLens();return;} + if(q('[data-rk-clear]')){RKF=null;renderRiskLens();return;} + if(q('[data-threat]')){const b=q('[data-threat]');state.selId=b.dataset.threatAsset;showThreat(b.dataset.threatAsset,b.dataset.threat);return;} + if(q('[data-rk-settings]')){showRiskSettings();return;} + if(q('[data-rk-landscape]')){showLandscape();return;} + if(q('[data-csv-register]'))exportRegister(); +}); +lensEl.addEventListener('keydown',e=>{if(state.lens!=='risk'||(e.key!=='Enter'&&e.key!==' '))return;const t=e.target.closest('[data-cell],[data-threat]');if(t){e.preventDefault();t.click();}}); +function exportRegister(){ + const rows=[['Asset','IP','Type','Threat','Applies because','MITRE ATT&CK','Likelihood before','Impact before','Level before','Level now','Level once planned','Requirements applied','Requirements planned','Requirements not applied','Decision','Justification']]; + const M=RS.matrix,refs=(r,s)=>r.requirements.filter(x=>(x.status||'')===s).map(x=>`${x.baselineName} ${x.ref}`).join(', '); + SITE.register.forEach(r=>rows.push([r.asset.name,r.asset.ip||'',TYPE_LABEL[r.asset.type]||r.asset.type,r.threat.name,r.why.join('; '),r.threat.attack.join(' '),M.likelihood[r.inherent.l],M.impact[r.inherent.i],RK.LEVEL_LBL[r.inherent.level],RK.LEVEL_LBL[r.residual.level],RK.LEVEL_LBL[r.target.level],refs(r,'applied'),refs(r,'planned'),refs(r,''),DECISION[r.decision].split(' (')[0],r.note])); + if(rows.length===1){toast('No risk on this IS.',true);return;} + saveFile(`risk-register_${fileStem(SITE.name)}_${today()}.csv`,'text/csv;charset=utf-8',csv(rows)); +} + +// The threat landscape of an IS: how relevant each risk source is to it (EBIOS RM, workshop 2) +function showLandscape(){ + const L=SITE.landscape.actors||{},ro=Store.canWrite?'':' disabled'; + openDet(`
    Threat landscape · IS ${esc(SITE.name)}

    Risk sources

    How relevant each risk source and its objective is to this IS. A source rated 0 takes its threats out of the register; 3 keeps them at full likelihood.

    +
      ${RK.ACTORS.map(x=>{const v=L[x.id]??x.relevance;return `
    • ${esc(x.name)}${esc(x.origin)} · ${esc(x.objective)}
    • `;}).join('')}
    +

    Defaults follow the ENISA Threat Landscape: cybercrime is the most likely source for any organisation. Raise state-sponsored sources for operators of essential services or defence suppliers.

    `,'landscape'); +} +det.addEventListener('change',e=>{ + const s=e.target.closest('[data-actor]');if(!s||state.panel!=='landscape'||!SITE)return; + const d=clone(raw.si[SITE.id]),L=Object.assign({},(d.landscape&&d.landscape.actors)||{});L[s.dataset.actor]=+s.value; + const def=RK.ACTORS.find(x=>x.id===s.dataset.actor);if(def&&def.relevance===+s.value)delete L[s.dataset.actor]; + d.landscape=Object.assign({},d.landscape,{actors:L});if(!Object.keys(L).length)delete d.landscape.actors;if(!Object.keys(d.landscape).length)delete d.landscape; + Store.putSite(SITE.id,d).catch(()=>{}); +}); + +// Risk settings: the matrix, the baselines in use, the threat catalogue. Edited on a copy, saved at once. +let RSD=null; +function showRiskSettings(keep){ + if(!keep)RSD=clone(raw.risk||{}); + const S=RK.settings(RSD,BASELINES()),M=S.matrix,ro=Store.canWrite?'':' disabled',top=keep?det.scrollTop:0; + const all=BASELINES().map(b=>RK.cleanBaseline(b,false)).concat(S.custom),cat=RK.THREATS.concat(S.customThreats); + const sizes=(k,n)=>``; + openDet(`
    Risks · every IS

    Risk settings

    The matrix, the baselines whose requirements are offered against each threat, and the threat catalogue

    +
    +

    Risk matrix

    +
    +
    +
    ${(()=>{let h='';for(let l=M.likelihood.length-1;l>=0;l--){h+=``;for(let i=0;i`;}h+='';} + return h+`${M.impact.map((x,i)=>``).join('')}
    `;})()}
    +

    Rows: likelihood, highest at the top. Columns: impact. Click a cell to change its level. The levels split the scores evenly; a risk above the acceptable level needs requirements or a decision.

    +

    Baselines · ${S.baselines.length} enabled

    +
      ${all.map(b=>`
    • ${b.custom?``:''}
    • `).join('')||'
    • No baseline available.
    • '}
    +
    +

    Threat catalogue · ${cat.length-S.disabled.size} in use

    +
      ${cat.map(t=>`
    • ${t.custom?``:''}
    • `).join('')}
    +
    Add a custom threat +
    +
    +
    +
    +
    +
    +
    +

    Share

    +
    + +
    `,'risksettings'); + if(keep)det.scrollTop=top; +} +// Every change is saved at once, then the panel is drawn again from the saved copy +function rsSave(){const d=clone(RSD);Store.putRisk(d).then(()=>{if(state.panel==='risksettings')showRiskSettings(true);}).catch(()=>{RSD=clone(raw.risk||{});if(state.panel==='risksettings')showRiskSettings(true);});} +const rsMatrix=()=>RK.cleanMatrix(RSD.matrix); +const rsEnabled=()=>RK.settings(RSD,BASELINES()).baselines; +let RS_IMPORT=null; +det.addEventListener('click',e=>{ + if(state.panel!=='risksettings'||!RSD)return;const q=s=>e.target.closest(s); + if(q('[data-rs-cell]')){const [l,i]=q('[data-rs-cell]').dataset.rsCell.split(',').map(Number),M=rsMatrix();M.cells=M.cells.map(r=>r.slice());M.cells[l][i]=(M.cells[l][i]+1)%4;RSD.matrix=M;rsSave();return;} + if(q('[data-rs-del-baseline]')){const id=q('[data-rs-del-baseline]').dataset.rsDelBaseline,en=rsEnabled();RSD.custom=(RSD.custom||[]).filter(b=>'custom:'+String(b.id).replace(/^custom:/,'')!==id);RSD.baselines=en.filter(x=>x!==id);rsSave();return;} + if(q('[data-rs-del-threat]')){const id=q('[data-rs-del-threat]').dataset.rsDelThreat;RSD.threats=Object.assign({},RSD.threats);RSD.threats.custom=(RSD.threats.custom||[]).filter(t=>'custom:'+String(t.id).replace(/^custom:/,'')!==id);rsSave();return;} + if(q('[data-rs-add-threat]')){ + const name=$('#rsTName').value.trim();if(!name){toast('Give the threat a name.',true);return;} + const types=[...$('#rsTTypes').selectedOptions].map(o=>o.value),w={critMin:+$('#rsTCrit').value};if(types.length)w.types=types;if($('#rsTExp').value)w.exposure=$('#rsTExp').value; + const t={id:fileStem(name).toLowerCase()+'-'+Date.now().toString(36),name,desc:$('#rsTDesc').value.trim(),base:+$('#rsTBase').value,severity:+$('#rsTSev').value,when:w,attack:$('#rsTAtt').value.split(/[\s,;]+/).map(x=>x.trim().toUpperCase()).filter(Boolean)}; + RSD.threats=Object.assign({},RSD.threats);RSD.threats.custom=(RSD.threats.custom||[]).concat([t]);rsSave();return;} + if(q('[data-rs-export]')){saveFile(`strata-risk-settings_${today()}.json`,'application/json',JSON.stringify({format:'strata-risk',version:1,risk:raw.risk||{}},null,2));return;} + if(q('[data-rs-template]')){saveFile('baseline-template.csv','text/csv;charset=utf-8',csv([['id','title','text','threats'],['R1','Multi-factor authentication on remote access','Every remote access (VPN, remote desktop, administration) asks for a second factor.','remote-access:0.5:likelihood|brute-force:0.6:likelihood'],['R2','Offline backups','A copy of the backups is kept offline and restores are tested.','ransomware:0.5:impact|backup-destruction:0.6:impact']]));return;} + if(q('[data-rs-import]')){RS_IMPORT=q('[data-rs-import]').dataset.rsImport;$('#rsFile').value='';$('#rsFile').click();} +}); +det.addEventListener('change',async e=>{ + if(state.panel!=='risksettings'||!RSD)return;const t=e.target; + if(t.dataset.rsSize){const M=rsMatrix(),n=t.dataset.rsSize==='l'?+t.value:M.likelihood.length,m=t.dataset.rsSize==='i'?+t.value:M.impact.length;RSD.matrix=Object.assign(RK.defaultMatrix(n,m),{accept:M.accept});rsSave();return;} + if(t.hasAttribute('data-rs-accept')){RSD.matrix=Object.assign(rsMatrix(),{accept:+t.value});rsSave();return;} + if(t.dataset.rsLabel){const [k,x]=t.dataset.rsLabel.split(':'),M=rsMatrix();M[k]=M[k].slice();M[k][+x]=t.value.trim()||M[k][+x];RSD.matrix=M;rsSave();return;} + if(t.dataset.rsBaseline){const s=new Set(rsEnabled());t.checked?s.add(t.dataset.rsBaseline):s.delete(t.dataset.rsBaseline);RSD.baselines=[...s];rsSave();return;} + if(t.dataset.rsThreat){const s=new Set(((RSD.threats||{}).disabled)||[]);t.checked?s.delete(t.dataset.rsThreat):s.add(t.dataset.rsThreat);RSD.threats=Object.assign({},RSD.threats,{disabled:[...s]});rsSave();return;} + if(t.id==='rsFile'&&t.files[0]){ + const f=t.files[0],text=await f.text();let o; + try{ + if(RS_IMPORT==='baseline'){o=/\.csv$/i.test(f.name)||!/^\s*[[{]/.test(text)?baselineFromCsv(text,f.name):JSON.parse(text); + if(!o||!Array.isArray(o.requirements)||!o.requirements.length)throw new Error('no requirement found'); + o.id=o.id||fileStem(o.name||f.name.replace(/\.\w+$/,'')).toLowerCase();o.name=o.name||f.name.replace(/\.\w+$/,''); + const id='custom:'+String(o.id).replace(/^custom:/,'');RSD.custom=(RSD.custom||[]).filter(b=>'custom:'+String(b.id).replace(/^custom:/,'')!==id).concat([o]);RSD.baselines=[...new Set([...rsEnabled(),id])]; + toast(`Baseline “${o.name}” imported: ${plural(o.requirements.length,'requirement')}.`);} + else if(RS_IMPORT==='threats'){o=JSON.parse(text);const l=Array.isArray(o)?o:Array.isArray(o.threats)?o.threats:[];if(!l.length)throw new Error('expected a list of threats'); + RSD.threats=Object.assign({},RSD.threats);const ids=new Set(l.map(x=>String(x.id)));RSD.threats.custom=(RSD.threats.custom||[]).filter(x=>!ids.has(String(x.id))).concat(l);toast(`${plural(l.length,'threat')} imported.`);} + else{o=JSON.parse(text);const r=o&&o.risk&&typeof o.risk==='object'?o.risk:o;if(!r||typeof r!=='object'||Array.isArray(r))throw new Error('expected a Strata risk settings export');RSD=clone(r);toast('Risk settings imported.');} + }catch(err){toast('Could not import this file: '+(err.message||'invalid')+'.',true);return;} + rsSave(); + } +}); +// A baseline as CSV: id, title, text, threats (threat:share:effect separated by |), comma or semicolon separated +function baselineFromCsv(text,file){ + const rows=[];let row=[],cell='',q=false;const sep=(text.split('\n')[0].match(/;/g)||[]).length>=(text.split('\n')[0].match(/,/g)||[]).length?';':','; + for(let k=0;kh.replace(/^/,'').trim().toLowerCase()),col=k=>head.indexOf(k); + if(col('id')<0||col('title')<0)throw new Error('the first line needs the columns id and title'); + return {name:file.replace(/\.\w+$/,''),requirements:rows.filter(r=>r[col('id')]&&r[col('title')]).map(r=>({id:r[col('id')].trim(),title:r[col('title')].trim(),text:col('text')>=0?r[col('text')]||'':'', + threats:col('threats')>=0?String(r[col('threats')]||'').split('|').map(x=>x.trim().split(':')).filter(x=>x[0]).map(([id,s,ef])=>[id,+s||0.3,ef==='impact'?'impact':'likelihood']):[]}))}; +} + /* ================= Navigation ================= */ let fly=null; function flyTo(target,dist){const off=camera.position.clone().sub(controls.target);off.setLength(dist||Math.min(off.length(),28)); @@ -3600,6 +3847,8 @@ function onData(){ else if(state.panel==='attack')showAttack(); else if(state.panel==='incident')showIncident(true); else if(state.panel==='ai'){const a=byId[AI_FOR];if(a)showPrompts(a,true);else closeDet();} + else if(state.panel==='threat'&&THREAT_FOR){if(byId[THREAT_FOR.aid])showThreat(THREAT_FOR.aid,THREAT_FOR.tid,true);else closeDet();} + else if(state.panel==='landscape')showLandscape(); else if(state.panel==='business'){const b=SITE.bizById[state.bizPanel];if(b)showBusiness(b);else closeDet();} } }else{ @@ -3610,6 +3859,8 @@ function onData(){ refreshOverview(); } if(state.panel==='proposal'&&Store.prop)showProposal(); + // the risk settings follow the saved document, unless a label is being typed + if(state.panel==='risksettings'&&!(det.contains(document.activeElement)&&document.activeElement.matches('input,textarea'))){RSD=clone(raw.risk||{});showRiskSettings(true);} renderServiceLists();renderCollab(); lastCount=SITES.length;renderCart();syncUI();renderEmpty();runPending(); } diff --git a/public/baselines.js b/public/baselines.js new file mode 100644 index 0000000..b2a9208 --- /dev/null +++ b/public/baselines.js @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +// Security baselines shipped with Strata, for the risk register. Each requirement lists the threats of the +// catalogue in risk.js it reduces: [threat id, share of the likelihood or impact it removes, 'likelihood'|'impact']. +// The links and shares are Strata's own judgement, not part of the baselines. Licences: +// - ANSSI, Guide d'hygiène informatique (42 mesures, 2017): Licence Ouverte / Open Licence (Etalab). French titles +// as published; English titles and summaries translated. +// - NIST Cybersecurity Framework 2.0: a U.S. Government work, public domain. Titles from NIST's own export. +// - CIS Critical Security Controls v8.1 and ISO/IEC 27001:2022 Annex A: numbering only, with titles paraphrased +// by Strata; neither text is reproduced. ig: the lowest CIS Implementation Group of the safeguard. +(function(root){ +'use strict'; +root.StrataBaselines=[{"id":"anssi","name":"ANSSI — Guide d'hygiène informatique (42 mesures)","version":"2.0 (2017)","license":"Licence Ouverte / Open Licence (Etalab, v1), as stated in the guide. Translated and summarised.","url":"https://messervices.cyber.gouv.fr/guides/guide-dhygiene-informatique","requirements":[{"id":"1","ref":"M1","title":"Train the operational teams in information system security","titleFr":"Former les équipes opérationnelles à la sécurité des systèmes d’information","text":"Train administrators, developers, project managers and other operational staff, on arrival and regularly, in security topics such as hardening, authentication, access control, partitioning and logging. Service contracts should guarantee the same training for external staff and outsourcers.","threats":[["directory-takeover",0.2,"likelihood"],["lateral-admin",0.2,"likelihood"],["default-credentials",0.2,"likelihood"],["data-exposure",0.2,"likelihood"],["web-app",0.1,"likelihood"],["privilege-escalation",0.1,"likelihood"]]},{"id":"2","ref":"M2","title":"Raise users’ awareness of basic IT security practices","titleFr":"Sensibiliser les utilisateurs aux bonnes pratiques élémentaires de sécurité informatique","text":"Inform every user, from arrival and regularly, of the security stakes, sensitive information and everyday rules (no personal devices, no password sharing or reuse, report suspicious events, lock sessions). A signed IT charter is the strengthened level.","threats":[["phishing",0.4,"likelihood"],["bec",0.3,"likelihood"],["brute-force",0.1,"likelihood"],["physical-access",0.1,"likelihood"]]},{"id":"3","ref":"M3","title":"Control the risks of outsourcing","titleFr":"Maîtriser les risques de l’infogérance","text":"Assess the risks of outsourcing the information system or data beforehand and impose security requirements on the provider (reversibility, audits, backups in an open format, security maintenance), formalised in a security assurance plan.","threats":[["third-party-access",0.3,"likelihood"],["supply-chain",0.2,"likelihood"],["internet-dependency",0.2,"impact"]]},{"id":"4","ref":"M4","title":"Identify the most sensitive information and servers and maintain a network diagram","titleFr":"Identifier les informations et serveurs les plus sensibles et maintenir un schéma du réseau","text":"List the sensitive data and the servers and devices that hold it so they get specific protection, and keep a simplified network map showing IP zones, addressing, routing and security devices, external connections and partners.","threats":[["data-exposure",0.2,"likelihood"],["data-theft",0.1,"likelihood"],["it-ot-pivot",0.1,"likelihood"]]},{"id":"5","ref":"M5","title":"Keep an exhaustive, up-to-date inventory of privileged accounts","titleFr":"Disposer d’un inventaire exhaustif des comptes privilégiés et le maintenir à jour","text":"Inventory accounts with administrator or elevated rights, access to managers’ or all users’ folders, or unmanaged workstations; review them periodically to remove obsolete rights, and use a clear naming scheme for system and admin accounts.","threats":[["directory-takeover",0.2,"likelihood"],["insider-misuse",0.2,"likelihood"],["lateral-admin",0.1,"likelihood"]]},{"id":"6","ref":"M6","title":"Organise procedures for users joining, leaving and changing roles","titleFr":"Organiser les procédures d’arrivée, de départ et de changement de fonction des utilisateurs","text":"Define, with HR, arrival and departure procedures that create and remove accounts and mailboxes, adjust rights on role changes, manage badges and keys, mobile equipment and the handover of sensitive information and passwords.","threats":[["insider-misuse",0.3,"likelihood"],["remote-access",0.2,"likelihood"],["third-party-access",0.1,"likelihood"]]},{"id":"7","ref":"M7","title":"Allow only managed devices to connect to the organisation’s network","titleFr":"Autoriser la connexion au réseau de l’entité aux seuls équipements maîtrisés","text":"Only devices managed by the organisation may connect to its wired or wireless networks; personal and visitor devices go on a separate network (e.g. a dedicated Wi-Fi SSID). Device authentication such as 802.1X is the strengthened level.","threats":[["wifi-intrusion",0.3,"likelihood"],["physical-access",0.2,"likelihood"],["device-takeover",0.1,"likelihood"]]},{"id":"8","ref":"M8","title":"Identify each person accessing the system by name and distinguish user and administrator roles","titleFr":"Identifier nommément chaque personne accédant au système et distinguer les rôles utilisateur/administrateur","text":"Use nominative accounts, keep generic accounts marginal and as tightly managed, and give each administrator a separate admin account with distinct credentials, used only for administration in a dedicated environment; log account connections.","threats":[["lateral-admin",0.3,"likelihood"],["directory-takeover",0.3,"likelihood"],["insider-misuse",0.2,"likelihood"]]},{"id":"9","ref":"M9","title":"Assign the right permissions on the information system’s sensitive resources","titleFr":"Attribuer les bons droits sur les ressources sensibles du système d’information","text":"List sensitive resources (folders, databases, mailboxes, shares), define which group may access each, enforce authenticated access, avoid copies to less protected areas, and review access rights regularly.","threats":[["data-exposure",0.3,"likelihood"],["data-theft",0.3,"likelihood"],["insider-misuse",0.3,"likelihood"]]},{"id":"10","ref":"M10","title":"Define and enforce rules for choosing passwords and their length","titleFr":"Définir et vérifier des règles de choix et de dimensionnement des mots de passe","text":"Set password strength rules following ANSSI recommendations, explain them to users (in particular no reuse), and enforce them with account lockout after failed attempts, no anonymous logins and password strength checks.","threats":[["brute-force",0.4,"likelihood"],["remote-access",0.2,"likelihood"],["default-credentials",0.2,"likelihood"]]},{"id":"11","ref":"M11","title":"Protect passwords stored on systems","titleFr":"Protéger les mots de passe stockés sur les systèmes","text":"Do not store passwords in clear on paper or in files, e-mails or browsers; use an encrypted password vault protected by a strong, memorised master password.","threats":[["lateral-admin",0.2,"likelihood"],["directory-takeover",0.1,"likelihood"]]},{"id":"12","ref":"M12","title":"Change default authentication credentials on devices and services","titleFr":"Changer les éléments d’authentification par défaut sur les équipements et services","text":"Replace default passwords and credentials of every component at installation, following the password rules, report hard-coded secrets to the vendor, and renew them regularly at the strengthened level.","threats":[["default-credentials",0.6,"likelihood"],["device-takeover",0.4,"likelihood"],["network-device",0.2,"likelihood"]]},{"id":"13","ref":"M13","title":"Use strong authentication whenever possible","titleFr":"Privilégier lorsque c’est possible une authentification forte","text":"Prefer multi-factor authentication combining something you know, have or are; smart cards or one-time passwords with a hardware token are the strengthened level.","threats":[["remote-access",0.6,"likelihood"],["brute-force",0.5,"likelihood"],["bec",0.4,"likelihood"],["phishing",0.3,"likelihood"],["lateral-admin",0.2,"likelihood"],["directory-takeover",0.2,"likelihood"]]},{"id":"14","ref":"M14","title":"Apply a minimum security level across the whole IT estate","titleFr":"Mettre en place un niveau de sécurité minimal sur l’ensemble du parc informatique","text":"On every device, limit installed applications and browser add-ons, run anti-virus and a local firewall, encrypt user data partitions, disable autorun, and isolate devices that cannot meet the rules. Strengthened: back up vital data to disconnected media and test restores.","threats":[["phishing",0.3,"likelihood"],["ransomware",0.3,"likelihood"],["backup-destruction",0.2,"likelihood"],["physical-access",0.2,"impact"],["end-of-life",0.2,"impact"],["privilege-escalation",0.1,"likelihood"]]},{"id":"15","ref":"M15","title":"Protect against threats from removable media","titleFr":"Se protéger des menaces relatives à l’utilisation de supports amovibles","text":"Forbid unknown USB media, limit uncontrolled ones and scan them with anti-virus, raise user awareness; strengthened: block execution from removable media and destroy media securely at end of life.","threats":[["physical-access",0.3,"likelihood"],["data-theft",0.2,"likelihood"],["ransomware",0.1,"likelihood"]]},{"id":"16","ref":"M16","title":"Use a centralised management tool to make security policies uniform","titleFr":"Utiliser un outil de gestion centralisée afin d’homogénéiser les politiques de sécurité","text":"Manage as many workstations and servers as possible from a central tool (e.g. Active Directory) so hardening and security policies are applied uniformly and can be changed quickly in a crisis.","threats":[["privilege-escalation",0.1,"likelihood"],["lateral-admin",0.1,"likelihood"],["ransomware",0.1,"impact"]]},{"id":"17","ref":"M17","title":"Enable and configure the workstations’ local firewall","titleFr":"Activer et configurer le pare-feu local des postes de travail","text":"Turn on the host firewall to hinder lateral movement between workstations; strengthened: block administration ports by default except from identified hosts, whitelist needed inbound flows, and log blocked traffic.","threats":[["lateral-admin",0.4,"likelihood"],["ransomware",0.2,"impact"]]},{"id":"18","ref":"M18","title":"Encrypt sensitive data sent over the Internet","titleFr":"Chiffrer les données sensibles transmises par voie Internet","text":"Systematically encrypt sensitive data before e-mailing it or uploading it to online services, and pass the decryption secret through a separate trusted channel.","threats":[["data-theft",0.3,"likelihood"],["data-exposure",0.2,"impact"]]},{"id":"19","ref":"M19","title":"Segment the network and partition the resulting zones","titleFr":"Segmenter le réseau et mettre en place un cloisonnement entre ces zones","text":"Avoid flat networks: group systems with similar security needs into zones (VLANs, subnets or dedicated infrastructure) filtered by firewalls, segregating administration flows as far as possible.","threats":[["lateral-admin",0.4,"likelihood"],["it-ot-pivot",0.4,"likelihood"],["ransomware",0.3,"impact"],["directory-takeover",0.2,"likelihood"],["hypervisor-mass",0.2,"likelihood"],["device-takeover",0.2,"impact"]]},{"id":"20","ref":"M20","title":"Secure Wi-Fi access networks and separate uses","titleFr":"S’assurer de la sécurité des réseaux d’accès Wi-Fi et de la séparation des usages","text":"Filter Wi-Fi flows to what is needed, use robust encryption (WPA2/AES-CCMP) and centralised, ideally certificate-based, authentication rather than one shared key, administer access points securely, and keep staff/visitor Wi-Fi apart from the organisation’s devices.","threats":[["wifi-intrusion",0.6,"likelihood"]]},{"id":"21","ref":"M21","title":"Use secure protocols wherever they exist","titleFr":"Utiliser des protocoles sécurisés dès qu’ils existent","text":"Use protocols with built-in security (TLS-based variants such as HTTPS, IMAPS, SMTPS; SSH instead of Telnet) on both the Internet and internal networks.","threats":[["data-theft",0.2,"likelihood"],["lateral-admin",0.1,"likelihood"],["network-device",0.1,"likelihood"]]},{"id":"22","ref":"M22","title":"Set up a secure Internet access gateway","titleFr":"Mettre en place une passerelle d’accès sécurisé à Internet","text":"Users’ devices should not reach the Internet directly: go through a gateway with a firewall and an authenticating, logging proxy; strengthened: content scanning, URL filtering, DNS resolution via the proxy, and mobile devices browsing through it.","threats":[["phishing",0.3,"likelihood"],["ransomware",0.2,"likelihood"],["data-theft",0.2,"likelihood"],["device-takeover",0.1,"likelihood"]]},{"id":"23","ref":"M23","title":"Isolate Internet-facing services from the rest of the information system","titleFr":"Cloisonner les services visibles depuis Internet du reste du système d’information","text":"Host services exposed to the Internet in dedicated, filtered zones (DMZ) separate from the internal network, so that their compromise does not open the rest of the information system.","threats":[["exploit-public",0.3,"impact"],["web-app",0.3,"impact"],["lateral-admin",0.2,"likelihood"],["ransomware",0.2,"impact"],["data-theft",0.1,"impact"]]},{"id":"24","ref":"M24","title":"Protect professional e-mail","titleFr":"Protéger sa messagerie professionnelle","text":"Scan incoming mail for malware, enable TLS between mail servers and clients, forbid forwarding to personal mailboxes, apply procedures against transfer fraud, and train users; strengthened: relay servers, anti-spam and SPF/DKIM/DMARC.","threats":[["phishing",0.5,"likelihood"],["bec",0.5,"likelihood"],["ransomware",0.2,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"25","ref":"M25","title":"Secure dedicated network interconnections with partners","titleFr":"Sécuriser les interconnexions réseau dédiées avec les partenaires","text":"Treat partners as untrusted: use site-to-site tunnels (ideally IPsec) and a firewall restricting flows to the operational need; strengthened: a dedicated filtering device, intrusion detection and an up-to-date partner contact.","threats":[["third-party-access",0.5,"likelihood"],["supply-chain",0.2,"impact"]]},{"id":"26","ref":"M26","title":"Control and protect access to server rooms and technical premises","titleFr":"Contrôler et protéger l’accès aux salles serveurs et aux locaux techniques","text":"Restrict server rooms and technical areas with locks or badges, forbid unaccompanied external access, review and revoke access rights, and disable network sockets in public areas.","threats":[["physical-access",0.5,"likelihood"],["insider-misuse",0.1,"likelihood"]]},{"id":"27","ref":"M27","title":"Forbid Internet access from devices or servers used to administer the information system","titleFr":"Interdire l’accès à Internet depuis les postes ou serveurs utilisés pour l’administration du système d’information","text":"Administration workstations and servers must never browse the web or read e-mail; give administrators a separate device for office use, and bring updates in from trusted sources through a controlled path.","threats":[["directory-takeover",0.4,"likelihood"],["hypervisor-mass",0.3,"likelihood"],["lateral-admin",0.2,"likelihood"],["phishing",0.2,"impact"]]},{"id":"28","ref":"M28","title":"Use a dedicated, segregated network to administer the information system","titleFr":"Utiliser un réseau dédié et cloisonné pour l’administration du système d’information","text":"Separate the administration network from the office network, preferably physically, otherwise with IPsec tunnels, and at minimum with VLANs.","threats":[["directory-takeover",0.4,"likelihood"],["hypervisor-mass",0.4,"likelihood"],["lateral-admin",0.4,"likelihood"],["network-device",0.3,"likelihood"],["ot-manipulation",0.2,"likelihood"]]},{"id":"29","ref":"M29","title":"Limit administration rights on workstations to strict operational need","titleFr":"Limiter au strict besoin opérationnel les droits d’administration sur les postes de travail","text":"Users, including executives, should not be local administrators; only workstation administrators hold these rights, a validated application store covers needs, and any exceptional delegation is time-limited and monitored.","threats":[["phishing",0.2,"impact"],["ransomware",0.2,"impact"],["lateral-admin",0.2,"likelihood"],["insider-misuse",0.1,"likelihood"]]},{"id":"30","ref":"M30","title":"Physically secure mobile devices","titleFr":"Prendre des mesures de sécurisation physique des terminaux nomades","text":"Make users vigilant with laptops, tablets and phones while travelling, keep devices unbranded, fit privacy screens, and optionally keep authentication or decryption secrets on a separate token.","threats":[["physical-access",0.4,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"31","ref":"M31","title":"Encrypt sensitive data, especially on hardware that can be lost","titleFr":"Chiffrer les données sensibles, en particulier sur le matériel potentiellement perdable","text":"Store only encrypted data on laptops, phones, USB keys and external drives, preferring full-disk encryption before archive or file encryption, with a robust secret.","threats":[["physical-access",0.5,"impact"],["data-theft",0.3,"impact"]]},{"id":"32","ref":"M32","title":"Secure the network connection of devices used while travelling","titleFr":"Sécuriser la connexion réseau des postes utilisés en situation de nomadisme","text":"Connect mobile workstations through an IPsec VPN to the organisation’s gateway, established automatically and not bypassable; strengthened: two-factor authentication with a certificate on a token or one-time passwords.","threats":[["remote-access",0.3,"likelihood"],["data-theft",0.2,"likelihood"]]},{"id":"33","ref":"M33","title":"Adopt security policies dedicated to mobile devices","titleFr":"Adopter des politiques de sécurité dédiées aux terminaux mobiles","text":"Do not mix personal and professional use on smartphones and tablets, and manage company devices centrally (unlock method, only validated apps); avoid built-in voice assistants.","threats":[["device-takeover",0.3,"likelihood"],["data-theft",0.2,"likelihood"],["physical-access",0.2,"impact"]]},{"id":"34","ref":"M34","title":"Define an update policy for the information system’s components","titleFr":"Définir une politique de mise à jour des composants du système d’information","text":"Track new vulnerabilities (e.g. CERT-FR) and apply security patches to all components within a month of release, with procedures covering inventory, sources, deployment tools and testing; isolate unsupported components.","threats":[["known-exploited",0.6,"likelihood"],["exploit-public",0.5,"likelihood"],["network-device",0.4,"likelihood"],["privilege-escalation",0.4,"likelihood"],["hypervisor-mass",0.3,"likelihood"],["device-takeover",0.3,"likelihood"],["web-app",0.2,"likelihood"],["defacement",0.2,"likelihood"],["end-of-life",0.3,"impact"]]},{"id":"35","ref":"M35","title":"Anticipate the end of software and system support and limit software dependencies","titleFr":"Anticiper la fin de la maintenance des logiciels et systèmes et limiter les adhérences logicielles","text":"Keep an inventory of applications and systems, choose products supported for their whole service life, monitor end-of-support dates, keep a homogeneous estate, limit dependencies between products, and plan migrations.","threats":[["end-of-life",0.6,"likelihood"],["known-exploited",0.2,"likelihood"]]},{"id":"36","ref":"M36","title":"Enable and configure logs on the most important components","titleFr":"Activer et configurer les journaux des composants les plus importants","text":"Log security events on critical components (blocked flows, authentications, errors, interconnection traffic), keep them at least a year, synchronise clocks via NTP; strengthened: centralise logs so attackers cannot erase them.","threats":[["detection-blinding",0.4,"likelihood"],["ransomware",0.2,"impact"],["data-theft",0.2,"impact"],["insider-misuse",0.2,"impact"],["lateral-admin",0.2,"impact"],["directory-takeover",0.2,"impact"],["brute-force",0.2,"impact"]]},{"id":"37","ref":"M37","title":"Define and apply a backup policy for critical components","titleFr":"Définir et appliquer une politique de sauvegarde des composants critiques","text":"Formalise a backup policy listing vital data and servers, backup types including offline, frequency, procedures, storage and access restrictions, restore tests and media destruction; strengthened: a yearly restoration exercise.","threats":[["ransomware",0.6,"impact"],["hypervisor-mass",0.5,"impact"],["backup-destruction",0.5,"likelihood"],["insider-misuse",0.2,"impact"],["defacement",0.2,"impact"]]},{"id":"38","ref":"M38","title":"Carry out regular security checks and audits, then apply the corrective actions","titleFr":"Procéder à des contrôles et audits de sécurité réguliers puis appliquer les actions correctives associées","text":"Audit the information system at least yearly (technical and organisational, internal or by qualified providers), plan and track the corrective actions, and report progress to management.","threats":[["web-app",0.3,"likelihood"],["data-exposure",0.3,"likelihood"],["exploit-public",0.2,"likelihood"],["default-credentials",0.2,"likelihood"],["network-device",0.1,"likelihood"]]},{"id":"39","ref":"M39","title":"Appoint an information security point of contact and make them known to staff","titleFr":"Désigner un référent en sécurité des systèmes d’information et le faire connaître auprès du personnel","text":"Name a trained security referent, backed by management and known to all users, who sets and checks rules, drives awareness and training, and centralises incident reports.","threats":[["phishing",0.1,"impact"]]},{"id":"40","ref":"M40","title":"Define a security incident management procedure","titleFr":"Définir une procédure de gestion des incidents de sécurité","text":"Define how to react to suspected intrusions: disconnect the device from the network but keep it powered, alert management and the security referent, call on incident response providers, clean up and change passwords, and record incidents centrally.","threats":[["ransomware",0.3,"impact"],["data-theft",0.2,"impact"],["bec",0.2,"impact"],["lateral-admin",0.2,"impact"]]},{"id":"41","ref":"M41","title":"Carry out a formal risk analysis","titleFr":"Mener une analyse de risques formelle","text":"Assess information system risks formally (context, likelihood and impact, treatment plan validated by management) using a method such as ANSSI’s EBIOS, to decide and justify security measures.","threats":[]},{"id":"42","ref":"M42","title":"Prefer products and services qualified by ANSSI","titleFr":"Privilégier l’usage de produits et de services qualifiés par l’ANSSI","text":"Where possible, use security products and service providers (audit, incident response, cloud, etc.) that ANSSI has qualified, giving assurance of their robustness and trustworthiness.","threats":[["supply-chain",0.2,"likelihood"],["network-device",0.2,"likelihood"],["third-party-access",0.1,"likelihood"]]}]},{"id":"nist-csf","name":"NIST Cybersecurity Framework 2.0","version":"2.0 (2024)","license":"Public domain (U.S. Government work).","url":"https://www.nist.gov/cyberframework","requirements":[{"id":"GV.OC-01","ref":"GV.OC-01","title":"The organizational mission is understood and informs cybersecurity risk management","text":"","threats":[]},{"id":"GV.OC-02","ref":"GV.OC-02","title":"Internal and external stakeholders are understood, and their needs and expectations regarding cybersecurity risk management are understood and considered","text":"","threats":[]},{"id":"GV.OC-03","ref":"GV.OC-03","title":"Legal, regulatory, and contractual requirements regarding cybersecurity - including privacy and civil liberties obligations - are understood and managed","text":"","threats":[]},{"id":"GV.OC-04","ref":"GV.OC-04","title":"Critical objectives, capabilities, and services that external stakeholders depend on or expect from the organization are understood and communicated","text":"","threats":[]},{"id":"GV.OC-05","ref":"GV.OC-05","title":"Outcomes, capabilities, and services that the organization depends on are understood and communicated","text":"","threats":[["internet-dependency",0.2,"impact"]]},{"id":"GV.OV-01","ref":"GV.OV-01","title":"Cybersecurity risk management strategy outcomes are reviewed to inform and adjust strategy and direction","text":"","threats":[]},{"id":"GV.OV-02","ref":"GV.OV-02","title":"The cybersecurity risk management strategy is reviewed and adjusted to ensure coverage of organizational requirements and risks","text":"","threats":[]},{"id":"GV.OV-03","ref":"GV.OV-03","title":"Organizational cybersecurity risk management performance is evaluated and reviewed for adjustments needed","text":"","threats":[]},{"id":"GV.PO-01","ref":"GV.PO-01","title":"Policy for managing cybersecurity risks is established based on organizational context, cybersecurity strategy, and priorities and is communicated and enforced","text":"","threats":[["insider-misuse",0.1,"likelihood"]]},{"id":"GV.PO-02","ref":"GV.PO-02","title":"Policy for managing cybersecurity risks is reviewed, updated, communicated, and enforced to reflect changes in requirements, threats, technology, and organizational mission","text":"","threats":[]},{"id":"GV.RM-01","ref":"GV.RM-01","title":"Risk management objectives are established and agreed to by organizational stakeholders","text":"","threats":[]},{"id":"GV.RM-02","ref":"GV.RM-02","title":"Risk appetite and risk tolerance statements are established, communicated, and maintained","text":"","threats":[]},{"id":"GV.RM-03","ref":"GV.RM-03","title":"Cybersecurity risk management activities and outcomes are included in enterprise risk management processes","text":"","threats":[]},{"id":"GV.RM-04","ref":"GV.RM-04","title":"Strategic direction that describes appropriate risk response options is established and communicated","text":"","threats":[]},{"id":"GV.RM-05","ref":"GV.RM-05","title":"Lines of communication across the organization are established for cybersecurity risks, including risks from suppliers and other third parties","text":"","threats":[]},{"id":"GV.RM-06","ref":"GV.RM-06","title":"A standardized method for calculating, documenting, categorizing, and prioritizing cybersecurity risks is established and communicated","text":"","threats":[]},{"id":"GV.RM-07","ref":"GV.RM-07","title":"Strategic opportunities (i.e., positive risks) are characterized and are included in organizational cybersecurity risk discussions","text":"","threats":[]},{"id":"GV.RR-01","ref":"GV.RR-01","title":"Organizational leadership is responsible and accountable for cybersecurity risk and fosters a culture that is risk-aware, ethical, and continually improving","text":"","threats":[]},{"id":"GV.RR-02","ref":"GV.RR-02","title":"Roles, responsibilities, and authorities related to cybersecurity risk management are established, communicated, understood, and enforced","text":"","threats":[]},{"id":"GV.RR-03","ref":"GV.RR-03","title":"Adequate resources are allocated commensurate with the cybersecurity risk strategy, roles, responsibilities, and policies","text":"","threats":[]},{"id":"GV.RR-04","ref":"GV.RR-04","title":"Cybersecurity is included in human resources practices","text":"","threats":[["insider-misuse",0.2,"likelihood"]]},{"id":"GV.SC-01","ref":"GV.SC-01","title":"A cybersecurity supply chain risk management program, strategy, objectives, policies, and processes are established and agreed to by organizational stakeholders","text":"","threats":[["supply-chain",0.1,"likelihood"],["third-party-access",0.1,"likelihood"]]},{"id":"GV.SC-02","ref":"GV.SC-02","title":"Cybersecurity roles and responsibilities for suppliers, customers, and partners are established, communicated, and coordinated internally and externally","text":"","threats":[["third-party-access",0.2,"likelihood"]]},{"id":"GV.SC-03","ref":"GV.SC-03","title":"Cybersecurity supply chain risk management is integrated into cybersecurity and enterprise risk management, risk assessment, and improvement processes","text":"","threats":[["supply-chain",0.1,"likelihood"]]},{"id":"GV.SC-04","ref":"GV.SC-04","title":"Suppliers are known and prioritized by criticality","text":"","threats":[["supply-chain",0.1,"likelihood"],["third-party-access",0.1,"likelihood"],["internet-dependency",0.1,"impact"]]},{"id":"GV.SC-05","ref":"GV.SC-05","title":"Requirements to address cybersecurity risks in supply chains are established, prioritized, and integrated into contracts and other types of agreements with suppliers and other relevant third parties","text":"","threats":[["third-party-access",0.3,"likelihood"],["supply-chain",0.2,"likelihood"]]},{"id":"GV.SC-06","ref":"GV.SC-06","title":"Planning and due diligence are performed to reduce risks before entering into formal supplier or other third-party relationships","text":"","threats":[["supply-chain",0.2,"likelihood"],["third-party-access",0.2,"likelihood"]]},{"id":"GV.SC-07","ref":"GV.SC-07","title":"The risks posed by a supplier, their products and services, and other third parties are understood, recorded, prioritized, assessed, responded to, and monitored over the course of the relationship","text":"","threats":[["supply-chain",0.2,"likelihood"],["third-party-access",0.2,"likelihood"],["internet-dependency",0.1,"impact"]]},{"id":"GV.SC-08","ref":"GV.SC-08","title":"Relevant suppliers and other third parties are included in incident planning, response, and recovery activities","text":"","threats":[["supply-chain",0.2,"impact"],["third-party-access",0.2,"impact"],["internet-dependency",0.2,"impact"]]},{"id":"GV.SC-09","ref":"GV.SC-09","title":"Supply chain security practices are integrated into cybersecurity and enterprise risk management programs, and their performance is monitored throughout the technology product and service life cycle","text":"","threats":[["supply-chain",0.2,"likelihood"]]},{"id":"GV.SC-10","ref":"GV.SC-10","title":"Cybersecurity supply chain risk management plans include provisions for activities that occur after the conclusion of a partnership or service agreement","text":"","threats":[["third-party-access",0.3,"likelihood"]]},{"id":"ID.AM-01","ref":"ID.AM-01","title":"Inventories of hardware managed by the organization are maintained","text":"","threats":[["device-takeover",0.2,"likelihood"],["known-exploited",0.1,"likelihood"],["end-of-life",0.1,"likelihood"]]},{"id":"ID.AM-02","ref":"ID.AM-02","title":"Inventories of software, services, and systems managed by the organization are maintained","text":"","threats":[["end-of-life",0.2,"likelihood"],["known-exploited",0.2,"likelihood"],["exploit-public",0.1,"likelihood"]]},{"id":"ID.AM-03","ref":"ID.AM-03","title":"Representations of the organization's authorized network communication and internal and external network data flows are maintained","text":"","threats":[["it-ot-pivot",0.2,"likelihood"],["lateral-admin",0.1,"likelihood"],["data-exposure",0.1,"likelihood"]]},{"id":"ID.AM-04","ref":"ID.AM-04","title":"Inventories of services provided by suppliers are maintained","text":"","threats":[["internet-dependency",0.2,"impact"],["third-party-access",0.1,"likelihood"]]},{"id":"ID.AM-05","ref":"ID.AM-05","title":"Assets are prioritized based on classification, criticality, resources, and impact on the mission","text":"","threats":[["ransomware",0.1,"impact"]]},{"id":"ID.AM-07","ref":"ID.AM-07","title":"Inventories of data and corresponding metadata for designated data types are maintained","text":"","threats":[["data-exposure",0.2,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"ID.AM-08","ref":"ID.AM-08","title":"Systems, hardware, software, services, and data are managed throughout their life cycles","text":"","threats":[["end-of-life",0.4,"likelihood"],["known-exploited",0.1,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"ID.IM-01","ref":"ID.IM-01","title":"Improvements are identified from evaluations","text":"","threats":[]},{"id":"ID.IM-02","ref":"ID.IM-02","title":"Improvements are identified from security tests and exercises, including those done in coordination with suppliers and relevant third parties","text":"","threats":[["exploit-public",0.1,"likelihood"],["web-app",0.1,"likelihood"]]},{"id":"ID.IM-03","ref":"ID.IM-03","title":"Improvements are identified from execution of operational processes, procedures, and activities","text":"","threats":[]},{"id":"ID.IM-04","ref":"ID.IM-04","title":"Incident response plans and other cybersecurity plans that affect operations are established, communicated, maintained, and improved","text":"","threats":[["ransomware",0.3,"impact"],["hypervisor-mass",0.2,"impact"],["directory-takeover",0.2,"impact"],["internet-dependency",0.2,"impact"],["ddos",0.2,"impact"]]},{"id":"ID.RA-01","ref":"ID.RA-01","title":"Vulnerabilities in assets are identified, validated, and recorded","text":"","threats":[["known-exploited",0.4,"likelihood"],["exploit-public",0.3,"likelihood"],["network-device",0.3,"likelihood"],["web-app",0.2,"likelihood"],["privilege-escalation",0.2,"likelihood"],["end-of-life",0.2,"likelihood"],["default-credentials",0.2,"likelihood"],["data-exposure",0.2,"likelihood"]]},{"id":"ID.RA-02","ref":"ID.RA-02","title":"Cyber threat intelligence is received from information sharing forums and sources","text":"","threats":[["known-exploited",0.3,"likelihood"],["exploit-public",0.2,"likelihood"],["network-device",0.2,"likelihood"]]},{"id":"ID.RA-03","ref":"ID.RA-03","title":"Internal and external threats to the organization are identified and recorded","text":"","threats":[["exploit-public",0.1,"likelihood"]]},{"id":"ID.RA-04","ref":"ID.RA-04","title":"Potential impacts and likelihoods of threats exploiting vulnerabilities are identified and recorded","text":"","threats":[]},{"id":"ID.RA-05","ref":"ID.RA-05","title":"Threats, vulnerabilities, likelihoods, and impacts are used to understand inherent risk and inform risk response prioritization","text":"","threats":[]},{"id":"ID.RA-06","ref":"ID.RA-06","title":"Risk responses are chosen, prioritized, planned, tracked, and communicated","text":"","threats":[["known-exploited",0.2,"likelihood"],["exploit-public",0.1,"likelihood"]]},{"id":"ID.RA-07","ref":"ID.RA-07","title":"Changes and exceptions are managed, assessed for risk impact, recorded, and tracked","text":"","threats":[["data-exposure",0.2,"likelihood"],["insider-misuse",0.1,"likelihood"]]},{"id":"ID.RA-08","ref":"ID.RA-08","title":"Processes for receiving, analyzing, and responding to vulnerability disclosures are established","text":"","threats":[["web-app",0.2,"likelihood"],["exploit-public",0.1,"likelihood"]]},{"id":"ID.RA-09","ref":"ID.RA-09","title":"The authenticity and integrity of hardware and software are assessed prior to acquisition and use","text":"","threats":[["supply-chain",0.4,"likelihood"]]},{"id":"ID.RA-10","ref":"ID.RA-10","title":"Critical suppliers are assessed prior to acquisition","text":"","threats":[["supply-chain",0.3,"likelihood"],["third-party-access",0.2,"likelihood"]]},{"id":"PR.AA-01","ref":"PR.AA-01","title":"Identities and credentials for authorized users, services, and hardware are managed by the organization","text":"","threats":[["insider-misuse",0.2,"likelihood"],["default-credentials",0.2,"likelihood"],["third-party-access",0.2,"likelihood"],["remote-access",0.1,"likelihood"]]},{"id":"PR.AA-02","ref":"PR.AA-02","title":"Identities are proofed and bound to credentials based on the context of interactions","text":"","threats":[["remote-access",0.2,"likelihood"],["bec",0.1,"likelihood"]]},{"id":"PR.AA-03","ref":"PR.AA-03","title":"Users, services, and hardware are authenticated","text":"","threats":[["remote-access",0.5,"likelihood"],["brute-force",0.5,"likelihood"],["bec",0.4,"likelihood"],["default-credentials",0.3,"likelihood"],["lateral-admin",0.3,"likelihood"],["wifi-intrusion",0.3,"likelihood"],["directory-takeover",0.2,"likelihood"],["phishing",0.2,"likelihood"],["device-takeover",0.2,"likelihood"],["third-party-access",0.2,"likelihood"],["hypervisor-mass",0.2,"likelihood"],["network-device",0.2,"likelihood"],["defacement",0.2,"likelihood"]]},{"id":"PR.AA-04","ref":"PR.AA-04","title":"Identity assertions are protected, conveyed, and verified","text":"","threats":[["directory-takeover",0.2,"likelihood"],["lateral-admin",0.2,"likelihood"],["bec",0.2,"likelihood"]]},{"id":"PR.AA-05","ref":"PR.AA-05","title":"Access permissions, entitlements, and authorizations are defined in a policy, managed, enforced, and reviewed, and incorporate the principles of least privilege and separation of duties","text":"","threats":[["insider-misuse",0.4,"likelihood"],["directory-takeover",0.3,"likelihood"],["lateral-admin",0.3,"likelihood"],["data-exposure",0.3,"likelihood"],["data-theft",0.3,"impact"],["third-party-access",0.3,"impact"],["ransomware",0.2,"impact"],["hypervisor-mass",0.2,"likelihood"],["ot-manipulation",0.2,"likelihood"]]},{"id":"PR.AA-06","ref":"PR.AA-06","title":"Physical access to assets is managed, monitored, and enforced commensurate with risk","text":"","threats":[["physical-access",0.5,"likelihood"],["ot-manipulation",0.1,"likelihood"]]},{"id":"PR.AT-01","ref":"PR.AT-01","title":"Personnel are provided with awareness and training so that they possess the knowledge and skills to perform general tasks with cybersecurity risks in mind","text":"","threats":[["phishing",0.4,"likelihood"],["bec",0.3,"likelihood"],["physical-access",0.1,"likelihood"],["data-exposure",0.1,"likelihood"],["insider-misuse",0.1,"likelihood"]]},{"id":"PR.AT-02","ref":"PR.AT-02","title":"Individuals in specialized roles are provided with awareness and training so that they possess the knowledge and skills to perform relevant tasks with cybersecurity risks in mind","text":"","threats":[["bec",0.3,"likelihood"],["phishing",0.2,"likelihood"],["data-exposure",0.2,"likelihood"],["web-app",0.2,"likelihood"],["ot-manipulation",0.1,"likelihood"]]},{"id":"PR.DS-01","ref":"PR.DS-01","title":"The confidentiality, integrity, and availability of data-at-rest are protected","text":"","threats":[["physical-access",0.5,"impact"],["data-theft",0.4,"impact"],["data-exposure",0.3,"impact"]]},{"id":"PR.DS-02","ref":"PR.DS-02","title":"The confidentiality, integrity, and availability of data-in-transit are protected","text":"","threats":[["data-theft",0.2,"likelihood"],["wifi-intrusion",0.2,"impact"],["lateral-admin",0.1,"likelihood"]]},{"id":"PR.DS-10","ref":"PR.DS-10","title":"The confidentiality, integrity, and availability of data-in-use are protected","text":"","threats":[["lateral-admin",0.2,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"PR.DS-11","ref":"PR.DS-11","title":"Backups of data are created, protected, maintained, and tested","text":"","threats":[["ransomware",0.6,"impact"],["backup-destruction",0.5,"likelihood"],["hypervisor-mass",0.5,"impact"],["defacement",0.3,"impact"],["insider-misuse",0.3,"impact"],["ot-manipulation",0.2,"impact"],["directory-takeover",0.2,"impact"]]},{"id":"PR.IR-01","ref":"PR.IR-01","title":"Networks and environments are protected from unauthorized logical access and usage","text":"","threats":[["it-ot-pivot",0.5,"likelihood"],["lateral-admin",0.4,"likelihood"],["ransomware",0.3,"impact"],["wifi-intrusion",0.3,"impact"],["device-takeover",0.3,"impact"],["data-exposure",0.3,"likelihood"],["hypervisor-mass",0.3,"likelihood"],["exploit-public",0.2,"likelihood"],["third-party-access",0.2,"impact"],["remote-access",0.2,"impact"]]},{"id":"PR.IR-02","ref":"PR.IR-02","title":"The organization's technology assets are protected from environmental threats","text":"","threats":[]},{"id":"PR.IR-03","ref":"PR.IR-03","title":"Mechanisms are implemented to achieve resilience requirements in normal and adverse situations","text":"","threats":[["internet-dependency",0.4,"impact"],["ddos",0.3,"impact"],["ransomware",0.2,"impact"],["hypervisor-mass",0.2,"impact"]]},{"id":"PR.IR-04","ref":"PR.IR-04","title":"Adequate resource capacity to ensure availability is maintained","text":"","threats":[["ddos",0.3,"impact"]]},{"id":"PR.PS-01","ref":"PR.PS-01","title":"Configuration management practices are established and applied","text":"","threats":[["default-credentials",0.4,"likelihood"],["data-exposure",0.4,"likelihood"],["device-takeover",0.3,"likelihood"],["network-device",0.3,"likelihood"],["exploit-public",0.2,"likelihood"],["privilege-escalation",0.2,"likelihood"],["wifi-intrusion",0.2,"likelihood"],["lateral-admin",0.2,"likelihood"],["hypervisor-mass",0.2,"likelihood"],["web-app",0.1,"likelihood"]]},{"id":"PR.PS-02","ref":"PR.PS-02","title":"Software is maintained, replaced, and removed commensurate with risk","text":"","threats":[["known-exploited",0.5,"likelihood"],["end-of-life",0.5,"likelihood"],["exploit-public",0.4,"likelihood"],["privilege-escalation",0.4,"likelihood"],["web-app",0.3,"likelihood"],["network-device",0.3,"likelihood"],["hypervisor-mass",0.3,"likelihood"],["device-takeover",0.2,"likelihood"],["ransomware",0.2,"likelihood"],["phishing",0.1,"likelihood"]]},{"id":"PR.PS-03","ref":"PR.PS-03","title":"Hardware is maintained, replaced, and removed commensurate with risk","text":"","threats":[["end-of-life",0.4,"likelihood"],["network-device",0.3,"likelihood"],["device-takeover",0.3,"likelihood"],["known-exploited",0.2,"likelihood"],["physical-access",0.1,"likelihood"]]},{"id":"PR.PS-04","ref":"PR.PS-04","title":"Log records are generated and made available for continuous monitoring","text":"","threats":[["detection-blinding",0.3,"impact"],["insider-misuse",0.3,"impact"],["ransomware",0.2,"impact"],["data-theft",0.2,"impact"],["lateral-admin",0.2,"impact"],["directory-takeover",0.2,"impact"],["bec",0.2,"impact"],["third-party-access",0.2,"impact"]]},{"id":"PR.PS-05","ref":"PR.PS-05","title":"Installation and execution of unauthorized software are prevented","text":"","threats":[["phishing",0.4,"likelihood"],["ransomware",0.4,"likelihood"],["privilege-escalation",0.2,"likelihood"],["lateral-admin",0.1,"likelihood"],["supply-chain",0.1,"likelihood"]]},{"id":"PR.PS-06","ref":"PR.PS-06","title":"Secure software development practices are integrated, and their performance is monitored throughout the software development life cycle","text":"","threats":[["web-app",0.5,"likelihood"],["exploit-public",0.3,"likelihood"],["supply-chain",0.2,"likelihood"],["data-exposure",0.1,"likelihood"]]},{"id":"DE.AE-02","ref":"DE.AE-02","title":"Potentially adverse events are analyzed to better understand associated activities","text":"","threats":[["ransomware",0.2,"impact"],["directory-takeover",0.2,"impact"],["lateral-admin",0.2,"impact"],["data-theft",0.2,"impact"],["phishing",0.2,"impact"]]},{"id":"DE.AE-03","ref":"DE.AE-03","title":"Information is correlated from multiple sources","text":"","threats":[["detection-blinding",0.2,"impact"],["lateral-admin",0.2,"impact"],["directory-takeover",0.2,"impact"],["ransomware",0.2,"impact"]]},{"id":"DE.AE-04","ref":"DE.AE-04","title":"The estimated impact and scope of adverse events are understood","text":"","threats":[["ransomware",0.1,"impact"],["data-theft",0.1,"impact"]]},{"id":"DE.AE-06","ref":"DE.AE-06","title":"Information on adverse events is provided to authorized staff and tools","text":"","threats":[["ransomware",0.1,"impact"]]},{"id":"DE.AE-07","ref":"DE.AE-07","title":"Cyber threat intelligence and other contextual information are integrated into the analysis","text":"","threats":[["ransomware",0.2,"impact"],["supply-chain",0.2,"impact"],["phishing",0.1,"impact"]]},{"id":"DE.AE-08","ref":"DE.AE-08","title":"Incidents are declared when adverse events meet the defined incident criteria","text":"","threats":[["ransomware",0.1,"impact"]]},{"id":"DE.CM-01","ref":"DE.CM-01","title":"Networks and network services are monitored to find potentially adverse events","text":"","threats":[["lateral-admin",0.3,"impact"],["data-theft",0.3,"impact"],["ransomware",0.3,"impact"],["it-ot-pivot",0.3,"impact"],["wifi-intrusion",0.3,"impact"],["device-takeover",0.3,"impact"],["ddos",0.2,"impact"],["network-device",0.2,"impact"],["remote-access",0.2,"impact"]]},{"id":"DE.CM-02","ref":"DE.CM-02","title":"The physical environment is monitored to find potentially adverse events","text":"","threats":[["physical-access",0.3,"impact"]]},{"id":"DE.CM-03","ref":"DE.CM-03","title":"Personnel activity and technology usage are monitored to find potentially adverse events","text":"","threats":[["insider-misuse",0.4,"impact"],["remote-access",0.3,"impact"],["bec",0.3,"impact"],["third-party-access",0.3,"impact"],["lateral-admin",0.3,"impact"],["data-theft",0.3,"impact"],["directory-takeover",0.3,"impact"],["brute-force",0.2,"impact"]]},{"id":"DE.CM-06","ref":"DE.CM-06","title":"External service provider activities and services are monitored to find potentially adverse events","text":"","threats":[["third-party-access",0.4,"impact"],["supply-chain",0.2,"impact"],["internet-dependency",0.2,"impact"]]},{"id":"DE.CM-09","ref":"DE.CM-09","title":"Computing hardware and software, runtime environments, and their data are monitored to find potentially adverse events","text":"","threats":[["ransomware",0.4,"impact"],["privilege-escalation",0.3,"impact"],["detection-blinding",0.3,"impact"],["phishing",0.3,"impact"],["lateral-admin",0.3,"impact"],["exploit-public",0.3,"impact"],["defacement",0.3,"impact"],["directory-takeover",0.3,"impact"],["web-app",0.2,"impact"],["hypervisor-mass",0.2,"impact"],["ot-manipulation",0.2,"impact"],["supply-chain",0.2,"impact"]]},{"id":"RS.AN-03","ref":"RS.AN-03","title":"Analysis is performed to establish what has taken place during an incident and the root cause of the incident","text":"","threats":[["ransomware",0.2,"impact"],["directory-takeover",0.2,"impact"]]},{"id":"RS.AN-06","ref":"RS.AN-06","title":"Actions performed during an investigation are recorded, and the records' integrity and provenance are preserved","text":"","threats":[]},{"id":"RS.AN-07","ref":"RS.AN-07","title":"Incident data and metadata are collected, and their integrity and provenance are preserved","text":"","threats":[["insider-misuse",0.1,"impact"]]},{"id":"RS.AN-08","ref":"RS.AN-08","title":"An incident's magnitude is estimated and validated","text":"","threats":[["data-theft",0.1,"impact"]]},{"id":"RS.CO-02","ref":"RS.CO-02","title":"Internal and external stakeholders are notified of incidents","text":"","threats":[["bec",0.2,"impact"],["data-theft",0.1,"impact"]]},{"id":"RS.CO-03","ref":"RS.CO-03","title":"Information is shared with designated internal and external stakeholders","text":"","threats":[["defacement",0.1,"impact"]]},{"id":"RS.MA-01","ref":"RS.MA-01","title":"The incident response plan is executed in coordination with relevant third parties once an incident is declared","text":"","threats":[["ransomware",0.3,"impact"],["data-theft",0.2,"impact"],["directory-takeover",0.2,"impact"],["hypervisor-mass",0.2,"impact"],["bec",0.2,"impact"]]},{"id":"RS.MA-02","ref":"RS.MA-02","title":"Incident reports are triaged and validated","text":"","threats":[["ransomware",0.1,"impact"],["phishing",0.1,"impact"]]},{"id":"RS.MA-03","ref":"RS.MA-03","title":"Incidents are categorized and prioritized","text":"","threats":[]},{"id":"RS.MA-04","ref":"RS.MA-04","title":"Incidents are escalated or elevated as needed","text":"","threats":[["ransomware",0.1,"impact"]]},{"id":"RS.MA-05","ref":"RS.MA-05","title":"The criteria for initiating incident recovery are applied","text":"","threats":[["ransomware",0.1,"impact"]]},{"id":"RS.MI-01","ref":"RS.MI-01","title":"Incidents are contained","text":"","threats":[["ransomware",0.4,"impact"],["lateral-admin",0.3,"impact"],["data-theft",0.3,"impact"],["directory-takeover",0.3,"impact"],["hypervisor-mass",0.2,"impact"],["ddos",0.2,"impact"],["it-ot-pivot",0.2,"impact"],["phishing",0.2,"impact"],["bec",0.2,"impact"]]},{"id":"RS.MI-02","ref":"RS.MI-02","title":"Incidents are eradicated","text":"","threats":[["directory-takeover",0.3,"impact"],["ransomware",0.2,"impact"],["remote-access",0.1,"impact"],["phishing",0.1,"impact"]]},{"id":"RC.CO-03","ref":"RC.CO-03","title":"Recovery activities and progress in restoring operational capabilities are communicated to designated internal and external stakeholders","text":"","threats":[]},{"id":"RC.CO-04","ref":"RC.CO-04","title":"Public updates on incident recovery are shared using approved methods and messaging","text":"","threats":[["defacement",0.2,"impact"]]},{"id":"RC.RP-01","ref":"RC.RP-01","title":"The recovery portion of the incident response plan is executed once initiated from the incident response process","text":"","threats":[["ransomware",0.3,"impact"],["hypervisor-mass",0.3,"impact"],["directory-takeover",0.2,"impact"],["internet-dependency",0.1,"impact"]]},{"id":"RC.RP-02","ref":"RC.RP-02","title":"Recovery actions are selected, scoped, prioritized, and performed","text":"","threats":[["ransomware",0.2,"impact"],["hypervisor-mass",0.2,"impact"]]},{"id":"RC.RP-03","ref":"RC.RP-03","title":"The integrity of backups and other restoration assets is verified before using them for restoration","text":"","threats":[["ransomware",0.3,"impact"],["backup-destruction",0.3,"impact"]]},{"id":"RC.RP-04","ref":"RC.RP-04","title":"Critical mission functions and cybersecurity risk management are considered to establish post-incident operational norms","text":"","threats":[]},{"id":"RC.RP-05","ref":"RC.RP-05","title":"The integrity of restored assets is verified, systems and services are restored, and normal operating status is confirmed","text":"","threats":[["ransomware",0.2,"impact"],["directory-takeover",0.2,"impact"],["defacement",0.2,"impact"],["ot-manipulation",0.2,"impact"]]},{"id":"RC.RP-06","ref":"RC.RP-06","title":"The end of incident recovery is declared based on criteria, and incident-related documentation is completed","text":"","threats":[]}]},{"id":"cis-v8","name":"CIS Critical Security Controls v8.1","version":"8.1","license":"References only: safeguard titles are paraphrased; see cisecurity.org for the Controls.","url":"https://www.cisecurity.org/controls","requirements":[{"id":"1.1","ref":"1.1","title":"Complete register of hardware assets","text":"","ig":1,"threats":[["device-takeover",0.2,"likelihood"],["known-exploited",0.1,"likelihood"],["end-of-life",0.1,"likelihood"]]},{"id":"1.2","ref":"1.2","title":"Deal with devices not approved","text":"","ig":1,"threats":[["device-takeover",0.2,"likelihood"],["wifi-intrusion",0.2,"impact"],["physical-access",0.1,"impact"]]},{"id":"1.3","ref":"1.3","title":"Active scanning to discover devices","text":"","ig":2,"threats":[["device-takeover",0.2,"likelihood"],["wifi-intrusion",0.2,"impact"]]},{"id":"1.4","ref":"1.4","title":"Feed the asset register from DHCP records","text":"","ig":2,"threats":[["device-takeover",0.1,"likelihood"]]},{"id":"1.5","ref":"1.5","title":"Passive traffic listening to discover devices","text":"","ig":3,"threats":[["device-takeover",0.1,"likelihood"]]},{"id":"2.1","ref":"2.1","title":"Register of installed software","text":"","ig":1,"threats":[["end-of-life",0.2,"likelihood"],["known-exploited",0.2,"likelihood"]]},{"id":"2.2","ref":"2.2","title":"Only vendor-supported software in use","text":"","ig":1,"threats":[["end-of-life",0.6,"likelihood"],["known-exploited",0.2,"likelihood"]]},{"id":"2.3","ref":"2.3","title":"Remove or approve unlisted software","text":"","ig":1,"threats":[["end-of-life",0.1,"likelihood"],["ransomware",0.1,"likelihood"],["supply-chain",0.1,"likelihood"]]},{"id":"2.4","ref":"2.4","title":"Automated software inventory tooling","text":"","ig":2,"threats":[["end-of-life",0.1,"likelihood"],["known-exploited",0.1,"likelihood"]]},{"id":"2.5","ref":"2.5","title":"Application allowlisting for programs","text":"","ig":2,"threats":[["ransomware",0.5,"likelihood"],["phishing",0.4,"likelihood"],["privilege-escalation",0.2,"likelihood"],["lateral-admin",0.2,"likelihood"],["supply-chain",0.1,"likelihood"],["insider-misuse",0.1,"likelihood"]]},{"id":"2.6","ref":"2.6","title":"Allowlisting for code libraries","text":"","ig":2,"threats":[["ransomware",0.2,"likelihood"],["phishing",0.2,"likelihood"],["privilege-escalation",0.1,"likelihood"]]},{"id":"2.7","ref":"2.7","title":"Allowlisting or signing for scripts","text":"","ig":3,"threats":[["phishing",0.3,"likelihood"],["ransomware",0.3,"likelihood"],["lateral-admin",0.1,"likelihood"]]},{"id":"3.1","ref":"3.1","title":"Rules for handling sensitive data","text":"","ig":1,"threats":[["data-exposure",0.1,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"3.2","ref":"3.2","title":"Register of sensitive data","text":"","ig":1,"threats":[["data-exposure",0.2,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"3.3","ref":"3.3","title":"Permissions restricting who reads data","text":"","ig":1,"threats":[["data-exposure",0.5,"likelihood"],["insider-misuse",0.3,"likelihood"],["data-theft",0.3,"impact"],["ransomware",0.1,"impact"]]},{"id":"3.4","ref":"3.4","title":"Delete data past its retention period","text":"","ig":1,"threats":[["data-theft",0.3,"impact"],["data-exposure",0.2,"impact"]]},{"id":"3.5","ref":"3.5","title":"Safe destruction of data","text":"","ig":1,"threats":[["data-theft",0.2,"likelihood"],["physical-access",0.2,"impact"]]},{"id":"3.6","ref":"3.6","title":"Disk encryption on laptops and workstations","text":"","ig":1,"threats":[["physical-access",0.6,"impact"],["data-theft",0.2,"impact"]]},{"id":"3.7","ref":"3.7","title":"Data sensitivity classification","text":"","ig":2,"threats":[["data-exposure",0.1,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"3.8","ref":"3.8","title":"Map of data movements","text":"","ig":2,"threats":[["data-exposure",0.1,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"3.9","ref":"3.9","title":"Encryption of USB and removable media","text":"","ig":2,"threats":[["physical-access",0.4,"impact"],["data-theft",0.2,"impact"]]},{"id":"3.10","ref":"3.10","title":"Encryption of sensitive data over networks","text":"","ig":2,"threats":[["data-theft",0.2,"likelihood"],["wifi-intrusion",0.2,"impact"],["lateral-admin",0.1,"likelihood"]]},{"id":"3.11","ref":"3.11","title":"Encryption of stored sensitive data","text":"","ig":2,"threats":[["data-theft",0.4,"impact"],["physical-access",0.3,"impact"],["data-exposure",0.3,"impact"]]},{"id":"3.12","ref":"3.12","title":"Separate storage by data sensitivity","text":"","ig":2,"threats":[["data-theft",0.3,"impact"],["data-exposure",0.2,"impact"],["lateral-admin",0.1,"likelihood"]]},{"id":"3.13","ref":"3.13","title":"Data leak prevention tooling","text":"","ig":3,"threats":[["data-theft",0.4,"impact"],["insider-misuse",0.3,"impact"],["data-exposure",0.2,"likelihood"]]},{"id":"3.14","ref":"3.14","title":"Logging of sensitive data access","text":"","ig":3,"threats":[["insider-misuse",0.3,"impact"],["data-theft",0.2,"impact"]]},{"id":"4.1","ref":"4.1","title":"Secure baseline configuration process","text":"","ig":1,"threats":[["default-credentials",0.3,"likelihood"],["data-exposure",0.3,"likelihood"],["exploit-public",0.2,"likelihood"],["privilege-escalation",0.2,"likelihood"],["device-takeover",0.2,"likelihood"],["lateral-admin",0.2,"likelihood"],["hypervisor-mass",0.2,"likelihood"]]},{"id":"4.2","ref":"4.2","title":"Hardening baseline for network equipment","text":"","ig":1,"threats":[["network-device",0.4,"likelihood"],["default-credentials",0.3,"likelihood"],["wifi-intrusion",0.2,"likelihood"]]},{"id":"4.3","ref":"4.3","title":"Lock idle sessions automatically","text":"","ig":1,"threats":[["physical-access",0.2,"likelihood"],["insider-misuse",0.1,"likelihood"]]},{"id":"4.4","ref":"4.4","title":"Host firewall on servers","text":"","ig":1,"threats":[["lateral-admin",0.3,"likelihood"],["exploit-public",0.2,"likelihood"],["data-exposure",0.2,"likelihood"],["ransomware",0.2,"impact"]]},{"id":"4.5","ref":"4.5","title":"Host firewall on user devices","text":"","ig":1,"threats":[["lateral-admin",0.3,"likelihood"],["ransomware",0.2,"impact"],["wifi-intrusion",0.2,"impact"]]},{"id":"4.6","ref":"4.6","title":"Administer systems over secure channels","text":"","ig":1,"threats":[["network-device",0.2,"likelihood"],["lateral-admin",0.1,"likelihood"],["hypervisor-mass",0.1,"likelihood"]]},{"id":"4.7","ref":"4.7","title":"Disable or change factory default accounts","text":"","ig":1,"threats":[["default-credentials",0.6,"likelihood"],["device-takeover",0.3,"likelihood"],["network-device",0.3,"likelihood"],["brute-force",0.2,"likelihood"],["lateral-admin",0.2,"likelihood"]]},{"id":"4.8","ref":"4.8","title":"Turn off unneeded services and ports","text":"","ig":2,"threats":[["exploit-public",0.3,"likelihood"],["lateral-admin",0.2,"likelihood"],["device-takeover",0.2,"likelihood"],["network-device",0.2,"likelihood"],["privilege-escalation",0.1,"likelihood"]]},{"id":"4.9","ref":"4.9","title":"Point devices at trusted DNS resolvers","text":"","ig":2,"threats":[["phishing",0.1,"likelihood"],["ransomware",0.1,"likelihood"]]},{"id":"4.10","ref":"4.10","title":"Lock mobile devices after failed unlocks","text":"","ig":2,"threats":[["physical-access",0.3,"likelihood"]]},{"id":"4.11","ref":"4.11","title":"Remote wipe for mobile devices","text":"","ig":2,"threats":[["physical-access",0.4,"impact"],["data-theft",0.1,"impact"]]},{"id":"4.12","ref":"4.12","title":"Isolate work data on mobile devices","text":"","ig":3,"threats":[["device-takeover",0.2,"impact"],["data-theft",0.1,"impact"]]},{"id":"5.1","ref":"5.1","title":"Register of all user accounts","text":"","ig":1,"threats":[["insider-misuse",0.2,"likelihood"],["third-party-access",0.2,"likelihood"],["remote-access",0.1,"likelihood"]]},{"id":"5.2","ref":"5.2","title":"Distinct strong password per account","text":"","ig":1,"threats":[["brute-force",0.4,"likelihood"],["default-credentials",0.4,"likelihood"],["lateral-admin",0.3,"likelihood"],["remote-access",0.2,"likelihood"],["directory-takeover",0.1,"likelihood"]]},{"id":"5.3","ref":"5.3","title":"Disable accounts left unused","text":"","ig":1,"threats":[["insider-misuse",0.3,"likelihood"],["remote-access",0.2,"likelihood"],["brute-force",0.2,"likelihood"],["third-party-access",0.2,"likelihood"]]},{"id":"5.4","ref":"5.4","title":"Separate admin accounts from daily use","text":"","ig":1,"threats":[["directory-takeover",0.3,"likelihood"],["lateral-admin",0.3,"likelihood"],["phishing",0.3,"impact"],["ransomware",0.2,"impact"]]},{"id":"5.5","ref":"5.5","title":"Register of service accounts","text":"","ig":2,"threats":[["directory-takeover",0.2,"likelihood"],["lateral-admin",0.1,"likelihood"]]},{"id":"5.6","ref":"5.6","title":"Manage accounts from a central directory","text":"","ig":2,"threats":[["insider-misuse",0.1,"likelihood"],["remote-access",0.1,"likelihood"],["third-party-access",0.1,"likelihood"]]},{"id":"6.1","ref":"6.1","title":"Formal process to give access","text":"","ig":1,"threats":[["insider-misuse",0.2,"likelihood"],["third-party-access",0.1,"likelihood"]]},{"id":"6.2","ref":"6.2","title":"Formal process to withdraw access","text":"","ig":1,"threats":[["insider-misuse",0.3,"likelihood"],["third-party-access",0.3,"likelihood"],["remote-access",0.2,"likelihood"]]},{"id":"6.3","ref":"6.3","title":"MFA on Internet-facing applications","text":"","ig":1,"threats":[["brute-force",0.6,"likelihood"],["bec",0.5,"likelihood"],["phishing",0.3,"likelihood"],["defacement",0.2,"likelihood"]]},{"id":"6.4","ref":"6.4","title":"MFA on VPN and remote entry","text":"","ig":1,"threats":[["remote-access",0.6,"likelihood"],["brute-force",0.4,"likelihood"],["third-party-access",0.3,"likelihood"],["ransomware",0.2,"likelihood"]]},{"id":"6.5","ref":"6.5","title":"MFA for administrator logins","text":"","ig":1,"threats":[["directory-takeover",0.4,"likelihood"],["lateral-admin",0.4,"likelihood"],["hypervisor-mass",0.4,"likelihood"],["network-device",0.3,"likelihood"],["ransomware",0.2,"likelihood"]]},{"id":"6.6","ref":"6.6","title":"List of authentication and authorisation systems","text":"","ig":2,"threats":[["remote-access",0.1,"likelihood"],["brute-force",0.1,"likelihood"]]},{"id":"6.7","ref":"6.7","title":"Central access control, e.g. single sign-on","text":"","ig":2,"threats":[["brute-force",0.2,"likelihood"],["third-party-access",0.2,"likelihood"],["remote-access",0.1,"likelihood"],["insider-misuse",0.1,"likelihood"]]},{"id":"6.8","ref":"6.8","title":"Permissions assigned by job role","text":"","ig":3,"threats":[["insider-misuse",0.3,"likelihood"],["data-exposure",0.2,"likelihood"],["data-theft",0.2,"impact"],["lateral-admin",0.1,"likelihood"]]},{"id":"7.1","ref":"7.1","title":"Documented vulnerability handling process","text":"","ig":1,"threats":[["known-exploited",0.2,"likelihood"],["exploit-public",0.1,"likelihood"]]},{"id":"7.2","ref":"7.2","title":"Risk-based fix prioritisation process","text":"","ig":1,"threats":[["known-exploited",0.3,"likelihood"],["exploit-public",0.2,"likelihood"]]},{"id":"7.3","ref":"7.3","title":"Automatic operating system patching","text":"","ig":1,"threats":[["known-exploited",0.5,"likelihood"],["privilege-escalation",0.4,"likelihood"],["exploit-public",0.3,"likelihood"],["ransomware",0.2,"likelihood"],["lateral-admin",0.2,"likelihood"]]},{"id":"7.4","ref":"7.4","title":"Automatic application patching","text":"","ig":1,"threats":[["known-exploited",0.4,"likelihood"],["exploit-public",0.3,"likelihood"],["phishing",0.2,"likelihood"],["web-app",0.2,"likelihood"]]},{"id":"7.5","ref":"7.5","title":"Vulnerability scanning of internal assets","text":"","ig":2,"threats":[["known-exploited",0.3,"likelihood"],["privilege-escalation",0.2,"likelihood"],["end-of-life",0.2,"likelihood"],["default-credentials",0.2,"likelihood"],["hypervisor-mass",0.2,"likelihood"]]},{"id":"7.6","ref":"7.6","title":"Vulnerability scanning of Internet-facing assets","text":"","ig":2,"threats":[["exploit-public",0.4,"likelihood"],["known-exploited",0.4,"likelihood"],["web-app",0.3,"likelihood"],["network-device",0.3,"likelihood"],["data-exposure",0.3,"likelihood"],["remote-access",0.2,"likelihood"]]},{"id":"7.7","ref":"7.7","title":"Fix vulnerabilities found by scans","text":"","ig":2,"threats":[["known-exploited",0.4,"likelihood"],["exploit-public",0.3,"likelihood"],["web-app",0.2,"likelihood"],["privilege-escalation",0.2,"likelihood"],["network-device",0.2,"likelihood"]]},{"id":"8.1","ref":"8.1","title":"Documented log management process","text":"","ig":1,"threats":[["detection-blinding",0.1,"impact"],["insider-misuse",0.1,"impact"]]},{"id":"8.2","ref":"8.2","title":"Logging turned on across assets","text":"","ig":1,"threats":[["insider-misuse",0.2,"impact"],["detection-blinding",0.1,"impact"],["lateral-admin",0.1,"impact"],["data-theft",0.1,"impact"]]},{"id":"8.3","ref":"8.3","title":"Enough storage for logs","text":"","ig":1,"threats":[["detection-blinding",0.1,"impact"]]},{"id":"8.4","ref":"8.4","title":"Common time source for all systems","text":"","ig":2,"threats":[]},{"id":"8.5","ref":"8.5","title":"Detailed event logging","text":"","ig":2,"threats":[["insider-misuse",0.2,"impact"],["lateral-admin",0.2,"impact"],["data-theft",0.2,"impact"]]},{"id":"8.6","ref":"8.6","title":"Logging of DNS lookups","text":"","ig":2,"threats":[["phishing",0.2,"impact"],["data-theft",0.2,"impact"],["ransomware",0.1,"impact"]]},{"id":"8.7","ref":"8.7","title":"Logging of web requests","text":"","ig":2,"threats":[["phishing",0.2,"impact"],["data-theft",0.1,"impact"]]},{"id":"8.8","ref":"8.8","title":"Logging of commands and scripts run","text":"","ig":2,"threats":[["lateral-admin",0.3,"impact"],["privilege-escalation",0.2,"impact"],["ransomware",0.2,"impact"],["insider-misuse",0.2,"impact"]]},{"id":"8.9","ref":"8.9","title":"Central log collection","text":"","ig":2,"threats":[["detection-blinding",0.5,"impact"],["ransomware",0.2,"impact"],["lateral-admin",0.2,"impact"]]},{"id":"8.10","ref":"8.10","title":"Keep logs long enough","text":"","ig":2,"threats":[["detection-blinding",0.1,"impact"],["insider-misuse",0.1,"impact"],["data-theft",0.1,"impact"]]},{"id":"8.11","ref":"8.11","title":"Regular review of logs","text":"","ig":2,"threats":[["lateral-admin",0.2,"impact"],["insider-misuse",0.2,"impact"],["remote-access",0.2,"impact"],["brute-force",0.2,"impact"],["directory-takeover",0.2,"impact"]]},{"id":"8.12","ref":"8.12","title":"Gather logs from service providers","text":"","ig":3,"threats":[["third-party-access",0.3,"impact"],["bec",0.2,"impact"]]},{"id":"9.1","ref":"9.1","title":"Supported browsers and mail clients only","text":"","ig":1,"threats":[["phishing",0.3,"likelihood"],["end-of-life",0.3,"likelihood"],["known-exploited",0.2,"likelihood"]]},{"id":"9.2","ref":"9.2","title":"DNS filtering of malicious domains","text":"","ig":1,"threats":[["phishing",0.4,"likelihood"],["ransomware",0.2,"likelihood"],["data-theft",0.1,"impact"]]},{"id":"9.3","ref":"9.3","title":"Web filtering by URL or category","text":"","ig":2,"threats":[["phishing",0.3,"likelihood"],["ransomware",0.1,"likelihood"],["data-theft",0.1,"impact"]]},{"id":"9.4","ref":"9.4","title":"Limit browser and mail extensions","text":"","ig":2,"threats":[["phishing",0.2,"likelihood"],["data-theft",0.1,"likelihood"],["supply-chain",0.1,"likelihood"]]},{"id":"9.5","ref":"9.5","title":"DMARC on mail domains","text":"","ig":2,"threats":[["bec",0.5,"likelihood"],["phishing",0.2,"likelihood"]]},{"id":"9.6","ref":"9.6","title":"Block risky attachment file types","text":"","ig":2,"threats":[["phishing",0.4,"likelihood"],["ransomware",0.3,"likelihood"]]},{"id":"9.7","ref":"9.7","title":"Malware scanning at the mail server","text":"","ig":3,"threats":[["phishing",0.4,"likelihood"],["ransomware",0.2,"likelihood"]]},{"id":"10.1","ref":"10.1","title":"Anti-malware on every asset","text":"","ig":1,"threats":[["ransomware",0.4,"likelihood"],["phishing",0.3,"likelihood"]]},{"id":"10.2","ref":"10.2","title":"Automatic anti-malware definition updates","text":"","ig":1,"threats":[["ransomware",0.2,"likelihood"],["phishing",0.2,"likelihood"]]},{"id":"10.3","ref":"10.3","title":"No autorun from removable media","text":"","ig":1,"threats":[["physical-access",0.3,"likelihood"]]},{"id":"10.4","ref":"10.4","title":"Scan removable media when inserted","text":"","ig":2,"threats":[["physical-access",0.2,"likelihood"]]},{"id":"10.5","ref":"10.5","title":"Operating system exploit mitigations turned on","text":"","ig":2,"threats":[["privilege-escalation",0.3,"likelihood"],["exploit-public",0.2,"likelihood"],["phishing",0.2,"likelihood"],["ransomware",0.2,"likelihood"],["lateral-admin",0.1,"likelihood"]]},{"id":"10.6","ref":"10.6","title":"Central console for anti-malware","text":"","ig":2,"threats":[["detection-blinding",0.3,"likelihood"],["ransomware",0.2,"likelihood"]]},{"id":"10.7","ref":"10.7","title":"Behaviour-based malware detection","text":"","ig":2,"threats":[["ransomware",0.4,"likelihood"],["phishing",0.2,"likelihood"],["privilege-escalation",0.2,"likelihood"],["lateral-admin",0.2,"impact"]]},{"id":"11.1","ref":"11.1","title":"Documented data recovery process","text":"","ig":1,"threats":[["ransomware",0.3,"impact"],["hypervisor-mass",0.3,"impact"],["backup-destruction",0.1,"impact"]]},{"id":"11.2","ref":"11.2","title":"Scheduled automatic backups","text":"","ig":1,"threats":[["ransomware",0.5,"impact"],["hypervisor-mass",0.4,"impact"],["insider-misuse",0.3,"impact"],["defacement",0.3,"impact"],["ot-manipulation",0.2,"impact"],["directory-takeover",0.2,"impact"]]},{"id":"11.3","ref":"11.3","title":"Protect backups like the source data","text":"","ig":1,"threats":[["backup-destruction",0.3,"likelihood"],["ransomware",0.2,"impact"],["data-theft",0.2,"likelihood"]]},{"id":"11.4","ref":"11.4","title":"Isolated, offline or immutable backup copy","text":"","ig":1,"threats":[["backup-destruction",0.6,"likelihood"],["ransomware",0.6,"impact"],["hypervisor-mass",0.5,"impact"],["insider-misuse",0.3,"impact"]]},{"id":"11.5","ref":"11.5","title":"Regular restore tests","text":"","ig":2,"threats":[["ransomware",0.3,"impact"],["hypervisor-mass",0.3,"impact"],["directory-takeover",0.2,"impact"]]},{"id":"12.1","ref":"12.1","title":"Current firmware on network equipment","text":"","ig":1,"threats":[["network-device",0.5,"likelihood"],["known-exploited",0.4,"likelihood"],["end-of-life",0.3,"likelihood"],["remote-access",0.2,"likelihood"]]},{"id":"12.2","ref":"12.2","title":"Segmented, secure network design","text":"","ig":2,"threats":[["it-ot-pivot",0.5,"likelihood"],["lateral-admin",0.4,"likelihood"],["ransomware",0.3,"impact"],["device-takeover",0.3,"impact"],["wifi-intrusion",0.3,"impact"],["exploit-public",0.2,"impact"],["hypervisor-mass",0.2,"likelihood"],["data-exposure",0.2,"likelihood"]]},{"id":"12.3","ref":"12.3","title":"Secure administration of network equipment","text":"","ig":2,"threats":[["network-device",0.4,"likelihood"],["default-credentials",0.2,"likelihood"]]},{"id":"12.4","ref":"12.4","title":"Up-to-date network diagrams","text":"","ig":2,"threats":[["it-ot-pivot",0.1,"likelihood"],["lateral-admin",0.1,"likelihood"]]},{"id":"12.5","ref":"12.5","title":"Central AAA for network devices","text":"","ig":2,"threats":[["network-device",0.3,"likelihood"],["wifi-intrusion",0.2,"likelihood"],["insider-misuse",0.2,"impact"]]},{"id":"12.6","ref":"12.6","title":"Encrypted management and network protocols","text":"","ig":2,"threats":[["wifi-intrusion",0.3,"likelihood"],["network-device",0.2,"likelihood"],["lateral-admin",0.1,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"12.7","ref":"12.7","title":"Remote users routed through VPN with central auth","text":"","ig":2,"threats":[["remote-access",0.2,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"12.8","ref":"12.8","title":"Dedicated isolated machines for admin work","text":"","ig":3,"threats":[["directory-takeover",0.4,"likelihood"],["lateral-admin",0.4,"likelihood"],["hypervisor-mass",0.3,"likelihood"],["network-device",0.2,"likelihood"],["phishing",0.3,"impact"]]},{"id":"13.1","ref":"13.1","title":"Central correlation and alerting of events","text":"","ig":2,"threats":[["ransomware",0.3,"impact"],["lateral-admin",0.3,"impact"],["directory-takeover",0.3,"impact"],["detection-blinding",0.3,"impact"],["brute-force",0.2,"impact"],["remote-access",0.2,"impact"]]},{"id":"13.2","ref":"13.2","title":"Host-based intrusion detection","text":"","ig":2,"threats":[["privilege-escalation",0.3,"impact"],["ransomware",0.3,"impact"],["lateral-admin",0.3,"impact"],["exploit-public",0.2,"impact"],["phishing",0.2,"impact"]]},{"id":"13.3","ref":"13.3","title":"Network-based intrusion detection","text":"","ig":2,"threats":[["lateral-admin",0.3,"impact"],["it-ot-pivot",0.3,"impact"],["exploit-public",0.2,"impact"],["data-theft",0.2,"impact"],["device-takeover",0.2,"impact"]]},{"id":"13.4","ref":"13.4","title":"Filtering between network zones","text":"","ig":2,"threats":[["lateral-admin",0.5,"likelihood"],["it-ot-pivot",0.5,"likelihood"],["ransomware",0.4,"impact"],["device-takeover",0.3,"impact"],["hypervisor-mass",0.2,"likelihood"],["data-exposure",0.2,"likelihood"]]},{"id":"13.5","ref":"13.5","title":"Access control for remote endpoints","text":"","ig":2,"threats":[["remote-access",0.3,"likelihood"],["third-party-access",0.2,"likelihood"]]},{"id":"13.6","ref":"13.6","title":"Network flow logging","text":"","ig":2,"threats":[["data-theft",0.3,"impact"],["lateral-admin",0.2,"impact"]]},{"id":"13.7","ref":"13.7","title":"Host-based intrusion prevention","text":"","ig":3,"threats":[["ransomware",0.3,"likelihood"],["exploit-public",0.2,"likelihood"],["privilege-escalation",0.2,"likelihood"]]},{"id":"13.8","ref":"13.8","title":"Network-based intrusion prevention","text":"","ig":3,"threats":[["exploit-public",0.3,"likelihood"],["known-exploited",0.2,"likelihood"],["lateral-admin",0.2,"likelihood"]]},{"id":"13.9","ref":"13.9","title":"Device authentication on switch ports (802.1X)","text":"","ig":3,"threats":[["physical-access",0.3,"likelihood"],["wifi-intrusion",0.3,"likelihood"],["device-takeover",0.1,"impact"]]},{"id":"13.10","ref":"13.10","title":"Application-layer filtering (WAF, proxy)","text":"","ig":3,"threats":[["web-app",0.4,"likelihood"],["exploit-public",0.3,"likelihood"],["data-theft",0.2,"likelihood"],["ddos",0.2,"impact"]]},{"id":"13.11","ref":"13.11","title":"Tuning of alert thresholds","text":"","ig":3,"threats":[["ransomware",0.1,"impact"]]},{"id":"14.1","ref":"14.1","title":"Security awareness programme","text":"","ig":1,"threats":[["phishing",0.3,"likelihood"],["bec",0.3,"likelihood"]]},{"id":"14.2","ref":"14.2","title":"Training to spot social engineering","text":"","ig":1,"threats":[["phishing",0.4,"likelihood"],["bec",0.4,"likelihood"]]},{"id":"14.3","ref":"14.3","title":"Training on passwords and MFA use","text":"","ig":1,"threats":[["brute-force",0.2,"likelihood"],["remote-access",0.2,"likelihood"],["phishing",0.1,"likelihood"]]},{"id":"14.4","ref":"14.4","title":"Training on handling sensitive data","text":"","ig":1,"threats":[["data-exposure",0.2,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"14.5","ref":"14.5","title":"Training on accidental data disclosure","text":"","ig":1,"threats":[["data-exposure",0.3,"likelihood"]]},{"id":"14.6","ref":"14.6","title":"Training to report suspected incidents","text":"","ig":1,"threats":[["phishing",0.3,"impact"],["bec",0.2,"impact"],["physical-access",0.1,"impact"]]},{"id":"14.7","ref":"14.7","title":"Training to report missing updates","text":"","ig":1,"threats":[["known-exploited",0.1,"likelihood"]]},{"id":"14.8","ref":"14.8","title":"Training on risks of untrusted networks","text":"","ig":1,"threats":[["wifi-intrusion",0.2,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"14.9","ref":"14.9","title":"Security training tailored to job roles","text":"","ig":2,"threats":[["phishing",0.2,"likelihood"],["bec",0.2,"likelihood"],["web-app",0.2,"likelihood"],["data-exposure",0.2,"likelihood"]]},{"id":"15.1","ref":"15.1","title":"Register of service providers","text":"","ig":1,"threats":[["third-party-access",0.2,"likelihood"],["internet-dependency",0.2,"impact"],["supply-chain",0.1,"likelihood"]]},{"id":"15.2","ref":"15.2","title":"Policy for managing service providers","text":"","ig":2,"threats":[["third-party-access",0.2,"likelihood"],["supply-chain",0.1,"likelihood"]]},{"id":"15.3","ref":"15.3","title":"Rank service providers by risk","text":"","ig":2,"threats":[["supply-chain",0.1,"likelihood"],["third-party-access",0.1,"likelihood"],["internet-dependency",0.1,"impact"]]},{"id":"15.4","ref":"15.4","title":"Security clauses in supplier contracts","text":"","ig":2,"threats":[["third-party-access",0.3,"likelihood"],["supply-chain",0.2,"likelihood"],["internet-dependency",0.2,"impact"]]},{"id":"15.5","ref":"15.5","title":"Assessment of service providers' security","text":"","ig":3,"threats":[["supply-chain",0.3,"likelihood"],["third-party-access",0.3,"likelihood"]]},{"id":"15.6","ref":"15.6","title":"Ongoing monitoring of service providers","text":"","ig":3,"threats":[["third-party-access",0.3,"impact"],["supply-chain",0.2,"impact"],["internet-dependency",0.2,"impact"]]},{"id":"15.7","ref":"15.7","title":"Secure offboarding of service providers","text":"","ig":3,"threats":[["third-party-access",0.3,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"16.1","ref":"16.1","title":"Secure software development lifecycle","text":"","ig":2,"threats":[["web-app",0.4,"likelihood"],["exploit-public",0.2,"likelihood"]]},{"id":"16.2","ref":"16.2","title":"Intake and handling of reported software flaws","text":"","ig":2,"threats":[["web-app",0.3,"likelihood"],["exploit-public",0.2,"likelihood"]]},{"id":"16.3","ref":"16.3","title":"Root-cause analysis of code flaws","text":"","ig":2,"threats":[["web-app",0.2,"likelihood"]]},{"id":"16.4","ref":"16.4","title":"Inventory of third-party code components","text":"","ig":2,"threats":[["supply-chain",0.3,"likelihood"],["web-app",0.2,"likelihood"],["known-exploited",0.2,"likelihood"]]},{"id":"16.5","ref":"16.5","title":"Current, trusted third-party components","text":"","ig":2,"threats":[["supply-chain",0.4,"likelihood"],["web-app",0.3,"likelihood"],["known-exploited",0.2,"likelihood"]]},{"id":"16.6","ref":"16.6","title":"Severity rating for application flaws","text":"","ig":2,"threats":[["web-app",0.1,"likelihood"]]},{"id":"16.7","ref":"16.7","title":"Hardened templates for application infrastructure","text":"","ig":2,"threats":[["data-exposure",0.3,"likelihood"],["web-app",0.2,"likelihood"],["default-credentials",0.2,"likelihood"]]},{"id":"16.8","ref":"16.8","title":"Production kept apart from test systems","text":"","ig":2,"threats":[["data-exposure",0.3,"likelihood"],["data-theft",0.2,"likelihood"],["web-app",0.1,"likelihood"],["insider-misuse",0.1,"likelihood"]]},{"id":"16.9","ref":"16.9","title":"Secure-coding training for developers","text":"","ig":2,"threats":[["web-app",0.3,"likelihood"]]},{"id":"16.10","ref":"16.10","title":"Secure design of application architecture","text":"","ig":2,"threats":[["web-app",0.3,"likelihood"],["data-exposure",0.2,"likelihood"]]},{"id":"16.11","ref":"16.11","title":"Reuse vetted security modules (auth, crypto)","text":"","ig":2,"threats":[["web-app",0.3,"likelihood"]]},{"id":"16.12","ref":"16.12","title":"Automated code security analysis","text":"","ig":3,"threats":[["web-app",0.4,"likelihood"],["supply-chain",0.1,"likelihood"]]},{"id":"16.13","ref":"16.13","title":"Penetration tests of applications","text":"","ig":3,"threats":[["web-app",0.4,"likelihood"],["exploit-public",0.2,"likelihood"],["data-exposure",0.2,"likelihood"]]},{"id":"16.14","ref":"16.14","title":"Threat modelling of applications","text":"","ig":3,"threats":[["web-app",0.2,"likelihood"]]},{"id":"17.1","ref":"17.1","title":"Named lead for incident handling","text":"","ig":1,"threats":[["ransomware",0.1,"impact"]]},{"id":"17.2","ref":"17.2","title":"Up-to-date incident contact list","text":"","ig":1,"threats":[["ransomware",0.1,"impact"],["bec",0.1,"impact"]]},{"id":"17.3","ref":"17.3","title":"Way for staff to report incidents","text":"","ig":1,"threats":[["phishing",0.2,"impact"],["bec",0.2,"impact"],["insider-misuse",0.1,"impact"]]},{"id":"17.4","ref":"17.4","title":"Documented incident response process","text":"","ig":2,"threats":[["ransomware",0.3,"impact"],["data-theft",0.2,"impact"],["directory-takeover",0.2,"impact"],["hypervisor-mass",0.2,"impact"],["bec",0.2,"impact"]]},{"id":"17.5","ref":"17.5","title":"Incident response roles assigned","text":"","ig":2,"threats":[["ransomware",0.1,"impact"]]},{"id":"17.6","ref":"17.6","title":"Communication channels during incidents","text":"","ig":2,"threats":[["ransomware",0.2,"impact"],["directory-takeover",0.1,"impact"],["defacement",0.1,"impact"]]},{"id":"17.7","ref":"17.7","title":"Regular incident response exercises","text":"","ig":2,"threats":[["ransomware",0.3,"impact"],["hypervisor-mass",0.2,"impact"],["ddos",0.1,"impact"]]},{"id":"17.8","ref":"17.8","title":"Lessons-learned review after incidents","text":"","ig":2,"threats":[["ransomware",0.1,"impact"]]},{"id":"17.9","ref":"17.9","title":"Thresholds that define an incident","text":"","ig":3,"threats":[["ransomware",0.1,"impact"]]},{"id":"18.1","ref":"18.1","title":"Penetration testing programme","text":"","ig":2,"threats":[["exploit-public",0.2,"likelihood"],["lateral-admin",0.1,"likelihood"],["directory-takeover",0.1,"likelihood"]]},{"id":"18.2","ref":"18.2","title":"External penetration tests","text":"","ig":2,"threats":[["exploit-public",0.3,"likelihood"],["web-app",0.3,"likelihood"],["remote-access",0.2,"likelihood"],["data-exposure",0.2,"likelihood"],["network-device",0.2,"likelihood"]]},{"id":"18.3","ref":"18.3","title":"Fix penetration test findings","text":"","ig":2,"threats":[["exploit-public",0.3,"likelihood"],["web-app",0.2,"likelihood"],["directory-takeover",0.2,"likelihood"],["lateral-admin",0.2,"likelihood"]]},{"id":"18.4","ref":"18.4","title":"Test that security controls actually work","text":"","ig":3,"threats":[["detection-blinding",0.2,"impact"],["lateral-admin",0.1,"impact"]]},{"id":"18.5","ref":"18.5","title":"Internal penetration tests","text":"","ig":3,"threats":[["directory-takeover",0.3,"likelihood"],["lateral-admin",0.3,"likelihood"],["privilege-escalation",0.2,"likelihood"],["it-ot-pivot",0.2,"likelihood"],["default-credentials",0.2,"likelihood"]]}]},{"id":"iso27001","name":"ISO/IEC 27001:2022 Annex A","version":"2022","license":"References only: the control titles are paraphrased; the standard's text is not reproduced.","url":"https://www.iso.org/standard/27001","requirements":[{"id":"5.1","ref":"5.1","title":"Approved set of security policies","text":"","threats":[]},{"id":"5.2","ref":"5.2","title":"Assigning security roles","text":"","threats":[]},{"id":"5.3","ref":"5.3","title":"Separating conflicting duties","text":"","threats":[["insider-misuse",0.3,"likelihood"],["bec",0.2,"likelihood"]]},{"id":"5.4","ref":"5.4","title":"Management enforcing security rules","text":"","threats":[]},{"id":"5.5","ref":"5.5","title":"Relationship with relevant authorities","text":"","threats":[["ransomware",0.1,"impact"]]},{"id":"5.6","ref":"5.6","title":"Links with security communities and forums","text":"","threats":[["known-exploited",0.1,"likelihood"]]},{"id":"5.7","ref":"5.7","title":"Collecting and using threat information","text":"","threats":[["known-exploited",0.2,"likelihood"],["phishing",0.1,"likelihood"]]},{"id":"5.8","ref":"5.8","title":"Security built into projects","text":"","threats":[["web-app",0.1,"likelihood"],["data-exposure",0.1,"likelihood"]]},{"id":"5.9","ref":"5.9","title":"Inventory of information assets and owners","text":"","threats":[["end-of-life",0.2,"likelihood"],["known-exploited",0.1,"likelihood"],["data-exposure",0.1,"likelihood"]]},{"id":"5.10","ref":"5.10","title":"Rules for permitted use of assets","text":"","threats":[["insider-misuse",0.1,"likelihood"],["phishing",0.1,"likelihood"]]},{"id":"5.11","ref":"5.11","title":"Handing back assets on departure","text":"","threats":[["insider-misuse",0.1,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"5.12","ref":"5.12","title":"Classifying information by sensitivity","text":"","threats":[["data-exposure",0.1,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"5.13","ref":"5.13","title":"Marking information with its class","text":"","threats":[["data-exposure",0.1,"likelihood"]]},{"id":"5.14","ref":"5.14","title":"Securing information exchanges","text":"","threats":[["data-theft",0.2,"likelihood"],["bec",0.2,"likelihood"]]},{"id":"5.15","ref":"5.15","title":"Rules governing access","text":"","threats":[["data-exposure",0.2,"likelihood"],["insider-misuse",0.2,"likelihood"]]},{"id":"5.16","ref":"5.16","title":"Identity lifecycle handling","text":"","threats":[["insider-misuse",0.2,"likelihood"],["remote-access",0.1,"likelihood"],["lateral-admin",0.1,"likelihood"]]},{"id":"5.17","ref":"5.17","title":"Handling passwords and other secrets","text":"","threats":[["brute-force",0.3,"likelihood"],["default-credentials",0.3,"likelihood"],["remote-access",0.2,"likelihood"]]},{"id":"5.18","ref":"5.18","title":"Granting, reviewing and revoking permissions","text":"","threats":[["insider-misuse",0.3,"likelihood"],["third-party-access",0.2,"likelihood"],["data-exposure",0.2,"likelihood"]]},{"id":"5.19","ref":"5.19","title":"Security with suppliers","text":"","threats":[["third-party-access",0.3,"likelihood"],["supply-chain",0.2,"likelihood"]]},{"id":"5.20","ref":"5.20","title":"Security clauses in supplier contracts","text":"","threats":[["third-party-access",0.2,"likelihood"],["supply-chain",0.1,"likelihood"],["internet-dependency",0.1,"impact"]]},{"id":"5.21","ref":"5.21","title":"Security of the ICT supply chain","text":"","threats":[["supply-chain",0.4,"likelihood"]]},{"id":"5.22","ref":"5.22","title":"Overseeing supplier services and their changes","text":"","threats":[["third-party-access",0.2,"likelihood"],["supply-chain",0.2,"likelihood"],["internet-dependency",0.1,"likelihood"]]},{"id":"5.23","ref":"5.23","title":"Security when using cloud services","text":"","threats":[["data-exposure",0.3,"likelihood"],["internet-dependency",0.3,"impact"]]},{"id":"5.24","ref":"5.24","title":"Preparing for incident handling","text":"","threats":[["ransomware",0.2,"impact"],["data-theft",0.1,"impact"]]},{"id":"5.25","ref":"5.25","title":"Triage and classification of security events","text":"","threats":[["ransomware",0.1,"impact"],["lateral-admin",0.1,"impact"]]},{"id":"5.26","ref":"5.26","title":"Handling security incidents","text":"","threats":[["ransomware",0.3,"impact"],["directory-takeover",0.2,"impact"],["data-theft",0.2,"impact"],["bec",0.2,"impact"]]},{"id":"5.27","ref":"5.27","title":"Learning lessons after incidents","text":"","threats":[]},{"id":"5.28","ref":"5.28","title":"Gathering and preserving evidence","text":"","threats":[["insider-misuse",0.1,"impact"]]},{"id":"5.29","ref":"5.29","title":"Keeping security during disruptions","text":"","threats":[["ransomware",0.1,"impact"],["ddos",0.1,"impact"]]},{"id":"5.30","ref":"5.30","title":"ICT preparedness for continuity","text":"","threats":[["ransomware",0.4,"impact"],["hypervisor-mass",0.4,"impact"],["internet-dependency",0.4,"impact"],["ddos",0.3,"impact"],["backup-destruction",0.2,"impact"]]},{"id":"5.31","ref":"5.31","title":"Meeting legal and contractual obligations","text":"","threats":[]},{"id":"5.32","ref":"5.32","title":"Protecting intellectual property","text":"","threats":[]},{"id":"5.33","ref":"5.33","title":"Safeguarding records","text":"","threats":[["insider-misuse",0.1,"impact"]]},{"id":"5.34","ref":"5.34","title":"Privacy and personal data","text":"","threats":[["data-exposure",0.2,"likelihood"],["data-theft",0.2,"impact"]]},{"id":"5.35","ref":"5.35","title":"Independent assessment of security","text":"","threats":[["data-exposure",0.1,"likelihood"]]},{"id":"5.36","ref":"5.36","title":"Checking adherence to security rules","text":"","threats":[["default-credentials",0.1,"likelihood"],["data-exposure",0.1,"likelihood"]]},{"id":"5.37","ref":"5.37","title":"Written operational procedures","text":"","threats":[]},{"id":"6.1","ref":"6.1","title":"Background checks on staff","text":"","threats":[["insider-misuse",0.3,"likelihood"]]},{"id":"6.2","ref":"6.2","title":"Security duties in employment contracts","text":"","threats":[["insider-misuse",0.1,"likelihood"]]},{"id":"6.3","ref":"6.3","title":"Security awareness and training","text":"","threats":[["phishing",0.4,"likelihood"],["bec",0.3,"likelihood"],["brute-force",0.1,"likelihood"]]},{"id":"6.4","ref":"6.4","title":"Sanctions for security breaches","text":"","threats":[["insider-misuse",0.1,"likelihood"]]},{"id":"6.5","ref":"6.5","title":"Obligations after leaving or changing role","text":"","threats":[["insider-misuse",0.1,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"6.6","ref":"6.6","title":"Non-disclosure commitments","text":"","threats":[["data-theft",0.1,"likelihood"]]},{"id":"6.7","ref":"6.7","title":"Security of work done remotely","text":"","threats":[["remote-access",0.2,"likelihood"],["physical-access",0.1,"likelihood"]]},{"id":"6.8","ref":"6.8","title":"Staff reporting of security events","text":"","threats":[["phishing",0.2,"impact"],["bec",0.2,"impact"],["ransomware",0.1,"impact"]]},{"id":"7.1","ref":"7.1","title":"Defined physical security boundaries","text":"","threats":[["physical-access",0.3,"likelihood"]]},{"id":"7.2","ref":"7.2","title":"Controlling physical entry","text":"","threats":[["physical-access",0.4,"likelihood"]]},{"id":"7.3","ref":"7.3","title":"Physical protection of offices and facilities","text":"","threats":[["physical-access",0.3,"likelihood"]]},{"id":"7.4","ref":"7.4","title":"Surveillance of premises","text":"","threats":[["physical-access",0.2,"likelihood"]]},{"id":"7.5","ref":"7.5","title":"Protection from environmental hazards","text":"","threats":[]},{"id":"7.6","ref":"7.6","title":"Rules for working in protected areas","text":"","threats":[["physical-access",0.2,"likelihood"],["insider-misuse",0.1,"likelihood"]]},{"id":"7.7","ref":"7.7","title":"Tidy desks and locked screens","text":"","threats":[["physical-access",0.2,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"7.8","ref":"7.8","title":"Placement and protection of equipment","text":"","threats":[["physical-access",0.2,"likelihood"]]},{"id":"7.9","ref":"7.9","title":"Protecting equipment outside the premises","text":"","threats":[["physical-access",0.3,"likelihood"]]},{"id":"7.10","ref":"7.10","title":"Handling of storage media","text":"","threats":[["physical-access",0.3,"likelihood"],["data-theft",0.2,"likelihood"]]},{"id":"7.11","ref":"7.11","title":"Power and other supporting services","text":"","threats":[["internet-dependency",0.1,"impact"]]},{"id":"7.12","ref":"7.12","title":"Protecting power and network cables","text":"","threats":[["physical-access",0.1,"likelihood"]]},{"id":"7.13","ref":"7.13","title":"Maintaining equipment properly","text":"","threats":[]},{"id":"7.14","ref":"7.14","title":"Safe disposal or reuse of equipment","text":"","threats":[["data-theft",0.2,"likelihood"],["physical-access",0.2,"impact"]]},{"id":"8.1","ref":"8.1","title":"Protecting user devices","text":"","threats":[["physical-access",0.3,"impact"],["device-takeover",0.2,"likelihood"],["phishing",0.1,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"8.2","ref":"8.2","title":"Restricting and managing privileged access","text":"","threats":[["directory-takeover",0.4,"likelihood"],["lateral-admin",0.3,"likelihood"],["insider-misuse",0.3,"likelihood"],["hypervisor-mass",0.3,"likelihood"]]},{"id":"8.3","ref":"8.3","title":"Limiting access to information","text":"","threats":[["data-exposure",0.3,"likelihood"],["data-theft",0.2,"likelihood"],["insider-misuse",0.2,"likelihood"]]},{"id":"8.4","ref":"8.4","title":"Controlling access to source code","text":"","threats":[["supply-chain",0.1,"likelihood"],["insider-misuse",0.1,"likelihood"]]},{"id":"8.5","ref":"8.5","title":"Robust authentication mechanisms","text":"","threats":[["remote-access",0.5,"likelihood"],["brute-force",0.5,"likelihood"],["bec",0.3,"likelihood"],["phishing",0.2,"likelihood"],["default-credentials",0.2,"likelihood"]]},{"id":"8.6","ref":"8.6","title":"Managing resource capacity","text":"","threats":[["ddos",0.2,"impact"]]},{"id":"8.7","ref":"8.7","title":"Defending against malicious software","text":"","threats":[["ransomware",0.3,"likelihood"],["phishing",0.3,"likelihood"],["device-takeover",0.1,"likelihood"]]},{"id":"8.8","ref":"8.8","title":"Handling technical vulnerabilities","text":"","threats":[["known-exploited",0.6,"likelihood"],["exploit-public",0.5,"likelihood"],["network-device",0.4,"likelihood"],["privilege-escalation",0.4,"likelihood"],["hypervisor-mass",0.3,"likelihood"],["web-app",0.3,"likelihood"],["device-takeover",0.3,"likelihood"],["end-of-life",0.2,"likelihood"],["defacement",0.2,"likelihood"]]},{"id":"8.9","ref":"8.9","title":"Secure configuration baselines","text":"","threats":[["default-credentials",0.4,"likelihood"],["data-exposure",0.4,"likelihood"],["device-takeover",0.2,"likelihood"],["network-device",0.2,"likelihood"],["exploit-public",0.2,"likelihood"]]},{"id":"8.10","ref":"8.10","title":"Erasing information no longer needed","text":"","threats":[["data-theft",0.2,"impact"]]},{"id":"8.11","ref":"8.11","title":"Masking or obfuscating data","text":"","threats":[["data-theft",0.2,"impact"],["data-exposure",0.2,"impact"]]},{"id":"8.12","ref":"8.12","title":"Preventing data leaks","text":"","threats":[["data-theft",0.3,"likelihood"],["insider-misuse",0.2,"likelihood"]]},{"id":"8.13","ref":"8.13","title":"Backing up information","text":"","threats":[["ransomware",0.6,"impact"],["hypervisor-mass",0.5,"impact"],["backup-destruction",0.3,"likelihood"],["defacement",0.3,"impact"],["insider-misuse",0.2,"impact"],["ot-manipulation",0.1,"impact"]]},{"id":"8.14","ref":"8.14","title":"Redundant processing capacity","text":"","threats":[["internet-dependency",0.4,"impact"],["ddos",0.2,"impact"],["hypervisor-mass",0.1,"impact"]]},{"id":"8.15","ref":"8.15","title":"Recording and protecting event logs","text":"","threats":[["detection-blinding",0.3,"likelihood"],["lateral-admin",0.2,"impact"],["insider-misuse",0.2,"impact"],["data-theft",0.2,"impact"]]},{"id":"8.16","ref":"8.16","title":"Watching for anomalous activity","text":"","threats":[["ransomware",0.3,"impact"],["data-theft",0.3,"impact"],["lateral-admin",0.3,"impact"],["directory-takeover",0.3,"impact"],["brute-force",0.2,"impact"],["detection-blinding",0.2,"impact"],["ot-manipulation",0.2,"impact"],["it-ot-pivot",0.2,"impact"]]},{"id":"8.17","ref":"8.17","title":"Common time source for systems","text":"","threats":[["lateral-admin",0.1,"impact"]]},{"id":"8.18","ref":"8.18","title":"Restricting powerful system utilities","text":"","threats":[["privilege-escalation",0.1,"likelihood"],["lateral-admin",0.1,"likelihood"]]},{"id":"8.19","ref":"8.19","title":"Controlling software installation","text":"","threats":[["phishing",0.2,"likelihood"],["ransomware",0.1,"likelihood"],["supply-chain",0.1,"likelihood"]]},{"id":"8.20","ref":"8.20","title":"Protecting networks and devices on them","text":"","threats":[["lateral-admin",0.2,"likelihood"],["network-device",0.2,"likelihood"],["wifi-intrusion",0.2,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"8.21","ref":"8.21","title":"Securing network services","text":"","threats":[["ddos",0.2,"impact"],["internet-dependency",0.2,"likelihood"],["network-device",0.1,"likelihood"]]},{"id":"8.22","ref":"8.22","title":"Splitting networks into zones","text":"","threats":[["it-ot-pivot",0.5,"likelihood"],["lateral-admin",0.4,"likelihood"],["ransomware",0.3,"impact"],["wifi-intrusion",0.3,"impact"],["ot-manipulation",0.2,"likelihood"],["hypervisor-mass",0.2,"likelihood"],["device-takeover",0.2,"impact"],["exploit-public",0.2,"impact"]]},{"id":"8.23","ref":"8.23","title":"Filtering web browsing","text":"","threats":[["phishing",0.3,"likelihood"],["ransomware",0.1,"likelihood"]]},{"id":"8.24","ref":"8.24","title":"Encryption and key handling","text":"","threats":[["data-theft",0.3,"impact"],["physical-access",0.3,"impact"],["data-exposure",0.2,"impact"]]},{"id":"8.25","ref":"8.25","title":"Security across the development process","text":"","threats":[["web-app",0.3,"likelihood"]]},{"id":"8.26","ref":"8.26","title":"Defining application security needs","text":"","threats":[["web-app",0.3,"likelihood"]]},{"id":"8.27","ref":"8.27","title":"Security-by-design architecture","text":"","threats":[["lateral-admin",0.2,"likelihood"],["exploit-public",0.2,"impact"],["web-app",0.1,"likelihood"],["hypervisor-mass",0.1,"likelihood"]]},{"id":"8.28","ref":"8.28","title":"Writing code securely","text":"","threats":[["web-app",0.5,"likelihood"]]},{"id":"8.29","ref":"8.29","title":"Testing security before release","text":"","threats":[["web-app",0.3,"likelihood"],["exploit-public",0.1,"likelihood"]]},{"id":"8.30","ref":"8.30","title":"Overseeing externally developed software","text":"","threats":[["supply-chain",0.2,"likelihood"],["web-app",0.1,"likelihood"]]},{"id":"8.31","ref":"8.31","title":"Keeping dev, test and production apart","text":"","threats":[["data-exposure",0.2,"likelihood"],["insider-misuse",0.1,"likelihood"]]},{"id":"8.32","ref":"8.32","title":"Controlled changes to systems","text":"","threats":[["insider-misuse",0.1,"likelihood"],["data-exposure",0.1,"likelihood"],["defacement",0.1,"likelihood"]]},{"id":"8.33","ref":"8.33","title":"Protecting data used for testing","text":"","threats":[["data-exposure",0.2,"likelihood"],["data-theft",0.1,"likelihood"]]},{"id":"8.34","ref":"8.34","title":"Limiting audit impact on live systems","text":"","threats":[]}]}]; +})(typeof globalThis!=='undefined'?globalThis:this); diff --git a/public/index.html b/public/index.html index ce6b915..625f81b 100644 --- a/public/index.html +++ b/public/index.html @@ -22,7 +22,7 @@