umer-wasim commited on
Commit
1e42c44
·
verified ·
1 Parent(s): b2c9ced

Catalog 0.4 (70 computer checks: unique login, prohibited software, tamper protection on Mac/Linux), app 0.5.1

Browse files
README.md CHANGED
@@ -29,7 +29,7 @@ can be built before real customer data exists. The generated training data is in
29
 
30
  | Section | Checks | Examples |
31
  |---|---|---|
32
- | `COMPLIANCE RESULTS` | Security baseline (33 on Windows, 26 on Linux/macOS) | Password and lockout policy, antivirus, firewall, screen lock, USB storage, administrators, disk encryption |
33
  | `GDPR TECHNICAL CONTROLS` | 12 | Automatic updates, supported OS, security logging, time sync, backup, removable media encryption, guest account, remote access, diagnostic data, personal data discovery (opt-in, later stage) |
34
  | `EU AI ACT CONTROLS` | 5 | AI software inventory, unapproved AI tools (shadow AI), risk classification (by the model), Windows Recall / Apple Intelligence, AI log retention |
35
  | `ORGANISATIONAL CONTROLS` | 8 | RoPA, DPIA, breach procedure, processor agreements, AI register, AI literacy, human oversight, AI transparency |
@@ -210,7 +210,7 @@ Devseis builds the bundle with `python3 vulndb/build_bundle.py` (needs internet;
210
 
211
  | Part | Version | Notes |
212
  |---|---|---|
213
- | Catalog, library, synthetic data, training data | **0.3** | 74 checks: Windows 64, Linux 56, macOS 56, iPhone 29, Android 30. 0.3 adds phones, real CVEs in training data and wording identical to the collectors and the phone page; 39,500 grounded examples |
214
  | Collectors (Windows, Linux, macOS) | **0.2** (catalog 0.3) | macOS tested on a real Mac; Linux tested on Ubuntu 24.04 and Fedora 42 containers; Windows parse-checked only (needs a real Windows test). Known vulnerabilities: inventory only, matching comes with the offline vulnerability bundle |
215
  | Vulnerability matcher and bundle | 0.1 | Tested: this Mac (Chrome 154 → 58 critical/high, fixed in 155), Ubuntu 24.04 (OpenSSL), Rocky 9 (25 of 25 packages agree with dnf's own security list), Fedora reported as not covered |
216
  | Website | **2026-10-14** | Computers only: download, check list, report viewer; no AI in the browser |
 
29
 
30
  | Section | Checks | Examples |
31
  |---|---|---|
32
+ | `COMPLIANCE RESULTS` | Security baseline | Password and lockout policy, unique user login, antivirus and tamper protection, firewall, screen lock, USB storage, administrators, disk encryption, updates, vulnerabilities, prohibited software |
33
  | `GDPR TECHNICAL CONTROLS` | 12 | Automatic updates, supported OS, security logging, time sync, backup, removable media encryption, guest account, remote access, diagnostic data, personal data discovery (opt-in, later stage) |
34
  | `EU AI ACT CONTROLS` | 5 | AI software inventory, unapproved AI tools (shadow AI), risk classification (by the model), Windows Recall / Apple Intelligence, AI log retention |
35
  | `ORGANISATIONAL CONTROLS` | 8 | RoPA, DPIA, breach procedure, processor agreements, AI register, AI literacy, human oversight, AI transparency |
 
210
 
211
  | Part | Version | Notes |
212
  |---|---|---|
213
+ | Catalog, library, synthetic data | **0.4** | 76 checks, 70 on computers (Windows 66, Linux 59, macOS 59). 0.4 adds unique user login, prohibited software (`PROHIBITED_SOFTWARE`), tamper protection on macOS (SIP) and Linux (SELinux/AppArmor) and names the encryption product. The fine-tuned models handle the new checks without retraining (v0.3 full precision and v0.6 4-bit: 24/24 findings). Training data is still 0.3 |
214
  | Collectors (Windows, Linux, macOS) | **0.2** (catalog 0.3) | macOS tested on a real Mac; Linux tested on Ubuntu 24.04 and Fedora 42 containers; Windows parse-checked only (needs a real Windows test). Known vulnerabilities: inventory only, matching comes with the offline vulnerability bundle |
215
  | Vulnerability matcher and bundle | 0.1 | Tested: this Mac (Chrome 154 → 58 critical/high, fixed in 155), Ubuntu 24.04 (OpenSSL), Rocky 9 (25 of 25 packages agree with dnf's own security list), Fedora reported as not covered |
216
  | Website | **2026-10-14** | Computers only: download, check list, report viewer; no AI in the browser |
app/package.json CHANGED
@@ -1,7 +1,7 @@
1
  {
2
  "name": "devseis-endpoint-auditor",
3
  "productName": "Arx",
4
- "version": "0.5.0",
5
  "description": "Read-only endpoint audit for ISO 27001, GDPR and the EU AI Act, with a local AI auditor.",
6
  "author": {
7
  "name": "Devseis",
 
1
  {
2
  "name": "devseis-endpoint-auditor",
3
  "productName": "Arx",
4
+ "version": "0.5.1",
5
  "description": "Read-only endpoint audit for ISO 27001, GDPR and the EU AI Act, with a local AI auditor.",
6
  "author": {
7
  "name": "Devseis",
baseline.conf CHANGED
@@ -40,11 +40,19 @@ APPROVED_ADMINS=itadmin
40
  # Windows: a disabled built-in Administrator (RID 500) is not counted as unauthorized.
41
  ALLOW_DISABLED_BUILTIN_ADMIN=1
42
 
 
 
 
 
43
  # --- Vulnerabilities -------------------------------------------------------
44
  MAX_PENDING_SECURITY_UPDATES=0
45
  MAX_OUTDATED_APPS=0
46
  # Critical or high vulnerabilities allowed in installed software (offline OSV/NVD data)
47
  MAX_CRITICAL_HIGH_VULNERABILITIES=0
 
 
 
 
48
 
49
  # --- GDPR technical controls ----------------------------------------------
50
  UPDATES_MAX_AGE_DAYS=30
 
40
  # Windows: a disabled built-in Administrator (RID 500) is not counted as unauthorized.
41
  ALLOW_DISABLED_BUILTIN_ADMIN=1
42
 
43
+ # --- Unique user login ------------------------------------------------------
44
+ # Account names that suggest a shared or generic login (exact match, any case). Each person should have their own account.
45
+ SHARED_ACCOUNT_NAMES=admin,administrator,user,users,shared,office,staff,reception,frontdesk,test,temp,demo,student,kiosk,public,helpdesk,owner
46
+
47
  # --- Vulnerabilities -------------------------------------------------------
48
  MAX_PENDING_SECURITY_UPDATES=0
49
  MAX_OUTDATED_APPS=0
50
  # Critical or high vulnerabilities allowed in installed software (offline OSV/NVD data)
51
  MAX_CRITICAL_HIGH_VULNERABILITIES=0
52
+ # Software that must not be installed: part of an installed app or package name, any case. Default: torrent clients
53
+ # (any name containing "torrent": µTorrent, BitTorrent, qBittorrent…) and
54
+ # Windows/Office activation cracks. Add your own (e.g. games, unlicensed tools). Licences cannot be checked from the device.
55
+ PROHIBITED_SOFTWARE=Torrent,Transmission,Deluge,Vuze,FrostWire,KMSpico,KMSAuto,AutoKMS,Microsoft Toolkit
56
 
57
  # --- GDPR technical controls ----------------------------------------------
58
  UPDATES_MAX_AGE_DAYS=30
catalog/checks.json CHANGED
@@ -1,5 +1,5 @@
1
  {
2
- "catalog_version": "0.3.0",
3
  "statuses": [
4
  "Compliant",
5
  "Non-Compliant",
@@ -59,7 +59,8 @@
59
  "A.8.17": "Clock synchronization",
60
  "A.8.19": "Installation of software on operational systems",
61
  "A.8.20": "Networks security",
62
- "A.8.24": "Use of cryptography"
 
63
  },
64
  "gdpr": {
65
  "Art. 5(1)(c)": "Data minimisation",
@@ -375,10 +376,12 @@
375
  "section": "baseline",
376
  "name": "Tamper protection",
377
  "os": [
378
- "windows"
 
 
379
  ],
380
  "baseline_keys": [],
381
- "rule": "Defender tamper protection is on.",
382
  "controls": {
383
  "iso27001": [
384
  "A.8.7"
@@ -1047,7 +1050,7 @@
1047
  "android"
1048
  ],
1049
  "baseline_keys": [],
1050
- "rule": "The system disk is fully encrypted (BitLocker / LUKS / FileVault). Phones: iOS data protection is on when a passcode is set; Android 10+ encrypts by default.",
1051
  "controls": {
1052
  "iso27001": [
1053
  "A.8.24",
@@ -1137,6 +1140,30 @@
1137
  "ai_act": []
1138
  }
1139
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1140
  {
1141
  "id": "vuln.pending_updates",
1142
  "section": "baseline",
@@ -1198,6 +1225,30 @@
1198
  "android": "App updates"
1199
  }
1200
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1201
  {
1202
  "id": "vuln.known_vulnerabilities",
1203
  "section": "baseline",
 
1
  {
2
+ "catalog_version": "0.4.0",
3
  "statuses": [
4
  "Compliant",
5
  "Non-Compliant",
 
59
  "A.8.17": "Clock synchronization",
60
  "A.8.19": "Installation of software on operational systems",
61
  "A.8.20": "Networks security",
62
+ "A.8.24": "Use of cryptography",
63
+ "A.5.32": "Intellectual property rights"
64
  },
65
  "gdpr": {
66
  "Art. 5(1)(c)": "Data minimisation",
 
376
  "section": "baseline",
377
  "name": "Tamper protection",
378
  "os": [
379
+ "windows",
380
+ "linux",
381
+ "macos"
382
  ],
383
  "baseline_keys": [],
384
+ "rule": "Protection cannot be switched off by malware: Defender tamper protection (Windows), System Integrity Protection (macOS), an enforcing SELinux or AppArmor (Linux).",
385
  "controls": {
386
  "iso27001": [
387
  "A.8.7"
 
1050
  "android"
1051
  ],
1052
  "baseline_keys": [],
1053
+ "rule": "The system disk is fully encrypted (BitLocker / LUKS / FileVault); the finding names the encryption product. Phones: iOS data protection is on when a passcode is set; Android 10+ encrypts by default.",
1054
  "controls": {
1055
  "iso27001": [
1056
  "A.8.24",
 
1140
  "ai_act": []
1141
  }
1142
  },
1143
+ {
1144
+ "id": "account.unique_login",
1145
+ "section": "baseline",
1146
+ "name": "Unique user login",
1147
+ "os": [
1148
+ "windows",
1149
+ "linux",
1150
+ "macos"
1151
+ ],
1152
+ "baseline_keys": [
1153
+ "SHARED_ACCOUNT_NAMES"
1154
+ ],
1155
+ "rule": "No automatic login, and no enabled account with a shared or generic name from SHARED_ACCOUNT_NAMES: each person signs in with their own account.",
1156
+ "controls": {
1157
+ "iso27001": [
1158
+ "A.5.16",
1159
+ "A.8.5"
1160
+ ],
1161
+ "gdpr": [
1162
+ "Art. 32(1)(b)"
1163
+ ],
1164
+ "ai_act": []
1165
+ }
1166
+ },
1167
  {
1168
  "id": "vuln.pending_updates",
1169
  "section": "baseline",
 
1225
  "android": "App updates"
1226
  }
1227
  },
1228
+ {
1229
+ "id": "software.prohibited",
1230
+ "section": "baseline",
1231
+ "name": "Prohibited software",
1232
+ "os": [
1233
+ "windows",
1234
+ "linux",
1235
+ "macos"
1236
+ ],
1237
+ "baseline_keys": [
1238
+ "PROHIBITED_SOFTWARE"
1239
+ ],
1240
+ "rule": "No installed application or package whose name contains an entry of PROHIBITED_SOFTWARE (torrent clients, activation cracks by default). Licences themselves cannot be checked from the device.",
1241
+ "controls": {
1242
+ "iso27001": [
1243
+ "A.8.19",
1244
+ "A.5.32"
1245
+ ],
1246
+ "gdpr": [
1247
+ "Art. 32(1)(b)"
1248
+ ],
1249
+ "ai_act": []
1250
+ }
1251
+ },
1252
  {
1253
  "id": "vuln.known_vulnerabilities",
1254
  "section": "baseline",
collectors/linux/audit.sh CHANGED
@@ -11,7 +11,7 @@
11
  set -u
12
 
13
  COLLECTOR_VERSION="0.2.0"
14
- CATALOG_VERSION="0.3.0"
15
 
16
  SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
17
  ROOT_DIR=$(cd "$SCRIPT_DIR/../.." && pwd)
@@ -49,7 +49,7 @@ conf_get() {
49
  if [ -n "$value" ]; then printf '%s' "$value"; else printf '%s' "$3"; fi
50
  }
51
 
52
- BASELINE_KEYS="PASSWORD_MIN_LENGTH PASSWORD_HISTORY PASSWORD_MAX_AGE_DAYS PASSWORD_MIN_AGE_DAYS PASSWORD_COMPLEXITY LOCKOUT_THRESHOLD_MAX LOCKOUT_DURATION_MIN_MINUTES LOCKOUT_OBSERVATION_MIN_MINUTES SIGNATURE_MAX_AGE_DAYS MACOS_XPROTECT_MAX_AGE_DAYS FIREWALL_OUTBOUND SCREEN_LOCK_MAX_SECONDS USB_READ USB_WRITE APPROVED_ADMINS ALLOW_DISABLED_BUILTIN_ADMIN UPDATES_MAX_AGE_DAYS BACKUP_MAX_AGE_DAYS APPROVED_REMOTE_SERVICES WINDOWS_MIN_BUILD MACOS_MIN_MAJOR UBUNTU_MIN_VERSION DEBIAN_MIN_VERSION RHEL_MIN_VERSION PERSONAL_DATA_SCAN APPROVED_AI_TOOLS USB_DEVICE_ACCESS MAX_PENDING_SECURITY_UPDATES MAX_OUTDATED_APPS MAX_CRITICAL_HIGH_VULNERABILITIES"
53
  declare -A B
54
  B[PASSWORD_MIN_LENGTH]=14; B[PASSWORD_HISTORY]=24; B[PASSWORD_MAX_AGE_DAYS]=365; B[PASSWORD_MIN_AGE_DAYS]=1
55
  B[PASSWORD_COMPLEXITY]=1; B[LOCKOUT_THRESHOLD_MAX]=5; B[LOCKOUT_DURATION_MIN_MINUTES]=15; B[LOCKOUT_OBSERVATION_MIN_MINUTES]=15
@@ -59,6 +59,8 @@ B[UPDATES_MAX_AGE_DAYS]=30; B[BACKUP_MAX_AGE_DAYS]=7; B[APPROVED_REMOTE_SERVICES
59
  B[MACOS_MIN_MAJOR]=14; B[UBUNTU_MIN_VERSION]=22.04; B[DEBIAN_MIN_VERSION]=12; B[RHEL_MIN_VERSION]=9
60
  B[PERSONAL_DATA_SCAN]=0; B[APPROVED_AI_TOOLS]=""
61
  B[USB_DEVICE_ACCESS]=allow; B[MAX_PENDING_SECURITY_UPDATES]=0; B[MAX_OUTDATED_APPS]=0; B[MAX_CRITICAL_HIGH_VULNERABILITIES]=0
 
 
62
  for key in $BASELINE_KEYS; do B[$key]=$(conf_get "$BASELINE_FILE" "$key" "${B[$key]}"); done
63
 
64
  is_root() { [ "$(id -u)" -eq 0 ]; }
@@ -284,6 +286,22 @@ else
284
  [ "$clamonacc" -eq 1 ]; pass_fail $? malware.on_access $S "On-access malware protection" "$( [ "$clamonacc" -eq 1 ] && echo "clamonacc running" || echo "not running")" "on-access scanning"
285
  fi
286
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
  # Firewall: ufw, firewalld, nftables or iptables.
288
  fw_name=""; fw_in=""; fw_out=""; fw_detail=""
289
  if have ufw && is_root; then
@@ -424,6 +442,24 @@ else
424
  fi
425
  fi
426
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
427
  # Disk encryption (LUKS under the root filesystem)
428
  root_src=$(findmnt -no SOURCE / 2>/dev/null)
429
  # Btrfs subvolumes appear as /dev/mapper/x[/@]: keep the device part only.
@@ -503,6 +539,31 @@ else
503
  pass_fail $? vuln.outdated_apps $S "Outdated third-party applications" "$outdated outdated" "$OUTDATED_EXP" "$outdated_detail"
504
  fi
505
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
506
  # Known vulnerabilities: inventory now; matching against offline OSV data comes in a later version.
507
  add vuln.known_vulnerabilities $S "Known vulnerabilities in installed software" Pending "$pkg_count packages inventoried" "<= ${B[MAX_CRITICAL_HIGH_VULNERABILITIES]} critical/high" "Inventory saved for the Devseis app, which matches it against its offline OSV/NVD vulnerability data; the collector on its own does not match."
508
 
 
11
  set -u
12
 
13
  COLLECTOR_VERSION="0.2.0"
14
+ CATALOG_VERSION="0.4.0"
15
 
16
  SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
17
  ROOT_DIR=$(cd "$SCRIPT_DIR/../.." && pwd)
 
49
  if [ -n "$value" ]; then printf '%s' "$value"; else printf '%s' "$3"; fi
50
  }
51
 
52
+ BASELINE_KEYS="PASSWORD_MIN_LENGTH PASSWORD_HISTORY PASSWORD_MAX_AGE_DAYS PASSWORD_MIN_AGE_DAYS PASSWORD_COMPLEXITY LOCKOUT_THRESHOLD_MAX LOCKOUT_DURATION_MIN_MINUTES LOCKOUT_OBSERVATION_MIN_MINUTES SIGNATURE_MAX_AGE_DAYS MACOS_XPROTECT_MAX_AGE_DAYS FIREWALL_OUTBOUND SCREEN_LOCK_MAX_SECONDS USB_READ USB_WRITE APPROVED_ADMINS ALLOW_DISABLED_BUILTIN_ADMIN UPDATES_MAX_AGE_DAYS BACKUP_MAX_AGE_DAYS APPROVED_REMOTE_SERVICES WINDOWS_MIN_BUILD MACOS_MIN_MAJOR UBUNTU_MIN_VERSION DEBIAN_MIN_VERSION RHEL_MIN_VERSION PERSONAL_DATA_SCAN APPROVED_AI_TOOLS USB_DEVICE_ACCESS MAX_PENDING_SECURITY_UPDATES MAX_OUTDATED_APPS MAX_CRITICAL_HIGH_VULNERABILITIES SHARED_ACCOUNT_NAMES PROHIBITED_SOFTWARE"
53
  declare -A B
54
  B[PASSWORD_MIN_LENGTH]=14; B[PASSWORD_HISTORY]=24; B[PASSWORD_MAX_AGE_DAYS]=365; B[PASSWORD_MIN_AGE_DAYS]=1
55
  B[PASSWORD_COMPLEXITY]=1; B[LOCKOUT_THRESHOLD_MAX]=5; B[LOCKOUT_DURATION_MIN_MINUTES]=15; B[LOCKOUT_OBSERVATION_MIN_MINUTES]=15
 
59
  B[MACOS_MIN_MAJOR]=14; B[UBUNTU_MIN_VERSION]=22.04; B[DEBIAN_MIN_VERSION]=12; B[RHEL_MIN_VERSION]=9
60
  B[PERSONAL_DATA_SCAN]=0; B[APPROVED_AI_TOOLS]=""
61
  B[USB_DEVICE_ACCESS]=allow; B[MAX_PENDING_SECURITY_UPDATES]=0; B[MAX_OUTDATED_APPS]=0; B[MAX_CRITICAL_HIGH_VULNERABILITIES]=0
62
+ B[SHARED_ACCOUNT_NAMES]="admin,administrator,user,users,shared,office,staff,reception,frontdesk,test,temp,demo,student,kiosk,public,helpdesk,owner"
63
+ B[PROHIBITED_SOFTWARE]="Torrent,Transmission,Deluge,Vuze,FrostWire,KMSpico,KMSAuto,AutoKMS,Microsoft Toolkit"
64
  for key in $BASELINE_KEYS; do B[$key]=$(conf_get "$BASELINE_FILE" "$key" "${B[$key]}"); done
65
 
66
  is_root() { [ "$(id -u)" -eq 0 ]; }
 
286
  [ "$clamonacc" -eq 1 ]; pass_fail $? malware.on_access $S "On-access malware protection" "$( [ "$clamonacc" -eq 1 ] && echo "clamonacc running" || echo "not running")" "on-access scanning"
287
  fi
288
 
289
+ # Tamper protection: an enforcing Linux security module (SELinux or AppArmor) confines services, so malware running as
290
+ # them cannot switch off protection; Secure Boot is reported for information.
291
+ lsm=""
292
+ if have getenforce && [ "$(getenforce 2>/dev/null)" = "Enforcing" ]; then lsm="SELinux enforcing"
293
+ elif [ "$(cat /sys/module/apparmor/parameters/enabled 2>/dev/null)" = "Y" ]; then
294
+ profiles=$(cat /sys/kernel/security/apparmor/profiles 2>/dev/null | grep -c "(enforce)")
295
+ if [ "${profiles:-0}" -gt 0 ]; then lsm="AppArmor enforcing ($profiles profiles)"
296
+ elif ! is_root; then lsm="AppArmor enabled"; fi
297
+ fi
298
+ sb=""; have mokutil && sb=$(mokutil --sb-state 2>/dev/null | head -1)
299
+ if [ -n "$lsm" ]; then
300
+ add malware.tamper $S "Tamper protection" Compliant "$lsm" "SELinux or AppArmor enforcing" "${sb:+Secure Boot: $sb}"
301
+ else
302
+ add malware.tamper $S "Tamper protection" Non-Compliant "no security module enforcing" "SELinux or AppArmor enforcing" "${sb:+Secure Boot: $sb}"
303
+ fi
304
+
305
  # Firewall: ufw, firewalld, nftables or iptables.
306
  fw_name=""; fw_in=""; fw_out=""; fw_detail=""
307
  if have ufw && is_root; then
 
442
  fi
443
  fi
444
 
445
+ # Unique user login: no automatic login in the display manager, and no shared or generic account names.
446
+ auto_login=""
447
+ for f in /etc/gdm3/custom.conf /etc/gdm/custom.conf; do
448
+ [ -r "$f" ] && grep -qiE '^[[:space:]]*AutomaticLoginEnable[[:space:]]*=[[:space:]]*true' "$f" && auto_login=$(awk -F= 'tolower($1) ~ /^[[:space:]]*automaticlogin[[:space:]]*$/ { gsub(/[[:space:]]/, "", $2); print $2 }' "$f" | head -1)
449
+ [ -n "$auto_login" ] && break
450
+ done
451
+ [ -z "$auto_login" ] && auto_login=$(cat /etc/lightdm/lightdm.conf /etc/lightdm/lightdm.conf.d/*.conf 2>/dev/null | awk -F= '/^[[:space:]]*autologin-user[[:space:]]*=/ { gsub(/[[:space:]]/, "", $2); if ($2 != "") print $2 }' | head -1)
452
+ [ -z "$auto_login" ] && auto_login=$(cat /etc/sddm.conf /etc/sddm.conf.d/*.conf 2>/dev/null | awk -F= '/^\[Autologin\]/ { a = 1; next } /^\[/ { a = 0 } a && $1 ~ /^[[:space:]]*User[[:space:]]*$/ { gsub(/[[:space:]]/, "", $2); if ($2 != "") print $2 }' | head -1)
453
+ generic=""
454
+ for entry in $HUMAN_USERS; do
455
+ name=${entry%%:*}
456
+ in_list "$name" "${B[SHARED_ACCOUNT_NAMES]}" && generic="${generic:+$generic, }$name"
457
+ done
458
+ issues=""
459
+ [ -n "$auto_login" ] && issues="automatic login as $auto_login"
460
+ [ -n "$generic" ] && issues="${issues:+$issues; }shared or generic accounts: $generic"
461
+ [ -z "$issues" ]; pass_fail $? account.unique_login $S "Unique user login" "${issues:-personal accounts, no automatic login}" "personal accounts, no automatic login"
462
+
463
  # Disk encryption (LUKS under the root filesystem)
464
  root_src=$(findmnt -no SOURCE / 2>/dev/null)
465
  # Btrfs subvolumes appear as /dev/mapper/x[/@]: keep the device part only.
 
539
  pass_fail $? vuln.outdated_apps $S "Outdated third-party applications" "$outdated outdated" "$OUTDATED_EXP" "$outdated_detail"
540
  fi
541
 
542
+ # Prohibited software (PROHIBITED_SOFTWARE: parts of package names, any case). Licences cannot be checked from the device.
543
+ pkg_names=""
544
+ if have dpkg-query; then pkg_names=$(dpkg-query -W -f '${db:Status-Abbrev}\t${Package}\n' 2>/dev/null | awk -F'\t' '$1 ~ /^ii/ { print $2 }')
545
+ elif have rpm; then pkg_names=$(rpm -qa --qf '%{NAME}\n' 2>/dev/null); fi
546
+ have flatpak && pkg_names="$pkg_names
547
+ $(flatpak list --app --columns=application 2>/dev/null)"
548
+ have snap && pkg_names="$pkg_names
549
+ $(snap list 2>/dev/null | awk 'NR > 1 { print $1 }')"
550
+ prohibited=""
551
+ if [ -n "${B[PROHIBITED_SOFTWARE]}" ]; then
552
+ old_ifs="$IFS"; IFS=,
553
+ for item in ${B[PROHIBITED_SOFTWARE]}; do
554
+ item=$(lower "$(printf '%s' "$item" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')")
555
+ [ -n "$item" ] || continue
556
+ found=$(printf '%s\n' "$pkg_names" | grep -iF -- "$item" | grep -v '^lib' | head -3 | paste -sd, - | sed 's/,/, /g')
557
+ [ -n "$found" ] && prohibited="${prohibited:+$prohibited, }$found"
558
+ done
559
+ IFS="$old_ifs"
560
+ fi
561
+ if [ -z "${B[PROHIBITED_SOFTWARE]}" ]; then
562
+ add software.prohibited $S "Prohibited software" Compliant "no list configured" "none of: (empty list)" "PROHIBITED_SOFTWARE in baseline.conf is empty."
563
+ else
564
+ [ -z "$prohibited" ]; pass_fail $? software.prohibited $S "Prohibited software" "${prohibited:-none found}" "none of: ${B[PROHIBITED_SOFTWARE]}"
565
+ fi
566
+
567
  # Known vulnerabilities: inventory now; matching against offline OSV data comes in a later version.
568
  add vuln.known_vulnerabilities $S "Known vulnerabilities in installed software" Pending "$pkg_count packages inventoried" "<= ${B[MAX_CRITICAL_HIGH_VULNERABILITIES]} critical/high" "Inventory saved for the Devseis app, which matches it against its offline OSV/NVD vulnerability data; the collector on its own does not match."
569
 
collectors/macos/audit.sh CHANGED
@@ -13,7 +13,7 @@
13
  set -u
14
 
15
  COLLECTOR_VERSION="0.2.0"
16
- CATALOG_VERSION="0.3.0"
17
 
18
  SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
19
  ROOT_DIR=$(cd "$SCRIPT_DIR/../.." && pwd)
@@ -51,7 +51,7 @@ conf_get() {
51
  if [ -n "$value" ]; then printf '%s' "$value"; else printf '%s' "$3"; fi
52
  }
53
 
54
- BASELINE_KEYS="PASSWORD_MIN_LENGTH PASSWORD_HISTORY PASSWORD_MAX_AGE_DAYS PASSWORD_MIN_AGE_DAYS PASSWORD_COMPLEXITY LOCKOUT_THRESHOLD_MAX LOCKOUT_DURATION_MIN_MINUTES LOCKOUT_OBSERVATION_MIN_MINUTES SIGNATURE_MAX_AGE_DAYS MACOS_XPROTECT_MAX_AGE_DAYS FIREWALL_OUTBOUND SCREEN_LOCK_MAX_SECONDS USB_READ USB_WRITE APPROVED_ADMINS ALLOW_DISABLED_BUILTIN_ADMIN UPDATES_MAX_AGE_DAYS BACKUP_MAX_AGE_DAYS APPROVED_REMOTE_SERVICES WINDOWS_MIN_BUILD MACOS_MIN_MAJOR UBUNTU_MIN_VERSION DEBIAN_MIN_VERSION RHEL_MIN_VERSION PERSONAL_DATA_SCAN APPROVED_AI_TOOLS USB_DEVICE_ACCESS MAX_PENDING_SECURITY_UPDATES MAX_OUTDATED_APPS MAX_CRITICAL_HIGH_VULNERABILITIES"
55
 
56
  B_PASSWORD_MIN_LENGTH=$(conf_get "$BASELINE_FILE" PASSWORD_MIN_LENGTH 14)
57
  B_PASSWORD_HISTORY=$(conf_get "$BASELINE_FILE" PASSWORD_HISTORY 24)
@@ -80,6 +80,8 @@ B_RHEL_MIN_VERSION=$(conf_get "$BASELINE_FILE" RHEL_MIN_VERSION 9)
80
  B_PERSONAL_DATA_SCAN=$(conf_get "$BASELINE_FILE" PERSONAL_DATA_SCAN 0)
81
  B_APPROVED_AI_TOOLS=$(conf_get "$BASELINE_FILE" APPROVED_AI_TOOLS "")
82
  B_USB_DEVICE_ACCESS=$(conf_get "$BASELINE_FILE" USB_DEVICE_ACCESS allow)
 
 
83
  B_MAX_PENDING_SECURITY_UPDATES=$(conf_get "$BASELINE_FILE" MAX_PENDING_SECURITY_UPDATES 0)
84
  B_MAX_OUTDATED_APPS=$(conf_get "$BASELINE_FILE" MAX_OUTDATED_APPS 0)
85
  B_MAX_CRITICAL_HIGH_VULNERABILITIES=$(conf_get "$BASELINE_FILE" MAX_CRITICAL_HIGH_VULNERABILITIES 0)
@@ -289,6 +291,17 @@ else
289
  add malware.on_access $S "On-access malware protection" NotApplicable "XProtect only" "on-access scanning" "XProtect scans at launch and download; macOS has no built-in on-access scanning."
290
  fi
291
 
 
 
 
 
 
 
 
 
 
 
 
292
  # Firewall (application firewall)
293
  FW=/usr/libexec/ApplicationFirewall/socketfilterfw
294
  fw_state=$("$FW" --getglobalstate 2>/dev/null)
@@ -416,6 +429,25 @@ else
416
  add user.account_type $S "Signed-in user account type" Compliant "Standard ($CONSOLE_USER)" "Standard"
417
  fi
418
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
419
  # FileVault
420
  fv=$(fdesetup status 2>/dev/null)
421
  if printf '%s' "$fv" | grep -q "FileVault is On"; then
@@ -481,6 +513,25 @@ for app in /Applications/*.app /Applications/*/*.app ${CONSOLE_HOME:+"$CONSOLE_H
481
  [ -f "$app/Contents/Info.plist" ] && APP_BUNDLES+=("$app")
482
  done
483
  app_count=${#APP_BUNDLES[@]}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484
  add vuln.known_vulnerabilities $S "Known vulnerabilities in installed software" Pending "$app_count applications inventoried" "<= $B_MAX_CRITICAL_HIGH_VULNERABILITIES critical/high" "Inventory saved for the Devseis app, which matches it against its offline OSV/NVD vulnerability data; the collector on its own does not match."
485
 
486
  # ---------------------------------------------------------------------------
 
13
  set -u
14
 
15
  COLLECTOR_VERSION="0.2.0"
16
+ CATALOG_VERSION="0.4.0"
17
 
18
  SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
19
  ROOT_DIR=$(cd "$SCRIPT_DIR/../.." && pwd)
 
51
  if [ -n "$value" ]; then printf '%s' "$value"; else printf '%s' "$3"; fi
52
  }
53
 
54
+ BASELINE_KEYS="PASSWORD_MIN_LENGTH PASSWORD_HISTORY PASSWORD_MAX_AGE_DAYS PASSWORD_MIN_AGE_DAYS PASSWORD_COMPLEXITY LOCKOUT_THRESHOLD_MAX LOCKOUT_DURATION_MIN_MINUTES LOCKOUT_OBSERVATION_MIN_MINUTES SIGNATURE_MAX_AGE_DAYS MACOS_XPROTECT_MAX_AGE_DAYS FIREWALL_OUTBOUND SCREEN_LOCK_MAX_SECONDS USB_READ USB_WRITE APPROVED_ADMINS ALLOW_DISABLED_BUILTIN_ADMIN UPDATES_MAX_AGE_DAYS BACKUP_MAX_AGE_DAYS APPROVED_REMOTE_SERVICES WINDOWS_MIN_BUILD MACOS_MIN_MAJOR UBUNTU_MIN_VERSION DEBIAN_MIN_VERSION RHEL_MIN_VERSION PERSONAL_DATA_SCAN APPROVED_AI_TOOLS USB_DEVICE_ACCESS MAX_PENDING_SECURITY_UPDATES MAX_OUTDATED_APPS MAX_CRITICAL_HIGH_VULNERABILITIES SHARED_ACCOUNT_NAMES PROHIBITED_SOFTWARE"
55
 
56
  B_PASSWORD_MIN_LENGTH=$(conf_get "$BASELINE_FILE" PASSWORD_MIN_LENGTH 14)
57
  B_PASSWORD_HISTORY=$(conf_get "$BASELINE_FILE" PASSWORD_HISTORY 24)
 
80
  B_PERSONAL_DATA_SCAN=$(conf_get "$BASELINE_FILE" PERSONAL_DATA_SCAN 0)
81
  B_APPROVED_AI_TOOLS=$(conf_get "$BASELINE_FILE" APPROVED_AI_TOOLS "")
82
  B_USB_DEVICE_ACCESS=$(conf_get "$BASELINE_FILE" USB_DEVICE_ACCESS allow)
83
+ B_SHARED_ACCOUNT_NAMES=$(conf_get "$BASELINE_FILE" SHARED_ACCOUNT_NAMES "admin,administrator,user,users,shared,office,staff,reception,frontdesk,test,temp,demo,student,kiosk,public,helpdesk,owner")
84
+ B_PROHIBITED_SOFTWARE=$(conf_get "$BASELINE_FILE" PROHIBITED_SOFTWARE "Torrent,Transmission,Deluge,Vuze,FrostWire,KMSpico,KMSAuto,AutoKMS,Microsoft Toolkit")
85
  B_MAX_PENDING_SECURITY_UPDATES=$(conf_get "$BASELINE_FILE" MAX_PENDING_SECURITY_UPDATES 0)
86
  B_MAX_OUTDATED_APPS=$(conf_get "$BASELINE_FILE" MAX_OUTDATED_APPS 0)
87
  B_MAX_CRITICAL_HIGH_VULNERABILITIES=$(conf_get "$BASELINE_FILE" MAX_CRITICAL_HIGH_VULNERABILITIES 0)
 
291
  add malware.on_access $S "On-access malware protection" NotApplicable "XProtect only" "on-access scanning" "XProtect scans at launch and download; macOS has no built-in on-access scanning."
292
  fi
293
 
294
+ # Tamper protection: System Integrity Protection stops anything, even root, changing protected system files and Apple's
295
+ # security tools (XProtect, Gatekeeper); it can only be switched off from Recovery mode.
296
+ sip=$(csrutil status 2>/dev/null)
297
+ if printf '%s' "$sip" | grep -q "status: enabled"; then
298
+ add malware.tamper $S "Tamper protection" Compliant "System Integrity Protection on" "on"
299
+ elif [ -n "$sip" ]; then
300
+ add malware.tamper $S "Tamper protection" Non-Compliant "System Integrity Protection $(printf '%s' "$sip" | sed -n 's/.*status: \([a-z]*\).*/\1/p' | head -1)" "on" "$(printf '%s' "$sip" | head -1)"
301
+ else
302
+ add malware.tamper $S "Tamper protection" Error "not read" "on" "csrutil status gave no answer."
303
+ fi
304
+
305
  # Firewall (application firewall)
306
  FW=/usr/libexec/ApplicationFirewall/socketfilterfw
307
  fw_state=$("$FW" --getglobalstate 2>/dev/null)
 
429
  add user.account_type $S "Signed-in user account type" Compliant "Standard ($CONSOLE_USER)" "Standard"
430
  fi
431
 
432
+ # Unique user login: no automatic login, and no shared or generic account names (each person signs in as themselves).
433
+ auto_login=$(defaults read /Library/Preferences/com.apple.loginwindow autoLoginUser 2>/dev/null)
434
+ generic=""
435
+ while read -r name uid; do
436
+ is_int "$uid" && [ "$uid" -ge 500 ] || continue
437
+ case "$name" in _*|daemon|nobody|root) continue ;; esac
438
+ in_list "$name" "$B_SHARED_ACCOUNT_NAMES" && generic="${generic:+$generic, }$name"
439
+ done <<EOF_USERS
440
+ $(dscl . -list /Users UniqueID 2>/dev/null)
441
+ EOF_USERS
442
+ issues=""
443
+ [ -n "$auto_login" ] && issues="automatic login as $auto_login"
444
+ [ -n "$generic" ] && issues="${issues:+$issues; }shared or generic accounts: $generic"
445
+ if [ -z "$issues" ]; then
446
+ add account.unique_login $S "Unique user login" Compliant "personal accounts, no automatic login" "personal accounts, no automatic login"
447
+ else
448
+ add account.unique_login $S "Unique user login" Non-Compliant "$issues" "personal accounts, no automatic login"
449
+ fi
450
+
451
  # FileVault
452
  fv=$(fdesetup status 2>/dev/null)
453
  if printf '%s' "$fv" | grep -q "FileVault is On"; then
 
513
  [ -f "$app/Contents/Info.plist" ] && APP_BUNDLES+=("$app")
514
  done
515
  app_count=${#APP_BUNDLES[@]}
516
+
517
+ # Prohibited software (PROHIBITED_SOFTWARE: parts of app names, any case). Licences cannot be checked from the device.
518
+ prohibited=""
519
+ for app in ${APP_BUNDLES[@]+"${APP_BUNDLES[@]}"}; do
520
+ name=$(basename "$app" .app); lname=$(lower "$name")
521
+ old_ifs="$IFS"; IFS=,
522
+ for item in $B_PROHIBITED_SOFTWARE; do
523
+ item=$(lower "$(printf '%s' "$item" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')")
524
+ [ -n "$item" ] && case "$lname" in *"$item"*) prohibited="${prohibited:+$prohibited, }$name"; break ;; esac
525
+ done
526
+ IFS="$old_ifs"
527
+ done
528
+ if [ -z "$B_PROHIBITED_SOFTWARE" ]; then
529
+ add software.prohibited $S "Prohibited software" Compliant "no list configured" "none of: (empty list)" "PROHIBITED_SOFTWARE in baseline.conf is empty."
530
+ elif [ -z "$prohibited" ]; then
531
+ add software.prohibited $S "Prohibited software" Compliant "none found in $app_count applications" "none of: $B_PROHIBITED_SOFTWARE"
532
+ else
533
+ add software.prohibited $S "Prohibited software" Non-Compliant "$prohibited" "none of: $B_PROHIBITED_SOFTWARE"
534
+ fi
535
  add vuln.known_vulnerabilities $S "Known vulnerabilities in installed software" Pending "$app_count applications inventoried" "<= $B_MAX_CRITICAL_HIGH_VULNERABILITIES critical/high" "Inventory saved for the Devseis app, which matches it against its offline OSV/NVD vulnerability data; the collector on its own does not match."
536
 
537
  # ---------------------------------------------------------------------------
collectors/windows/audit.ps1 CHANGED
@@ -26,7 +26,7 @@ param(
26
  Set-StrictMode -Version 2.0
27
  $ErrorActionPreference = 'Stop'
28
  $CollectorVersion = '0.2.0'
29
- $CatalogVersion = '0.3.0'
30
 
31
  # ---------------------------------------------------------------------------
32
  # Helpers
@@ -54,6 +54,8 @@ $Defaults = [ordered]@{
54
  MACOS_MIN_MAJOR = '14'; UBUNTU_MIN_VERSION = '22.04'; DEBIAN_MIN_VERSION = '12'; RHEL_MIN_VERSION = '9'
55
  PERSONAL_DATA_SCAN = '0'; APPROVED_AI_TOOLS = ''
56
  USB_DEVICE_ACCESS = 'allow'; MAX_PENDING_SECURITY_UPDATES = '0'; MAX_OUTDATED_APPS = '0'; MAX_CRITICAL_HIGH_VULNERABILITIES = '0'
 
 
57
  }
58
  $conf = Read-Conf $Baseline
59
  $B = [ordered]@{}
@@ -329,6 +331,17 @@ Check 'user.account_type' $S 'Signed-in user account type' 'Standard' {
329
  Pass $false "Administrator ($console)" 'The signed-in user is a member of the local Administrators group.'
330
  }
331
 
 
 
 
 
 
 
 
 
 
 
 
332
  # BitLocker on the system drive
333
  $Bl = $null; $BlError = $null
334
  try { Assert-Admin; $Bl = Get-BitLockerVolume -MountPoint $env:SystemDrive -ErrorAction Stop } catch { $BlError = $_.Exception.Message }
@@ -336,7 +349,7 @@ function BitLockerCheck($Id, $Name, $Expected, [scriptblock]$Test) {
336
  if ($null -eq $Bl) { Add-Result $Id $S $Name 'Error' 'not read' $Expected $BlError } else { Check $Id $S $Name $Expected $Test }
337
  }
338
  BitLockerCheck 'encryption.feature' 'BitLocker' 'on' { Pass ("$($Bl.VolumeStatus)" -ne 'FullyDecrypted') $(if ("$($Bl.VolumeStatus)" -ne 'FullyDecrypted') { 'on' } else { 'off' }) }
339
- BitLockerCheck 'encryption.enabled' 'Encryption' 'fully encrypted' { Pass ("$($Bl.VolumeStatus)" -eq 'FullyEncrypted') ("{0} ({1}%)" -f $Bl.VolumeStatus, $Bl.EncryptionPercentage) }
340
  BitLockerCheck 'encryption.protection' 'BitLocker protection' 'protection on, AES' {
341
  $method = "$($Bl.EncryptionMethod)"
342
  Pass ("$($Bl.ProtectionStatus)" -eq 'On' -and $method -match 'Aes') ("protection {0}, {1}" -f $Bl.ProtectionStatus, $method)
@@ -401,6 +414,12 @@ $Inventory = @(Get-ItemProperty -Path $UninstallKeys -ErrorAction SilentlyContin
401
  Where-Object { $_.DisplayName -and -not $_.SystemComponent -and -not $_.ParentKeyName } |
402
  ForEach-Object { [ordered]@{ name = "$($_.DisplayName)".Trim(); version = "$($_.DisplayVersion)".Trim(); publisher = "$($_.Publisher)".Trim() } } |
403
  Sort-Object { $_.name + '|' + $_.version } -Unique)
 
 
 
 
 
 
404
  Check 'vuln.known_vulnerabilities' $S 'Known vulnerabilities in installed software' "<= $($B.MAX_CRITICAL_HIGH_VULNERABILITIES) critical/high" {
405
  # Inventory now; matching against offline OSV/NVD data comes in a later version.
406
  State 'Pending' "$($Inventory.Count) applications inventoried" 'Inventory saved for the Devseis app, which matches it against its offline OSV/NVD vulnerability data; the collector on its own does not match.'
 
26
  Set-StrictMode -Version 2.0
27
  $ErrorActionPreference = 'Stop'
28
  $CollectorVersion = '0.2.0'
29
+ $CatalogVersion = '0.4.0'
30
 
31
  # ---------------------------------------------------------------------------
32
  # Helpers
 
54
  MACOS_MIN_MAJOR = '14'; UBUNTU_MIN_VERSION = '22.04'; DEBIAN_MIN_VERSION = '12'; RHEL_MIN_VERSION = '9'
55
  PERSONAL_DATA_SCAN = '0'; APPROVED_AI_TOOLS = ''
56
  USB_DEVICE_ACCESS = 'allow'; MAX_PENDING_SECURITY_UPDATES = '0'; MAX_OUTDATED_APPS = '0'; MAX_CRITICAL_HIGH_VULNERABILITIES = '0'
57
+ SHARED_ACCOUNT_NAMES = 'admin,administrator,user,users,shared,office,staff,reception,frontdesk,test,temp,demo,student,kiosk,public,helpdesk,owner'
58
+ PROHIBITED_SOFTWARE = 'Torrent,Transmission,Deluge,Vuze,FrostWire,KMSpico,KMSAuto,AutoKMS,Microsoft Toolkit'
59
  }
60
  $conf = Read-Conf $Baseline
61
  $B = [ordered]@{}
 
331
  Pass $false "Administrator ($console)" 'The signed-in user is a member of the local Administrators group.'
332
  }
333
 
334
+ # Unique user login: no automatic sign-in (Winlogon AutoAdminLogon) and no enabled shared or generic local accounts.
335
+ Check 'account.unique_login' $S 'Unique user login' 'personal accounts, no automatic login' {
336
+ $winlogon = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon'
337
+ $issues = @()
338
+ if ("$(Get-RegValue $winlogon 'AutoAdminLogon')" -eq '1') { $issues += "automatic login as $(Get-RegValue $winlogon 'DefaultUserName')" }
339
+ $shared = @(Split-List $B.SHARED_ACCOUNT_NAMES)
340
+ $generic = @(Get-LocalUser -ErrorAction Stop | Where-Object { $_.Enabled -and ($shared -contains $_.Name) } | ForEach-Object { $_.Name })
341
+ if ($generic.Count) { $issues += "shared or generic accounts: $($generic -join ', ')" }
342
+ if ($issues.Count) { Pass $false ($issues -join '; ') } else { Pass $true 'personal accounts, no automatic login' }
343
+ }
344
+
345
  # BitLocker on the system drive
346
  $Bl = $null; $BlError = $null
347
  try { Assert-Admin; $Bl = Get-BitLockerVolume -MountPoint $env:SystemDrive -ErrorAction Stop } catch { $BlError = $_.Exception.Message }
 
349
  if ($null -eq $Bl) { Add-Result $Id $S $Name 'Error' 'not read' $Expected $BlError } else { Check $Id $S $Name $Expected $Test }
350
  }
351
  BitLockerCheck 'encryption.feature' 'BitLocker' 'on' { Pass ("$($Bl.VolumeStatus)" -ne 'FullyDecrypted') $(if ("$($Bl.VolumeStatus)" -ne 'FullyDecrypted') { 'on' } else { 'off' }) }
352
+ BitLockerCheck 'encryption.enabled' 'Encryption' 'fully encrypted' { Pass ("$($Bl.VolumeStatus)" -eq 'FullyEncrypted') ("BitLocker: {0} ({1}%)" -f $Bl.VolumeStatus, $Bl.EncryptionPercentage) }
353
  BitLockerCheck 'encryption.protection' 'BitLocker protection' 'protection on, AES' {
354
  $method = "$($Bl.EncryptionMethod)"
355
  Pass ("$($Bl.ProtectionStatus)" -eq 'On' -and $method -match 'Aes') ("protection {0}, {1}" -f $Bl.ProtectionStatus, $method)
 
414
  Where-Object { $_.DisplayName -and -not $_.SystemComponent -and -not $_.ParentKeyName } |
415
  ForEach-Object { [ordered]@{ name = "$($_.DisplayName)".Trim(); version = "$($_.DisplayVersion)".Trim(); publisher = "$($_.Publisher)".Trim() } } |
416
  Sort-Object { $_.name + '|' + $_.version } -Unique)
417
+ # Prohibited software (PROHIBITED_SOFTWARE: parts of installed program names, any case). Licences cannot be checked here.
418
+ Check 'software.prohibited' $S 'Prohibited software' $(if ($B.PROHIBITED_SOFTWARE) { "none of: $($B.PROHIBITED_SOFTWARE)" } else { 'none of: (empty list)' }) {
419
+ if (-not $B.PROHIBITED_SOFTWARE) { return State 'Compliant' 'no list configured' 'PROHIBITED_SOFTWARE in baseline.conf is empty.' }
420
+ $found = @($Inventory | Where-Object { $n = $_.name; @(Split-List $B.PROHIBITED_SOFTWARE | Where-Object { $n -like "*$_*" }).Count } | ForEach-Object { $_.name } | Select-Object -Unique)
421
+ if ($found.Count) { Pass $false ($found -join ', ') } else { Pass $true "none found in $($Inventory.Count) programs" }
422
+ }
423
  Check 'vuln.known_vulnerabilities' $S 'Known vulnerabilities in installed software' "<= $($B.MAX_CRITICAL_HIGH_VULNERABILITIES) critical/high" {
424
  # Inventory now; matching against offline OSV/NVD data comes in a later version.
425
  State 'Pending' "$($Inventory.Count) applications inventoried" 'Inventory saved for the Devseis app, which matches it against its offline OSV/NVD vulnerability data; the collector on its own does not match.'
index.html CHANGED
@@ -3,7 +3,7 @@
3
  <head>
4
  <meta charset="utf-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
6
- <meta name="description" content="Arx: a free security audit for your Mac, Windows or Linux computer. 68 checks in about a minute, offline, mapped to ISO 27001, GDPR and the EU AI Act, with one-click fixes on Mac. Nothing is uploaded.">
7
  <meta name="theme-color" content="#ed2939">
8
  <title>Arx · Security audit for your computer</title>
9
  <link rel="icon" href="app/build/icon.png">
@@ -33,7 +33,7 @@
33
  <section class="wrap hero">
34
  <p class="eyebrow"><img src="app/build/icon.png" alt="">Arx security audit</p>
35
  <h1>Is your computer secure?<br><span class="grad">Find out in a minute.</span></h1>
36
- <p class="lead">A free audit of your Mac, Windows or Linux computer: <b>68 checks</b> mapped to <b>ISO 27001</b>, <b>GDPR</b> and the <b>EU AI Act</b>. A small AI on your computer writes the report, and on a Mac Arx can <b>fix problems for you</b>. It runs offline. <u>Nothing is uploaded.</u></p>
37
 
38
  <div class="device-card" id="deviceCard">
39
  <span class="device-icon" id="deviceIcon">💻</span>
@@ -56,12 +56,12 @@
56
  <label class="btn btn-lg" for="reportFile" title="Open the …-evidence.json file Arx saves next to each report">Open a report</label>
57
  <input type="file" id="reportFile" accept=".json,application/json" hidden>
58
  </div>
59
- <p class="tiny muted" id="heroMeta">Free · open source · version 0.5.0</p>
60
  </section>
61
 
62
  <section class="wrap">
63
  <div class="stats">
64
- <div class="stat c-red"><span class="tiny muted">Checks</span><b>68</b><span class="tiny muted">settings &amp; controls</span></div>
65
  <div class="stat c-blue"><span class="tiny muted">Time</span><b>~1 min</b><span class="tiny muted">for the whole audit</span></div>
66
  <div class="stat c-green"><span class="tiny muted">Uploaded</span><b>0 bytes</b><span class="tiny muted">runs offline</span></div>
67
  <div class="stat c-violet"><span class="tiny muted">Frameworks</span><b>3</b><span class="tiny muted">ISO · GDPR · AI Act</span></div>
@@ -69,7 +69,7 @@
69
  </section>
70
 
71
  <section class="wrap section" id="checks">
72
- <div class="section-head"><h2>High-risk checks</h2><a class="tiny muted link" href="#all-checks">See all 68 →</a></div>
73
  <div class="rail" id="riskRail"></div>
74
  </section>
75
 
@@ -95,7 +95,7 @@
95
  </section>
96
 
97
  <section class="wrap section" id="download">
98
- <div class="section-head"><h2>Download Arx</h2><span class="tiny muted" id="dlVersion">Version 0.5.0</span></div>
99
  <div class="dl-grid">
100
  <article class="dl-card" data-os="mac">
101
  <span class="ribbon ribbon-you hidden">YOUR SYSTEM</span>
 
3
  <head>
4
  <meta charset="utf-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
6
+ <meta name="description" content="Arx: a free security audit for your Mac, Windows or Linux computer. 70 checks in about a minute, offline, mapped to ISO 27001, GDPR and the EU AI Act, with one-click fixes on Mac. Nothing is uploaded.">
7
  <meta name="theme-color" content="#ed2939">
8
  <title>Arx · Security audit for your computer</title>
9
  <link rel="icon" href="app/build/icon.png">
 
33
  <section class="wrap hero">
34
  <p class="eyebrow"><img src="app/build/icon.png" alt="">Arx security audit</p>
35
  <h1>Is your computer secure?<br><span class="grad">Find out in a minute.</span></h1>
36
+ <p class="lead">A free audit of your Mac, Windows or Linux computer: <b><span data-count>70</span> checks</b> mapped to <b>ISO 27001</b>, <b>GDPR</b> and the <b>EU AI Act</b>. A small AI on your computer writes the report, and on a Mac Arx can <b>fix problems for you</b>. It runs offline. <u>Nothing is uploaded.</u></p>
37
 
38
  <div class="device-card" id="deviceCard">
39
  <span class="device-icon" id="deviceIcon">💻</span>
 
56
  <label class="btn btn-lg" for="reportFile" title="Open the …-evidence.json file Arx saves next to each report">Open a report</label>
57
  <input type="file" id="reportFile" accept=".json,application/json" hidden>
58
  </div>
59
+ <p class="tiny muted" id="heroMeta">Free · open source · version 0.5.1</p>
60
  </section>
61
 
62
  <section class="wrap">
63
  <div class="stats">
64
+ <div class="stat c-red"><span class="tiny muted">Checks</span><b data-count>70</b><span class="tiny muted">settings &amp; controls</span></div>
65
  <div class="stat c-blue"><span class="tiny muted">Time</span><b>~1 min</b><span class="tiny muted">for the whole audit</span></div>
66
  <div class="stat c-green"><span class="tiny muted">Uploaded</span><b>0 bytes</b><span class="tiny muted">runs offline</span></div>
67
  <div class="stat c-violet"><span class="tiny muted">Frameworks</span><b>3</b><span class="tiny muted">ISO · GDPR · AI Act</span></div>
 
69
  </section>
70
 
71
  <section class="wrap section" id="checks">
72
+ <div class="section-head"><h2>High-risk checks</h2><a class="tiny muted link" href="#all-checks">See all <span data-count>70</span> →</a></div>
73
  <div class="rail" id="riskRail"></div>
74
  </section>
75
 
 
95
  </section>
96
 
97
  <section class="wrap section" id="download">
98
+ <div class="section-head"><h2>Download Arx</h2><span class="tiny muted" id="dlVersion">Version 0.5.1</span></div>
99
  <div class="dl-grid">
100
  <article class="dl-card" data-os="mac">
101
  <span class="ribbon ribbon-you hidden">YOUR SYSTEM</span>
library/check_guidance.json CHANGED
@@ -1,5 +1,5 @@
1
  {
2
- "library_version": "0.3.0",
3
  "note": "Per-check guidance used to write findings. Fix steps are written for administrators; prefer central management (Group Policy/Intune, MDM, configuration management) over per-device changes. Review by a security professional before use with customers.",
4
  "aliases": {
5
  "firewall.domain.enabled": "firewall.enabled",
@@ -257,7 +257,7 @@
257
  "verify": "Re-run the audit; On-access malware protection should be Compliant."
258
  },
259
  "malware.tamper": {
260
- "why": "Tamper protection stops malware or users switching off Defender.",
261
  "risk": {
262
  "level": "Medium",
263
  "reason": "Attackers commonly disable antivirus before deploying ransomware."
@@ -265,6 +265,13 @@
265
  "fix": {
266
  "windows": [
267
  "Turn on Tamper Protection in Windows Security > Virus & threat protection settings, or centrally through Microsoft Intune / Defender for Endpoint (it cannot be set with PowerShell)."
 
 
 
 
 
 
 
268
  ]
269
  },
270
  "verify": "Re-run the audit; Tamper protection should be on."
@@ -1219,6 +1226,50 @@
1219
  ]
1220
  },
1221
  "verify": "Re-run the phone check; previews should be hidden when the phone is locked."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1222
  }
1223
  }
1224
  }
 
1
  {
2
+ "library_version": "0.4.0",
3
  "note": "Per-check guidance used to write findings. Fix steps are written for administrators; prefer central management (Group Policy/Intune, MDM, configuration management) over per-device changes. Review by a security professional before use with customers.",
4
  "aliases": {
5
  "firewall.domain.enabled": "firewall.enabled",
 
257
  "verify": "Re-run the audit; On-access malware protection should be Compliant."
258
  },
259
  "malware.tamper": {
260
+ "why": "Tamper protection stops malware, or a user, from switching off the device's security protection.",
261
  "risk": {
262
  "level": "Medium",
263
  "reason": "Attackers commonly disable antivirus before deploying ransomware."
 
265
  "fix": {
266
  "windows": [
267
  "Turn on Tamper Protection in Windows Security > Virus & threat protection settings, or centrally through Microsoft Intune / Defender for Endpoint (it cannot be set with PowerShell)."
268
+ ],
269
+ "macos": [
270
+ "System Integrity Protection can only be turned back on from Recovery: start the Mac in Recovery mode, open Terminal and run csrutil enable, then restart. Ask IT first if a tool needed it off."
271
+ ],
272
+ "linux": [
273
+ "Ubuntu / Debian: sudo apt install apparmor apparmor-utils && sudo systemctl enable --now apparmor (profiles load in enforce mode).",
274
+ "RHEL / Fedora: set SELINUX=enforcing in /etc/selinux/config, run sudo touch /.autorelabel and restart."
275
  ]
276
  },
277
  "verify": "Re-run the audit; Tamper protection should be on."
 
1226
  ]
1227
  },
1228
  "verify": "Re-run the phone check; previews should be hidden when the phone is locked."
1229
+ },
1230
+ "account.unique_login": {
1231
+ "why": "Every action on a device should be traceable to one person. Automatic login lets anyone who turns the computer on use it, and shared accounts hide who did what.",
1232
+ "risk": {
1233
+ "level": "Medium",
1234
+ "reason": "With shared or automatic logins, a lost or borrowed device opens straight into someone's data, and incidents cannot be traced to a person."
1235
+ },
1236
+ "fix": {
1237
+ "macos": [
1238
+ "Turn off automatic login: System Settings > Users & Groups > Automatically log in as: Off.",
1239
+ "Give each person their own account and remove or rename shared ones such as office or admin (keep one named, approved IT administrator)."
1240
+ ],
1241
+ "windows": [
1242
+ "Turn off automatic sign-in: run netplwiz and tick 'Users must enter a user name and password', or set AutoAdminLogon = 0 under HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon.",
1243
+ "Give each person their own account and disable or remove shared local accounts (Computer Management > Local Users and Groups)."
1244
+ ],
1245
+ "linux": [
1246
+ "Turn off automatic login in Settings > Users, or set AutomaticLoginEnable=false in /etc/gdm3/custom.conf (autologin-user= in LightDM, [Autologin] User= in SDDM).",
1247
+ "Give each person their own account; lock shared ones with sudo usermod -L <name>."
1248
+ ]
1249
+ },
1250
+ "verify": "Re-run the audit; Unique user login should be Compliant."
1251
+ },
1252
+ "software.prohibited": {
1253
+ "why": "Torrent clients and activation cracks are common sources of malware and of unlicensed software, which is a legal and licence-audit risk.",
1254
+ "risk": {
1255
+ "level": "High",
1256
+ "reason": "Activation cracks and pirated downloads often carry malware, and unlicensed software breaches copyright and licence terms."
1257
+ },
1258
+ "fix": {
1259
+ "macos": [
1260
+ "Quit the app and drag it from Applications to the Bin, then empty the Bin.",
1261
+ "If the software is needed for work, ask IT to approve it and remove its name from PROHIBITED_SOFTWARE in baseline.conf."
1262
+ ],
1263
+ "windows": [
1264
+ "Uninstall it in Settings > Apps > Installed apps. For activation cracks, also run a full Microsoft Defender scan and activate Windows/Office with a genuine licence.",
1265
+ "If the software is needed for work, ask IT to approve it and remove its name from PROHIBITED_SOFTWARE in baseline.conf."
1266
+ ],
1267
+ "linux": [
1268
+ "Remove the package: sudo apt remove <package> (or sudo dnf remove <package>, flatpak uninstall, snap remove).",
1269
+ "If the software is needed for work, ask IT to approve it and remove its name from PROHIBITED_SOFTWARE in baseline.conf."
1270
+ ]
1271
+ },
1272
+ "verify": "Re-run the audit; Prohibited software should show none found."
1273
  }
1274
  }
1275
  }
library/controls.json CHANGED
@@ -2,199 +2,526 @@
2
  "library_version": "0.1.0",
3
  "note": "Written by Devseis in its own words for retrieval by the auditor model. ISO/IEC 27001:2022 control titles are cited; the standard's text is not reproduced. GDPR and AI Act entries summarise the law and are not legal advice.",
4
  "controls": [
5
- { "id": "A.5.9", "framework": "ISO 27001:2022", "title": "Inventory of information and other associated assets",
 
 
 
6
  "summary": "Know which information assets, devices and software exist and who owns them, and keep that list current.",
7
- "auditor_looks_for": ["An up-to-date asset list that includes endpoints and installed software", "An owner for each asset"],
8
- "endpoint_relevance": "Each endpoint and the software on it (including AI tools) should appear in the inventory." },
9
- { "id": "A.5.12", "framework": "ISO 27001:2022", "title": "Classification of information",
 
 
 
 
 
 
 
10
  "summary": "Label information by how sensitive it is so that the right protection can be applied.",
11
- "auditor_looks_for": ["A classification scheme", "Evidence that sensitive data is identified, e.g. personal data"],
12
- "endpoint_relevance": "Personal or confidential files stored on laptops need to be found and protected accordingly." },
13
- { "id": "A.5.15", "framework": "ISO 27001:2022", "title": "Access control",
 
 
 
 
 
 
 
14
  "summary": "Grant access to information and systems based on business need, and document the rules.",
15
- "auditor_looks_for": ["An access control policy", "Administrative access limited to named, approved people"],
16
- "endpoint_relevance": "Only approved IT staff should hold administrator rights on endpoints." },
17
- { "id": "A.5.16", "framework": "ISO 27001:2022", "title": "Identity management",
 
 
 
 
 
 
 
18
  "summary": "Every account belongs to an identifiable person or a documented service, through its whole life cycle.",
19
- "auditor_looks_for": ["No shared or anonymous accounts", "Disabled guest and default accounts"],
20
- "endpoint_relevance": "Guest accounts and anonymous logins break the link between actions and people." },
21
- { "id": "A.5.17", "framework": "ISO 27001:2022", "title": "Authentication information",
 
 
 
 
 
 
 
22
  "summary": "Passwords and other secrets are allocated, managed and protected under clear rules.",
23
- "auditor_looks_for": ["A password rule set (length, reuse, change) enforced by the system", "Users told how to protect their passwords"],
24
- "endpoint_relevance": "The device's password policy is the technical enforcement of these rules." },
25
- { "id": "A.5.18", "framework": "ISO 27001:2022", "title": "Access rights",
 
 
 
 
 
 
 
26
  "summary": "Access rights are granted, reviewed regularly and removed when no longer needed.",
27
- "auditor_looks_for": ["Periodic review of who has administrator rights", "Removal of rights that are not justified"],
28
- "endpoint_relevance": "Employee accounts that are local administrators without approval are a finding." },
29
- { "id": "A.5.20", "framework": "ISO 27001:2022", "title": "Addressing information security within supplier agreements",
 
 
 
 
 
 
 
30
  "summary": "Agreements with suppliers set out the security requirements they must meet.",
31
- "auditor_looks_for": ["Signed agreements with security and data protection clauses"],
32
- "endpoint_relevance": "Cloud and AI services used from endpoints are suppliers that need agreements." },
33
- { "id": "A.5.24", "framework": "ISO 27001:2022", "title": "Information security incident management planning and preparation",
 
 
 
 
 
 
34
  "summary": "Plan in advance how security incidents are reported, handled and communicated.",
35
- "auditor_looks_for": ["A documented incident procedure with roles", "Contact points and escalation paths"],
36
- "endpoint_relevance": "Endpoint logs and alerts feed the incident process." },
37
- { "id": "A.5.26", "framework": "ISO 27001:2022", "title": "Response to information security incidents",
 
 
 
 
 
 
 
38
  "summary": "Respond to incidents according to the documented procedure.",
39
- "auditor_looks_for": ["Records of past incidents and how they were handled"],
40
- "endpoint_relevance": "Investigations depend on endpoint evidence being available and trustworthy." },
41
- { "id": "A.5.34", "framework": "ISO 27001:2022", "title": "Privacy and protection of PII",
 
 
 
 
 
 
42
  "summary": "Meet the legal and contractual requirements for protecting personal data.",
43
- "auditor_looks_for": ["Links between the ISMS and GDPR compliance", "Minimised collection and sharing of personal data"],
44
- "endpoint_relevance": "Diagnostic data sharing and OS AI features can send personal data off the device." },
45
- { "id": "A.6.3", "framework": "ISO 27001:2022", "title": "Information security awareness, education and training",
 
 
 
 
 
 
 
46
  "summary": "People receive awareness and training suited to their role, and it is kept current.",
47
- "auditor_looks_for": ["Training records", "Topics that match the risks people face (including AI use)"],
48
- "endpoint_relevance": "Users decide what they install and share; training reduces shadow IT and shadow AI." },
49
- { "id": "A.6.7", "framework": "ISO 27001:2022", "title": "Remote working",
 
 
 
 
 
 
 
50
  "summary": "Protect information accessed, processed or stored outside the organisation's premises.",
51
- "auditor_looks_for": ["Rules for remote access tools", "Only approved remote access services enabled"],
52
- "endpoint_relevance": "Remote desktop and screen sharing services open the device to outside access." },
53
- { "id": "A.7.7", "framework": "ISO 27001:2022", "title": "Clear desk and clear screen",
 
 
 
 
 
 
 
54
  "summary": "Unattended screens and papers must not expose information.",
55
- "auditor_looks_for": ["Automatic screen lock after a short idle time", "A password needed to unlock"],
56
- "endpoint_relevance": "The screen lock settings are the technical control for clear screen." },
57
- { "id": "A.7.10", "framework": "ISO 27001:2022", "title": "Storage media",
 
 
 
 
 
 
 
58
  "summary": "Manage removable media through its life cycle according to the classification of the data on it.",
59
- "auditor_looks_for": ["Rules for USB and external drives", "Encryption or blocking of removable media"],
60
- "endpoint_relevance": "Unrestricted USB writing lets data leave the device unencrypted." },
61
- { "id": "A.8.1", "framework": "ISO 27001:2022", "title": "User endpoint devices",
 
 
 
 
 
 
 
62
  "summary": "Protect information stored on, processed by or reachable from user devices.",
63
- "auditor_looks_for": ["A baseline configuration for laptops and desktops", "Encryption, firewall, screen lock and malware protection enforced"],
64
- "endpoint_relevance": "This is the main control the whole endpoint baseline supports." },
65
- { "id": "A.8.2", "framework": "ISO 27001:2022", "title": "Privileged access rights",
 
 
 
 
 
 
 
66
  "summary": "Restrict and manage the allocation and use of administrator rights.",
67
- "auditor_looks_for": ["Named, approved administrators", "No everyday user accounts with administrator rights"],
68
- "endpoint_relevance": "Local administrator membership on each device shows whether this control works." },
69
- { "id": "A.8.5", "framework": "ISO 27001:2022", "title": "Secure authentication",
 
 
 
 
 
 
 
70
  "summary": "Authentication methods and procedures resist guessing, brute force and misuse.",
71
- "auditor_looks_for": ["Account lockout after repeated failures", "Strong password or multi-factor requirements"],
72
- "endpoint_relevance": "Lockout, complexity and screen-unlock settings implement this on the device." },
73
- { "id": "A.8.7", "framework": "ISO 27001:2022", "title": "Protection against malware",
 
 
 
 
 
 
 
74
  "summary": "Protect against malware with technical controls supported by user awareness.",
75
- "auditor_looks_for": ["Anti-malware running with current signatures", "Protection that cannot easily be switched off"],
76
- "endpoint_relevance": "Antivirus status, real-time scanning, tamper protection and signature age are checked on each device." },
77
- { "id": "A.8.8", "framework": "ISO 27001:2022", "title": "Management of technical vulnerabilities",
 
 
 
 
 
 
 
78
  "summary": "Find technical weaknesses in time, judge the exposure and fix them.",
79
- "auditor_looks_for": ["Timely patching", "Supported operating system versions"],
80
- "endpoint_relevance": "Automatic updates, recent patch dates and a supported OS show vulnerabilities are being managed." },
81
- { "id": "A.8.12", "framework": "ISO 27001:2022", "title": "Data leakage prevention",
 
 
 
 
 
 
 
82
  "summary": "Apply measures that stop sensitive information leaving through unauthorised channels.",
83
- "auditor_looks_for": ["Controls on removable media and uploads", "Monitoring of data leaving the organisation"],
84
- "endpoint_relevance": "USB storage write access is a common leakage channel." },
85
- { "id": "A.8.13", "framework": "ISO 27001:2022", "title": "Information backup",
 
 
 
 
 
 
 
86
  "summary": "Keep backup copies of information and software and test that they can be restored.",
87
- "auditor_looks_for": ["Backups configured and recent", "Recovery keys and restore procedures available"],
88
- "endpoint_relevance": "Work stored only on a laptop is lost if the device fails, is stolen or is encrypted by ransomware." },
89
- { "id": "A.8.15", "framework": "ISO 27001:2022", "title": "Logging",
 
 
 
 
 
 
 
90
  "summary": "Produce, protect and review logs of activities, exceptions and security events.",
91
- "auditor_looks_for": ["Logon and account changes recorded", "Logs kept long enough for investigation"],
92
- "endpoint_relevance": "Without security event logs, a breach on the device cannot be reconstructed." },
93
- { "id": "A.8.17", "framework": "ISO 27001:2022", "title": "Clock synchronization",
 
 
 
 
 
 
 
94
  "summary": "Synchronise system clocks to an approved time source.",
95
- "auditor_looks_for": ["All devices using network time"],
96
- "endpoint_relevance": "Correct timestamps are needed to correlate events across devices during an incident." },
97
- { "id": "A.8.19", "framework": "ISO 27001:2022", "title": "Installation of software on operational systems",
 
 
 
 
 
 
98
  "summary": "Control which software users may install.",
99
- "auditor_looks_for": ["An approved software list", "Restrictions on self-installed software"],
100
- "endpoint_relevance": "Unapproved AI tools and remote access tools are signs this control is missing." },
101
- { "id": "A.8.20", "framework": "ISO 27001:2022", "title": "Networks security",
 
 
 
 
 
 
 
102
  "summary": "Secure, manage and control networks and network devices to protect information.",
103
- "auditor_looks_for": ["Host firewalls enabled", "Unsolicited inbound connections blocked"],
104
- "endpoint_relevance": "The host firewall protects the laptop on untrusted networks such as hotels and cafés." },
105
- { "id": "A.8.24", "framework": "ISO 27001:2022", "title": "Use of cryptography",
 
 
 
 
 
 
 
106
  "summary": "Define and apply rules for using cryptography, including key management.",
107
- "auditor_looks_for": ["Full-disk encryption with strong algorithms", "Recovery keys stored safely"],
108
- "endpoint_relevance": "Disk encryption protects data on lost or stolen devices." },
109
-
110
- { "id": "Art. 5(1)(c)", "framework": "GDPR", "title": "Data minimisation",
 
 
 
 
 
 
111
  "summary": "Personal data must be adequate, relevant and limited to what is necessary for the purpose.",
112
- "auditor_looks_for": ["Only necessary data collected or shared", "OS and app data sharing reduced to the minimum"],
113
- "endpoint_relevance": "Optional diagnostic data and AI features that capture screen content collect more than needed." },
114
- { "id": "Art. 5(1)(e)", "framework": "GDPR", "title": "Storage limitation",
 
 
 
 
 
 
 
115
  "summary": "Personal data must not be kept in identifiable form longer than necessary.",
116
- "auditor_looks_for": ["Retention rules", "Old personal data deleted"],
117
- "endpoint_relevance": "Copies of personal data left on laptops are often kept far longer than allowed." },
118
- { "id": "Art. 5(1)(f)", "framework": "GDPR", "title": "Integrity and confidentiality",
 
 
 
 
 
 
 
119
  "summary": "Personal data must be protected against unauthorised access, loss and damage with appropriate measures.",
120
- "auditor_looks_for": ["Technical security measures in place"],
121
- "endpoint_relevance": "The endpoint security baseline is part of these measures." },
122
- { "id": "Art. 25", "framework": "GDPR", "title": "Data protection by design and by default",
 
 
 
 
 
 
123
  "summary": "Build data protection into systems and use privacy-friendly settings by default.",
124
- "auditor_looks_for": ["Privacy-protective default settings on devices and software"],
125
- "endpoint_relevance": "Telemetry and AI data-collection features should be off unless needed." },
126
- { "id": "Art. 28", "framework": "GDPR", "title": "Processor",
 
 
 
 
 
 
127
  "summary": "Use only processors that give sufficient guarantees, under a written contract with required terms.",
128
- "auditor_looks_for": ["A data processing agreement with each processor"],
129
- "endpoint_relevance": "Cloud AI tools used with work data are processors and need an agreement." },
130
- { "id": "Art. 30", "framework": "GDPR", "title": "Records of processing activities",
 
 
 
 
 
 
131
  "summary": "Keep a written record of the processing activities you carry out.",
132
- "auditor_looks_for": ["A current record of processing (RoPA)"],
133
- "endpoint_relevance": "Processing done with endpoint tools, including AI tools, belongs in the record." },
134
- { "id": "Art. 32(1)(a)", "framework": "GDPR", "title": "Security of processing: pseudonymisation and encryption",
 
 
 
 
 
 
135
  "summary": "Where appropriate, protect personal data with pseudonymisation and encryption.",
136
- "auditor_looks_for": ["Encrypted devices and removable media"],
137
- "endpoint_relevance": "Disk encryption is the standard measure for laptops holding personal data." },
138
- { "id": "Art. 32(1)(b)", "framework": "GDPR", "title": "Security of processing: confidentiality, integrity, availability and resilience",
 
 
 
 
 
 
139
  "summary": "Ensure the ongoing confidentiality, integrity, availability and resilience of systems that process personal data.",
140
- "auditor_looks_for": ["Access control, malware protection, patching and network protection on devices"],
141
- "endpoint_relevance": "Most endpoint baseline checks support this requirement." },
142
- { "id": "Art. 32(1)(c)", "framework": "GDPR", "title": "Security of processing: restore availability and access after an incident",
 
 
 
 
 
 
143
  "summary": "Be able to restore access to personal data in time after a physical or technical incident.",
144
- "auditor_looks_for": ["Working backups", "Recovery keys available"],
145
- "endpoint_relevance": "Backups and disk-encryption recovery keys make restoration possible." },
146
- { "id": "Art. 32(1)(d)", "framework": "GDPR", "title": "Security of processing: regular testing and evaluation",
 
 
 
 
 
 
 
147
  "summary": "Regularly test, assess and evaluate whether security measures work.",
148
- "auditor_looks_for": ["Periodic audits such as this one", "Evidence that findings are followed up"],
149
- "endpoint_relevance": "Weekly audits and logging provide this evidence." },
150
- { "id": "Art. 33", "framework": "GDPR", "title": "Notification of a personal data breach to the supervisory authority",
 
 
 
 
 
 
 
151
  "summary": "Report a personal data breach to the supervisory authority within 72 hours of becoming aware of it, unless it is unlikely to result in a risk.",
152
- "auditor_looks_for": ["A breach procedure", "Logs and accurate time to establish what happened"],
153
- "endpoint_relevance": "Security logs and time synchronisation make the 72-hour assessment possible." },
154
- { "id": "Art. 34", "framework": "GDPR", "title": "Communication of a personal data breach to the data subject",
 
 
 
 
 
 
 
155
  "summary": "Tell affected people about a high-risk breach without undue delay; encryption can remove this duty.",
156
- "auditor_looks_for": ["Encryption that makes lost data unintelligible"],
157
- "endpoint_relevance": "Encrypted devices and media can avoid the need to notify individuals." },
158
- { "id": "Art. 35", "framework": "GDPR", "title": "Data protection impact assessment",
 
 
 
 
 
 
159
  "summary": "Assess the impact before processing that is likely to result in a high risk to people.",
160
- "auditor_looks_for": ["DPIAs for high-risk processing"],
161
- "endpoint_relevance": "New tools with high-risk processing, such as AI used on employees, may need a DPIA." },
162
- { "id": "Art. 44", "framework": "GDPR", "title": "General principle for transfers",
 
 
 
 
 
 
163
  "summary": "Transfer personal data outside the EEA only under the conditions of Chapter V.",
164
- "auditor_looks_for": ["A transfer basis (e.g. adequacy decision, standard contractual clauses) for non-EEA services"],
165
- "endpoint_relevance": "Cloud AI tools often process data outside the EEA." },
166
-
167
- { "id": "Art. 4", "framework": "EU AI Act", "title": "AI literacy",
 
 
 
 
 
168
  "summary": "Providers and deployers take measures so their staff using AI have a sufficient level of AI literacy.",
169
- "auditor_looks_for": ["AI training for staff who use AI tools"],
170
- "endpoint_relevance": "AI tools found on endpoints show who needs AI literacy training." },
171
- { "id": "Art. 5", "framework": "EU AI Act", "title": "Prohibited AI practices",
 
 
 
 
 
 
172
  "summary": "Certain AI uses are banned, such as emotion recognition at work and in education (with narrow exceptions) and social scoring.",
173
- "auditor_looks_for": ["No AI tools used for banned purposes"],
174
- "endpoint_relevance": "The purpose of each detected AI tool must be checked against the banned list." },
175
- { "id": "Art. 6", "framework": "EU AI Act", "title": "Classification rules for high-risk AI systems",
 
 
 
 
 
 
176
  "summary": "An AI system is high-risk if it is a safety component of regulated products or is used for a purpose listed in Annex III.",
177
- "auditor_looks_for": ["A risk classification for each AI system in use"],
178
- "endpoint_relevance": "Classification depends on what the tool is used for, not only on which tool it is." },
179
- { "id": "Art. 14", "framework": "EU AI Act", "title": "Human oversight",
 
 
 
 
 
 
180
  "summary": "High-risk AI systems must be designed so that people can oversee them effectively.",
181
- "auditor_looks_for": ["Named, trained people overseeing each high-risk AI system"],
182
- "endpoint_relevance": "Applies only when a high-risk AI system is in use." },
183
- { "id": "Art. 26", "framework": "EU AI Act", "title": "Obligations of deployers of high-risk AI systems",
 
 
 
 
 
 
184
  "summary": "Deployers must use high-risk AI as instructed, assign human oversight, monitor it, keep logs and inform affected people.",
185
- "auditor_looks_for": ["An AI register", "Use according to instructions", "Monitoring and log retention"],
186
- "endpoint_relevance": "The AI software inventory is the starting point for these duties." },
187
- { "id": "Art. 26(6)", "framework": "EU AI Act", "title": "Deployers: keep automatically generated logs for at least six months",
 
 
 
 
 
 
 
 
188
  "summary": "Deployers keep the logs a high-risk AI system generates, under their control, for at least six months unless other law says otherwise.",
189
- "auditor_looks_for": ["Log retention of at least six months for high-risk AI systems"],
190
- "endpoint_relevance": "Only applies if a detected AI tool is used in a high-risk way." },
191
- { "id": "Art. 50", "framework": "EU AI Act", "title": "Transparency obligations for providers and deployers of certain AI systems",
 
 
 
 
 
 
192
  "summary": "People must be told when they interact with an AI system, and deepfakes and certain AI-generated text must be disclosed.",
193
- "auditor_looks_for": ["Disclosure practices for chatbots and AI-generated content"],
194
- "endpoint_relevance": "Staff publishing AI-generated content need clear rules." },
195
- { "id": "Annex III", "framework": "EU AI Act", "title": "High-risk AI systems referred to in Article 6(2)",
 
 
 
 
 
 
196
  "summary": "Lists high-risk uses such as biometrics, critical infrastructure, education, employment and worker management, access to essential services, law enforcement, migration and justice.",
197
- "auditor_looks_for": ["No unassessed use of AI for employment decisions, credit scoring or similar Annex III purposes"],
198
- "endpoint_relevance": "A general AI assistant becomes high-risk if used, for example, to screen job applicants." }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  ]
200
  }
 
2
  "library_version": "0.1.0",
3
  "note": "Written by Devseis in its own words for retrieval by the auditor model. ISO/IEC 27001:2022 control titles are cited; the standard's text is not reproduced. GDPR and AI Act entries summarise the law and are not legal advice.",
4
  "controls": [
5
+ {
6
+ "id": "A.5.9",
7
+ "framework": "ISO 27001:2022",
8
+ "title": "Inventory of information and other associated assets",
9
  "summary": "Know which information assets, devices and software exist and who owns them, and keep that list current.",
10
+ "auditor_looks_for": [
11
+ "An up-to-date asset list that includes endpoints and installed software",
12
+ "An owner for each asset"
13
+ ],
14
+ "endpoint_relevance": "Each endpoint and the software on it (including AI tools) should appear in the inventory."
15
+ },
16
+ {
17
+ "id": "A.5.12",
18
+ "framework": "ISO 27001:2022",
19
+ "title": "Classification of information",
20
  "summary": "Label information by how sensitive it is so that the right protection can be applied.",
21
+ "auditor_looks_for": [
22
+ "A classification scheme",
23
+ "Evidence that sensitive data is identified, e.g. personal data"
24
+ ],
25
+ "endpoint_relevance": "Personal or confidential files stored on laptops need to be found and protected accordingly."
26
+ },
27
+ {
28
+ "id": "A.5.15",
29
+ "framework": "ISO 27001:2022",
30
+ "title": "Access control",
31
  "summary": "Grant access to information and systems based on business need, and document the rules.",
32
+ "auditor_looks_for": [
33
+ "An access control policy",
34
+ "Administrative access limited to named, approved people"
35
+ ],
36
+ "endpoint_relevance": "Only approved IT staff should hold administrator rights on endpoints."
37
+ },
38
+ {
39
+ "id": "A.5.16",
40
+ "framework": "ISO 27001:2022",
41
+ "title": "Identity management",
42
  "summary": "Every account belongs to an identifiable person or a documented service, through its whole life cycle.",
43
+ "auditor_looks_for": [
44
+ "No shared or anonymous accounts",
45
+ "Disabled guest and default accounts"
46
+ ],
47
+ "endpoint_relevance": "Guest accounts and anonymous logins break the link between actions and people."
48
+ },
49
+ {
50
+ "id": "A.5.17",
51
+ "framework": "ISO 27001:2022",
52
+ "title": "Authentication information",
53
  "summary": "Passwords and other secrets are allocated, managed and protected under clear rules.",
54
+ "auditor_looks_for": [
55
+ "A password rule set (length, reuse, change) enforced by the system",
56
+ "Users told how to protect their passwords"
57
+ ],
58
+ "endpoint_relevance": "The device's password policy is the technical enforcement of these rules."
59
+ },
60
+ {
61
+ "id": "A.5.18",
62
+ "framework": "ISO 27001:2022",
63
+ "title": "Access rights",
64
  "summary": "Access rights are granted, reviewed regularly and removed when no longer needed.",
65
+ "auditor_looks_for": [
66
+ "Periodic review of who has administrator rights",
67
+ "Removal of rights that are not justified"
68
+ ],
69
+ "endpoint_relevance": "Employee accounts that are local administrators without approval are a finding."
70
+ },
71
+ {
72
+ "id": "A.5.20",
73
+ "framework": "ISO 27001:2022",
74
+ "title": "Addressing information security within supplier agreements",
75
  "summary": "Agreements with suppliers set out the security requirements they must meet.",
76
+ "auditor_looks_for": [
77
+ "Signed agreements with security and data protection clauses"
78
+ ],
79
+ "endpoint_relevance": "Cloud and AI services used from endpoints are suppliers that need agreements."
80
+ },
81
+ {
82
+ "id": "A.5.24",
83
+ "framework": "ISO 27001:2022",
84
+ "title": "Information security incident management planning and preparation",
85
  "summary": "Plan in advance how security incidents are reported, handled and communicated.",
86
+ "auditor_looks_for": [
87
+ "A documented incident procedure with roles",
88
+ "Contact points and escalation paths"
89
+ ],
90
+ "endpoint_relevance": "Endpoint logs and alerts feed the incident process."
91
+ },
92
+ {
93
+ "id": "A.5.26",
94
+ "framework": "ISO 27001:2022",
95
+ "title": "Response to information security incidents",
96
  "summary": "Respond to incidents according to the documented procedure.",
97
+ "auditor_looks_for": [
98
+ "Records of past incidents and how they were handled"
99
+ ],
100
+ "endpoint_relevance": "Investigations depend on endpoint evidence being available and trustworthy."
101
+ },
102
+ {
103
+ "id": "A.5.34",
104
+ "framework": "ISO 27001:2022",
105
+ "title": "Privacy and protection of PII",
106
  "summary": "Meet the legal and contractual requirements for protecting personal data.",
107
+ "auditor_looks_for": [
108
+ "Links between the ISMS and GDPR compliance",
109
+ "Minimised collection and sharing of personal data"
110
+ ],
111
+ "endpoint_relevance": "Diagnostic data sharing and OS AI features can send personal data off the device."
112
+ },
113
+ {
114
+ "id": "A.6.3",
115
+ "framework": "ISO 27001:2022",
116
+ "title": "Information security awareness, education and training",
117
  "summary": "People receive awareness and training suited to their role, and it is kept current.",
118
+ "auditor_looks_for": [
119
+ "Training records",
120
+ "Topics that match the risks people face (including AI use)"
121
+ ],
122
+ "endpoint_relevance": "Users decide what they install and share; training reduces shadow IT and shadow AI."
123
+ },
124
+ {
125
+ "id": "A.6.7",
126
+ "framework": "ISO 27001:2022",
127
+ "title": "Remote working",
128
  "summary": "Protect information accessed, processed or stored outside the organisation's premises.",
129
+ "auditor_looks_for": [
130
+ "Rules for remote access tools",
131
+ "Only approved remote access services enabled"
132
+ ],
133
+ "endpoint_relevance": "Remote desktop and screen sharing services open the device to outside access."
134
+ },
135
+ {
136
+ "id": "A.7.7",
137
+ "framework": "ISO 27001:2022",
138
+ "title": "Clear desk and clear screen",
139
  "summary": "Unattended screens and papers must not expose information.",
140
+ "auditor_looks_for": [
141
+ "Automatic screen lock after a short idle time",
142
+ "A password needed to unlock"
143
+ ],
144
+ "endpoint_relevance": "The screen lock settings are the technical control for clear screen."
145
+ },
146
+ {
147
+ "id": "A.7.10",
148
+ "framework": "ISO 27001:2022",
149
+ "title": "Storage media",
150
  "summary": "Manage removable media through its life cycle according to the classification of the data on it.",
151
+ "auditor_looks_for": [
152
+ "Rules for USB and external drives",
153
+ "Encryption or blocking of removable media"
154
+ ],
155
+ "endpoint_relevance": "Unrestricted USB writing lets data leave the device unencrypted."
156
+ },
157
+ {
158
+ "id": "A.8.1",
159
+ "framework": "ISO 27001:2022",
160
+ "title": "User endpoint devices",
161
  "summary": "Protect information stored on, processed by or reachable from user devices.",
162
+ "auditor_looks_for": [
163
+ "A baseline configuration for laptops and desktops",
164
+ "Encryption, firewall, screen lock and malware protection enforced"
165
+ ],
166
+ "endpoint_relevance": "This is the main control the whole endpoint baseline supports."
167
+ },
168
+ {
169
+ "id": "A.8.2",
170
+ "framework": "ISO 27001:2022",
171
+ "title": "Privileged access rights",
172
  "summary": "Restrict and manage the allocation and use of administrator rights.",
173
+ "auditor_looks_for": [
174
+ "Named, approved administrators",
175
+ "No everyday user accounts with administrator rights"
176
+ ],
177
+ "endpoint_relevance": "Local administrator membership on each device shows whether this control works."
178
+ },
179
+ {
180
+ "id": "A.8.5",
181
+ "framework": "ISO 27001:2022",
182
+ "title": "Secure authentication",
183
  "summary": "Authentication methods and procedures resist guessing, brute force and misuse.",
184
+ "auditor_looks_for": [
185
+ "Account lockout after repeated failures",
186
+ "Strong password or multi-factor requirements"
187
+ ],
188
+ "endpoint_relevance": "Lockout, complexity and screen-unlock settings implement this on the device."
189
+ },
190
+ {
191
+ "id": "A.8.7",
192
+ "framework": "ISO 27001:2022",
193
+ "title": "Protection against malware",
194
  "summary": "Protect against malware with technical controls supported by user awareness.",
195
+ "auditor_looks_for": [
196
+ "Anti-malware running with current signatures",
197
+ "Protection that cannot easily be switched off"
198
+ ],
199
+ "endpoint_relevance": "Antivirus status, real-time scanning, tamper protection and signature age are checked on each device."
200
+ },
201
+ {
202
+ "id": "A.8.8",
203
+ "framework": "ISO 27001:2022",
204
+ "title": "Management of technical vulnerabilities",
205
  "summary": "Find technical weaknesses in time, judge the exposure and fix them.",
206
+ "auditor_looks_for": [
207
+ "Timely patching",
208
+ "Supported operating system versions"
209
+ ],
210
+ "endpoint_relevance": "Automatic updates, recent patch dates and a supported OS show vulnerabilities are being managed."
211
+ },
212
+ {
213
+ "id": "A.8.12",
214
+ "framework": "ISO 27001:2022",
215
+ "title": "Data leakage prevention",
216
  "summary": "Apply measures that stop sensitive information leaving through unauthorised channels.",
217
+ "auditor_looks_for": [
218
+ "Controls on removable media and uploads",
219
+ "Monitoring of data leaving the organisation"
220
+ ],
221
+ "endpoint_relevance": "USB storage write access is a common leakage channel."
222
+ },
223
+ {
224
+ "id": "A.8.13",
225
+ "framework": "ISO 27001:2022",
226
+ "title": "Information backup",
227
  "summary": "Keep backup copies of information and software and test that they can be restored.",
228
+ "auditor_looks_for": [
229
+ "Backups configured and recent",
230
+ "Recovery keys and restore procedures available"
231
+ ],
232
+ "endpoint_relevance": "Work stored only on a laptop is lost if the device fails, is stolen or is encrypted by ransomware."
233
+ },
234
+ {
235
+ "id": "A.8.15",
236
+ "framework": "ISO 27001:2022",
237
+ "title": "Logging",
238
  "summary": "Produce, protect and review logs of activities, exceptions and security events.",
239
+ "auditor_looks_for": [
240
+ "Logon and account changes recorded",
241
+ "Logs kept long enough for investigation"
242
+ ],
243
+ "endpoint_relevance": "Without security event logs, a breach on the device cannot be reconstructed."
244
+ },
245
+ {
246
+ "id": "A.8.17",
247
+ "framework": "ISO 27001:2022",
248
+ "title": "Clock synchronization",
249
  "summary": "Synchronise system clocks to an approved time source.",
250
+ "auditor_looks_for": [
251
+ "All devices using network time"
252
+ ],
253
+ "endpoint_relevance": "Correct timestamps are needed to correlate events across devices during an incident."
254
+ },
255
+ {
256
+ "id": "A.8.19",
257
+ "framework": "ISO 27001:2022",
258
+ "title": "Installation of software on operational systems",
259
  "summary": "Control which software users may install.",
260
+ "auditor_looks_for": [
261
+ "An approved software list",
262
+ "Restrictions on self-installed software"
263
+ ],
264
+ "endpoint_relevance": "Unapproved AI tools and remote access tools are signs this control is missing."
265
+ },
266
+ {
267
+ "id": "A.8.20",
268
+ "framework": "ISO 27001:2022",
269
+ "title": "Networks security",
270
  "summary": "Secure, manage and control networks and network devices to protect information.",
271
+ "auditor_looks_for": [
272
+ "Host firewalls enabled",
273
+ "Unsolicited inbound connections blocked"
274
+ ],
275
+ "endpoint_relevance": "The host firewall protects the laptop on untrusted networks such as hotels and cafés."
276
+ },
277
+ {
278
+ "id": "A.8.24",
279
+ "framework": "ISO 27001:2022",
280
+ "title": "Use of cryptography",
281
  "summary": "Define and apply rules for using cryptography, including key management.",
282
+ "auditor_looks_for": [
283
+ "Full-disk encryption with strong algorithms",
284
+ "Recovery keys stored safely"
285
+ ],
286
+ "endpoint_relevance": "Disk encryption protects data on lost or stolen devices."
287
+ },
288
+ {
289
+ "id": "Art. 5(1)(c)",
290
+ "framework": "GDPR",
291
+ "title": "Data minimisation",
292
  "summary": "Personal data must be adequate, relevant and limited to what is necessary for the purpose.",
293
+ "auditor_looks_for": [
294
+ "Only necessary data collected or shared",
295
+ "OS and app data sharing reduced to the minimum"
296
+ ],
297
+ "endpoint_relevance": "Optional diagnostic data and AI features that capture screen content collect more than needed."
298
+ },
299
+ {
300
+ "id": "Art. 5(1)(e)",
301
+ "framework": "GDPR",
302
+ "title": "Storage limitation",
303
  "summary": "Personal data must not be kept in identifiable form longer than necessary.",
304
+ "auditor_looks_for": [
305
+ "Retention rules",
306
+ "Old personal data deleted"
307
+ ],
308
+ "endpoint_relevance": "Copies of personal data left on laptops are often kept far longer than allowed."
309
+ },
310
+ {
311
+ "id": "Art. 5(1)(f)",
312
+ "framework": "GDPR",
313
+ "title": "Integrity and confidentiality",
314
  "summary": "Personal data must be protected against unauthorised access, loss and damage with appropriate measures.",
315
+ "auditor_looks_for": [
316
+ "Technical security measures in place"
317
+ ],
318
+ "endpoint_relevance": "The endpoint security baseline is part of these measures."
319
+ },
320
+ {
321
+ "id": "Art. 25",
322
+ "framework": "GDPR",
323
+ "title": "Data protection by design and by default",
324
  "summary": "Build data protection into systems and use privacy-friendly settings by default.",
325
+ "auditor_looks_for": [
326
+ "Privacy-protective default settings on devices and software"
327
+ ],
328
+ "endpoint_relevance": "Telemetry and AI data-collection features should be off unless needed."
329
+ },
330
+ {
331
+ "id": "Art. 28",
332
+ "framework": "GDPR",
333
+ "title": "Processor",
334
  "summary": "Use only processors that give sufficient guarantees, under a written contract with required terms.",
335
+ "auditor_looks_for": [
336
+ "A data processing agreement with each processor"
337
+ ],
338
+ "endpoint_relevance": "Cloud AI tools used with work data are processors and need an agreement."
339
+ },
340
+ {
341
+ "id": "Art. 30",
342
+ "framework": "GDPR",
343
+ "title": "Records of processing activities",
344
  "summary": "Keep a written record of the processing activities you carry out.",
345
+ "auditor_looks_for": [
346
+ "A current record of processing (RoPA)"
347
+ ],
348
+ "endpoint_relevance": "Processing done with endpoint tools, including AI tools, belongs in the record."
349
+ },
350
+ {
351
+ "id": "Art. 32(1)(a)",
352
+ "framework": "GDPR",
353
+ "title": "Security of processing: pseudonymisation and encryption",
354
  "summary": "Where appropriate, protect personal data with pseudonymisation and encryption.",
355
+ "auditor_looks_for": [
356
+ "Encrypted devices and removable media"
357
+ ],
358
+ "endpoint_relevance": "Disk encryption is the standard measure for laptops holding personal data."
359
+ },
360
+ {
361
+ "id": "Art. 32(1)(b)",
362
+ "framework": "GDPR",
363
+ "title": "Security of processing: confidentiality, integrity, availability and resilience",
364
  "summary": "Ensure the ongoing confidentiality, integrity, availability and resilience of systems that process personal data.",
365
+ "auditor_looks_for": [
366
+ "Access control, malware protection, patching and network protection on devices"
367
+ ],
368
+ "endpoint_relevance": "Most endpoint baseline checks support this requirement."
369
+ },
370
+ {
371
+ "id": "Art. 32(1)(c)",
372
+ "framework": "GDPR",
373
+ "title": "Security of processing: restore availability and access after an incident",
374
  "summary": "Be able to restore access to personal data in time after a physical or technical incident.",
375
+ "auditor_looks_for": [
376
+ "Working backups",
377
+ "Recovery keys available"
378
+ ],
379
+ "endpoint_relevance": "Backups and disk-encryption recovery keys make restoration possible."
380
+ },
381
+ {
382
+ "id": "Art. 32(1)(d)",
383
+ "framework": "GDPR",
384
+ "title": "Security of processing: regular testing and evaluation",
385
  "summary": "Regularly test, assess and evaluate whether security measures work.",
386
+ "auditor_looks_for": [
387
+ "Periodic audits such as this one",
388
+ "Evidence that findings are followed up"
389
+ ],
390
+ "endpoint_relevance": "Weekly audits and logging provide this evidence."
391
+ },
392
+ {
393
+ "id": "Art. 33",
394
+ "framework": "GDPR",
395
+ "title": "Notification of a personal data breach to the supervisory authority",
396
  "summary": "Report a personal data breach to the supervisory authority within 72 hours of becoming aware of it, unless it is unlikely to result in a risk.",
397
+ "auditor_looks_for": [
398
+ "A breach procedure",
399
+ "Logs and accurate time to establish what happened"
400
+ ],
401
+ "endpoint_relevance": "Security logs and time synchronisation make the 72-hour assessment possible."
402
+ },
403
+ {
404
+ "id": "Art. 34",
405
+ "framework": "GDPR",
406
+ "title": "Communication of a personal data breach to the data subject",
407
  "summary": "Tell affected people about a high-risk breach without undue delay; encryption can remove this duty.",
408
+ "auditor_looks_for": [
409
+ "Encryption that makes lost data unintelligible"
410
+ ],
411
+ "endpoint_relevance": "Encrypted devices and media can avoid the need to notify individuals."
412
+ },
413
+ {
414
+ "id": "Art. 35",
415
+ "framework": "GDPR",
416
+ "title": "Data protection impact assessment",
417
  "summary": "Assess the impact before processing that is likely to result in a high risk to people.",
418
+ "auditor_looks_for": [
419
+ "DPIAs for high-risk processing"
420
+ ],
421
+ "endpoint_relevance": "New tools with high-risk processing, such as AI used on employees, may need a DPIA."
422
+ },
423
+ {
424
+ "id": "Art. 44",
425
+ "framework": "GDPR",
426
+ "title": "General principle for transfers",
427
  "summary": "Transfer personal data outside the EEA only under the conditions of Chapter V.",
428
+ "auditor_looks_for": [
429
+ "A transfer basis (e.g. adequacy decision, standard contractual clauses) for non-EEA services"
430
+ ],
431
+ "endpoint_relevance": "Cloud AI tools often process data outside the EEA."
432
+ },
433
+ {
434
+ "id": "Art. 4",
435
+ "framework": "EU AI Act",
436
+ "title": "AI literacy",
437
  "summary": "Providers and deployers take measures so their staff using AI have a sufficient level of AI literacy.",
438
+ "auditor_looks_for": [
439
+ "AI training for staff who use AI tools"
440
+ ],
441
+ "endpoint_relevance": "AI tools found on endpoints show who needs AI literacy training."
442
+ },
443
+ {
444
+ "id": "Art. 5",
445
+ "framework": "EU AI Act",
446
+ "title": "Prohibited AI practices",
447
  "summary": "Certain AI uses are banned, such as emotion recognition at work and in education (with narrow exceptions) and social scoring.",
448
+ "auditor_looks_for": [
449
+ "No AI tools used for banned purposes"
450
+ ],
451
+ "endpoint_relevance": "The purpose of each detected AI tool must be checked against the banned list."
452
+ },
453
+ {
454
+ "id": "Art. 6",
455
+ "framework": "EU AI Act",
456
+ "title": "Classification rules for high-risk AI systems",
457
  "summary": "An AI system is high-risk if it is a safety component of regulated products or is used for a purpose listed in Annex III.",
458
+ "auditor_looks_for": [
459
+ "A risk classification for each AI system in use"
460
+ ],
461
+ "endpoint_relevance": "Classification depends on what the tool is used for, not only on which tool it is."
462
+ },
463
+ {
464
+ "id": "Art. 14",
465
+ "framework": "EU AI Act",
466
+ "title": "Human oversight",
467
  "summary": "High-risk AI systems must be designed so that people can oversee them effectively.",
468
+ "auditor_looks_for": [
469
+ "Named, trained people overseeing each high-risk AI system"
470
+ ],
471
+ "endpoint_relevance": "Applies only when a high-risk AI system is in use."
472
+ },
473
+ {
474
+ "id": "Art. 26",
475
+ "framework": "EU AI Act",
476
+ "title": "Obligations of deployers of high-risk AI systems",
477
  "summary": "Deployers must use high-risk AI as instructed, assign human oversight, monitor it, keep logs and inform affected people.",
478
+ "auditor_looks_for": [
479
+ "An AI register",
480
+ "Use according to instructions",
481
+ "Monitoring and log retention"
482
+ ],
483
+ "endpoint_relevance": "The AI software inventory is the starting point for these duties."
484
+ },
485
+ {
486
+ "id": "Art. 26(6)",
487
+ "framework": "EU AI Act",
488
+ "title": "Deployers: keep automatically generated logs for at least six months",
489
  "summary": "Deployers keep the logs a high-risk AI system generates, under their control, for at least six months unless other law says otherwise.",
490
+ "auditor_looks_for": [
491
+ "Log retention of at least six months for high-risk AI systems"
492
+ ],
493
+ "endpoint_relevance": "Only applies if a detected AI tool is used in a high-risk way."
494
+ },
495
+ {
496
+ "id": "Art. 50",
497
+ "framework": "EU AI Act",
498
+ "title": "Transparency obligations for providers and deployers of certain AI systems",
499
  "summary": "People must be told when they interact with an AI system, and deepfakes and certain AI-generated text must be disclosed.",
500
+ "auditor_looks_for": [
501
+ "Disclosure practices for chatbots and AI-generated content"
502
+ ],
503
+ "endpoint_relevance": "Staff publishing AI-generated content need clear rules."
504
+ },
505
+ {
506
+ "id": "Annex III",
507
+ "framework": "EU AI Act",
508
+ "title": "High-risk AI systems referred to in Article 6(2)",
509
  "summary": "Lists high-risk uses such as biometrics, critical infrastructure, education, employment and worker management, access to essential services, law enforcement, migration and justice.",
510
+ "auditor_looks_for": [
511
+ "No unassessed use of AI for employment decisions, credit scoring or similar Annex III purposes"
512
+ ],
513
+ "endpoint_relevance": "A general AI assistant becomes high-risk if used, for example, to screen job applicants."
514
+ },
515
+ {
516
+ "id": "A.5.32",
517
+ "framework": "ISO 27001:2022",
518
+ "title": "Intellectual property rights",
519
+ "summary": "Protect intellectual property rights and use only properly licensed software.",
520
+ "auditor_looks_for": [
521
+ "A software licence register",
522
+ "No pirated software, activation cracks or unlicensed copies on devices"
523
+ ],
524
+ "endpoint_relevance": "Torrent clients and activation cracks on a device point to unlicensed software and a weak software-installation control."
525
+ }
526
  ]
527
  }
library/fixes.json CHANGED
@@ -3,73 +3,244 @@
3
  "note": "Fixes Arx can apply or guide. kind 'auto': applied by collectors/<os>/fix.sh after the user clicks Fix and approves the administrator prompt; the old value is saved so it can be undone. kind 'settings': Arx opens the exact settings page and shows the steps (the change needs the user's password, a recovery key, a restart or a decision). The AI never writes or chooses commands; it may only explain these entries.",
4
  "fixes": {
5
  "firewall.enabled": {
6
- "macos": { "kind": "auto", "title": "Turn on the firewall", "changes": "Turns on the macOS firewall, which blocks unwanted incoming connections.", "note": "Apps you already allowed keep working.", "undo": true }
 
 
 
 
 
 
7
  },
8
  "firewall.inbound": {
9
- "macos": { "kind": "auto", "title": "Turn on the firewall and stealth mode", "changes": "Turns on the firewall and stealth mode, so the Mac does not answer probes from other computers on the network.", "note": "Other computers can no longer ping this Mac.", "undo": true }
 
 
 
 
 
 
10
  },
11
  "malware.service": {
12
- "macos": { "kind": "auto", "title": "Turn on Gatekeeper", "changes": "Turns on Gatekeeper, so only apps from the App Store and identified developers can open.", "note": "XProtect is always on and cannot be switched by a command.", "undo": true }
 
 
 
 
 
 
13
  },
14
  "malware.signatures": {
15
- "macos": { "kind": "auto", "title": "Update malware definitions", "changes": "Installs the latest XProtect malware definitions from Apple.", "note": "An update: there is nothing to undo.", "undo": false }
 
 
 
 
 
 
16
  },
17
  "malware.signature_updates": {
18
- "macos": { "kind": "auto", "title": "Install security responses automatically", "changes": "Turns on 'Install Security Responses and system files' in Software Update, so malware definitions stay current.", "note": "", "undo": true }
 
 
 
 
 
 
19
  },
20
  "gdpr.auto_updates": {
21
- "macos": { "kind": "auto", "title": "Turn on automatic updates", "changes": "Turns on checking for, downloading and installing macOS updates and security responses automatically.", "note": "macOS may restart overnight to finish an update; it warns first.", "undo": true }
 
 
 
 
 
 
22
  },
23
  "gdpr.guest_account": {
24
- "macos": { "kind": "auto", "title": "Turn off the guest account", "changes": "Turns off guest login and guest access to shared folders.", "note": "", "undo": true }
 
 
 
 
 
 
25
  },
26
  "gdpr.telemetry": {
27
- "macos": { "kind": "auto", "title": "Stop sharing analytics", "changes": "Turns off 'Share Mac Analytics' and 'Share with app developers'.", "note": "", "undo": true }
 
 
 
 
 
 
28
  },
29
  "gdpr.time_sync": {
30
- "macos": { "kind": "auto", "title": "Set the time automatically", "changes": "Turns on 'Set time and date automatically' from Apple's time server, so logs have correct times.", "note": "", "undo": true }
 
 
 
 
 
 
31
  },
32
  "screen_lock.enabled": {
33
- "macos": { "kind": "settings", "title": "Turn on the screen lock", "url": "x-apple.systempreferences:com.apple.Lock-Screen-Settings.extension", "steps": ["Set 'Start Screen Saver when inactive' and 'Turn display off when inactive' to 5 minutes or less.", "Set 'Require password after screen saver begins or display is turned off' to Immediately."] }
 
 
 
 
 
 
 
 
34
  },
35
  "screen_lock.timeout": {
36
- "macos": { "kind": "settings", "title": "Lock the screen sooner", "url": "x-apple.systempreferences:com.apple.Lock-Screen-Settings.extension", "steps": ["Set 'Start Screen Saver when inactive' and 'Turn display off when inactive' to 5 minutes or less.", "Set 'Require password after screen saver begins or display is turned off' to Immediately."] }
 
 
 
 
 
 
 
 
37
  },
38
  "screen_lock.password": {
39
- "macos": { "kind": "settings", "title": "Ask for the password straight away", "url": "x-apple.systempreferences:com.apple.Lock-Screen-Settings.extension", "steps": ["Set 'Require password after screen saver begins or display is turned off' to Immediately (macOS asks for your password)."] }
 
 
 
 
 
 
 
40
  },
41
  "encryption.enabled": {
42
- "macos": { "kind": "settings", "title": "Turn on FileVault", "url": "x-apple.systempreferences:com.apple.settings.PrivacySecurity.extension?FileVault", "steps": ["Scroll to FileVault and click Turn On.", "Choose how to unlock the disk if you forget your password, and keep the recovery key somewhere safe (not on this Mac): without it, data can be lost.", "Encryption continues in the background; you can keep working."] }
 
 
 
 
 
 
 
 
 
43
  },
44
  "encryption.protection": {
45
- "macos": { "kind": "settings", "title": "Finish disk encryption", "url": "x-apple.systempreferences:com.apple.settings.PrivacySecurity.extension?FileVault", "steps": ["Check that FileVault is on. If encryption is in progress, keep the Mac on power until it finishes."] }
 
 
 
 
 
 
 
46
  },
47
  "encryption.recovery": {
48
- "macos": { "kind": "settings", "title": "Set up a recovery key", "url": "x-apple.systempreferences:com.apple.settings.PrivacySecurity.extension?FileVault", "steps": ["Turn FileVault on (or off and on again) and choose 'Create a recovery key'.", "Store the key somewhere safe outside this Mac, or let your IT team escrow it."] }
 
 
 
 
 
 
 
 
49
  },
50
  "vuln.pending_updates": {
51
- "macos": { "kind": "settings", "title": "Install pending updates", "url": "x-apple.systempreferences:com.apple.Software-Update-Settings.extension", "steps": ["Click Update Now (or Restart Now). Save your work first: the Mac may restart."] }
 
 
 
 
 
 
 
52
  },
53
  "gdpr.updates_recent": {
54
- "macos": { "kind": "settings", "title": "Install the latest updates", "url": "x-apple.systempreferences:com.apple.Software-Update-Settings.extension", "steps": ["Click Update Now. Save your work first: the Mac may restart."] }
 
 
 
 
 
 
 
55
  },
56
  "gdpr.os_supported": {
57
- "macos": { "kind": "settings", "title": "Upgrade macOS", "url": "x-apple.systempreferences:com.apple.Software-Update-Settings.extension", "steps": ["Install the offered macOS upgrade. Back up first, and check that your apps support it."] }
 
 
 
 
 
 
 
58
  },
59
  "gdpr.remote_access": {
60
- "macos": { "kind": "settings", "title": "Turn off remote access you do not need", "url": "x-apple.systempreferences:com.apple.Sharing-Settings.extension", "steps": ["Turn off Screen Sharing, Remote Login, Remote Management and File Sharing unless your IT team needs them.", "Quit and uninstall remote tools such as TeamViewer or AnyDesk if they are not approved."] }
 
 
 
 
 
 
 
 
61
  },
62
  "gdpr.backup_configured": {
63
- "macos": { "kind": "settings", "title": "Set up Time Machine", "url": "x-apple.systempreferences:com.apple.Time-Machine-Settings.extension", "steps": ["Connect an external drive or choose a network backup disk, then click Add Backup Disk.", "Choose 'Encrypt backups'."] }
 
 
 
 
 
 
 
 
64
  },
65
  "gdpr.backup_recent": {
66
- "macos": { "kind": "settings", "title": "Back up now", "url": "x-apple.systempreferences:com.apple.Time-Machine-Settings.extension", "steps": ["Connect the backup disk and choose Back Up Now."] }
 
 
 
 
 
 
 
67
  },
68
  "user.account_type": {
69
- "macos": { "kind": "settings", "title": "Use a standard account for everyday work", "url": "x-apple.systempreferences:com.apple.Users-Groups-Settings.extension", "steps": ["Create a separate administrator account for installing software.", "Then turn off 'Allow this user to administer this computer' for your everyday account. Do this only after the other administrator account works."] }
 
 
 
 
 
 
 
 
70
  },
71
  "admin.unauthorized": {
72
- "macos": { "kind": "settings", "title": "Review administrator accounts", "url": "x-apple.systempreferences:com.apple.Users-Groups-Settings.extension", "steps": ["Turn off 'Allow this user to administer this computer' for accounts that are not approved IT administrators. Keep at least one working administrator."] }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  }
74
  }
75
  }
 
3
  "note": "Fixes Arx can apply or guide. kind 'auto': applied by collectors/<os>/fix.sh after the user clicks Fix and approves the administrator prompt; the old value is saved so it can be undone. kind 'settings': Arx opens the exact settings page and shows the steps (the change needs the user's password, a recovery key, a restart or a decision). The AI never writes or chooses commands; it may only explain these entries.",
4
  "fixes": {
5
  "firewall.enabled": {
6
+ "macos": {
7
+ "kind": "auto",
8
+ "title": "Turn on the firewall",
9
+ "changes": "Turns on the macOS firewall, which blocks unwanted incoming connections.",
10
+ "note": "Apps you already allowed keep working.",
11
+ "undo": true
12
+ }
13
  },
14
  "firewall.inbound": {
15
+ "macos": {
16
+ "kind": "auto",
17
+ "title": "Turn on the firewall and stealth mode",
18
+ "changes": "Turns on the firewall and stealth mode, so the Mac does not answer probes from other computers on the network.",
19
+ "note": "Other computers can no longer ping this Mac.",
20
+ "undo": true
21
+ }
22
  },
23
  "malware.service": {
24
+ "macos": {
25
+ "kind": "auto",
26
+ "title": "Turn on Gatekeeper",
27
+ "changes": "Turns on Gatekeeper, so only apps from the App Store and identified developers can open.",
28
+ "note": "XProtect is always on and cannot be switched by a command.",
29
+ "undo": true
30
+ }
31
  },
32
  "malware.signatures": {
33
+ "macos": {
34
+ "kind": "auto",
35
+ "title": "Update malware definitions",
36
+ "changes": "Installs the latest XProtect malware definitions from Apple.",
37
+ "note": "An update: there is nothing to undo.",
38
+ "undo": false
39
+ }
40
  },
41
  "malware.signature_updates": {
42
+ "macos": {
43
+ "kind": "auto",
44
+ "title": "Install security responses automatically",
45
+ "changes": "Turns on 'Install Security Responses and system files' in Software Update, so malware definitions stay current.",
46
+ "note": "",
47
+ "undo": true
48
+ }
49
  },
50
  "gdpr.auto_updates": {
51
+ "macos": {
52
+ "kind": "auto",
53
+ "title": "Turn on automatic updates",
54
+ "changes": "Turns on checking for, downloading and installing macOS updates and security responses automatically.",
55
+ "note": "macOS may restart overnight to finish an update; it warns first.",
56
+ "undo": true
57
+ }
58
  },
59
  "gdpr.guest_account": {
60
+ "macos": {
61
+ "kind": "auto",
62
+ "title": "Turn off the guest account",
63
+ "changes": "Turns off guest login and guest access to shared folders.",
64
+ "note": "",
65
+ "undo": true
66
+ }
67
  },
68
  "gdpr.telemetry": {
69
+ "macos": {
70
+ "kind": "auto",
71
+ "title": "Stop sharing analytics",
72
+ "changes": "Turns off 'Share Mac Analytics' and 'Share with app developers'.",
73
+ "note": "",
74
+ "undo": true
75
+ }
76
  },
77
  "gdpr.time_sync": {
78
+ "macos": {
79
+ "kind": "auto",
80
+ "title": "Set the time automatically",
81
+ "changes": "Turns on 'Set time and date automatically' from Apple's time server, so logs have correct times.",
82
+ "note": "",
83
+ "undo": true
84
+ }
85
  },
86
  "screen_lock.enabled": {
87
+ "macos": {
88
+ "kind": "settings",
89
+ "title": "Turn on the screen lock",
90
+ "url": "x-apple.systempreferences:com.apple.Lock-Screen-Settings.extension",
91
+ "steps": [
92
+ "Set 'Start Screen Saver when inactive' and 'Turn display off when inactive' to 5 minutes or less.",
93
+ "Set 'Require password after screen saver begins or display is turned off' to Immediately."
94
+ ]
95
+ }
96
  },
97
  "screen_lock.timeout": {
98
+ "macos": {
99
+ "kind": "settings",
100
+ "title": "Lock the screen sooner",
101
+ "url": "x-apple.systempreferences:com.apple.Lock-Screen-Settings.extension",
102
+ "steps": [
103
+ "Set 'Start Screen Saver when inactive' and 'Turn display off when inactive' to 5 minutes or less.",
104
+ "Set 'Require password after screen saver begins or display is turned off' to Immediately."
105
+ ]
106
+ }
107
  },
108
  "screen_lock.password": {
109
+ "macos": {
110
+ "kind": "settings",
111
+ "title": "Ask for the password straight away",
112
+ "url": "x-apple.systempreferences:com.apple.Lock-Screen-Settings.extension",
113
+ "steps": [
114
+ "Set 'Require password after screen saver begins or display is turned off' to Immediately (macOS asks for your password)."
115
+ ]
116
+ }
117
  },
118
  "encryption.enabled": {
119
+ "macos": {
120
+ "kind": "settings",
121
+ "title": "Turn on FileVault",
122
+ "url": "x-apple.systempreferences:com.apple.settings.PrivacySecurity.extension?FileVault",
123
+ "steps": [
124
+ "Scroll to FileVault and click Turn On.",
125
+ "Choose how to unlock the disk if you forget your password, and keep the recovery key somewhere safe (not on this Mac): without it, data can be lost.",
126
+ "Encryption continues in the background; you can keep working."
127
+ ]
128
+ }
129
  },
130
  "encryption.protection": {
131
+ "macos": {
132
+ "kind": "settings",
133
+ "title": "Finish disk encryption",
134
+ "url": "x-apple.systempreferences:com.apple.settings.PrivacySecurity.extension?FileVault",
135
+ "steps": [
136
+ "Check that FileVault is on. If encryption is in progress, keep the Mac on power until it finishes."
137
+ ]
138
+ }
139
  },
140
  "encryption.recovery": {
141
+ "macos": {
142
+ "kind": "settings",
143
+ "title": "Set up a recovery key",
144
+ "url": "x-apple.systempreferences:com.apple.settings.PrivacySecurity.extension?FileVault",
145
+ "steps": [
146
+ "Turn FileVault on (or off and on again) and choose 'Create a recovery key'.",
147
+ "Store the key somewhere safe outside this Mac, or let your IT team escrow it."
148
+ ]
149
+ }
150
  },
151
  "vuln.pending_updates": {
152
+ "macos": {
153
+ "kind": "settings",
154
+ "title": "Install pending updates",
155
+ "url": "x-apple.systempreferences:com.apple.Software-Update-Settings.extension",
156
+ "steps": [
157
+ "Click Update Now (or Restart Now). Save your work first: the Mac may restart."
158
+ ]
159
+ }
160
  },
161
  "gdpr.updates_recent": {
162
+ "macos": {
163
+ "kind": "settings",
164
+ "title": "Install the latest updates",
165
+ "url": "x-apple.systempreferences:com.apple.Software-Update-Settings.extension",
166
+ "steps": [
167
+ "Click Update Now. Save your work first: the Mac may restart."
168
+ ]
169
+ }
170
  },
171
  "gdpr.os_supported": {
172
+ "macos": {
173
+ "kind": "settings",
174
+ "title": "Upgrade macOS",
175
+ "url": "x-apple.systempreferences:com.apple.Software-Update-Settings.extension",
176
+ "steps": [
177
+ "Install the offered macOS upgrade. Back up first, and check that your apps support it."
178
+ ]
179
+ }
180
  },
181
  "gdpr.remote_access": {
182
+ "macos": {
183
+ "kind": "settings",
184
+ "title": "Turn off remote access you do not need",
185
+ "url": "x-apple.systempreferences:com.apple.Sharing-Settings.extension",
186
+ "steps": [
187
+ "Turn off Screen Sharing, Remote Login, Remote Management and File Sharing unless your IT team needs them.",
188
+ "Quit and uninstall remote tools such as TeamViewer or AnyDesk if they are not approved."
189
+ ]
190
+ }
191
  },
192
  "gdpr.backup_configured": {
193
+ "macos": {
194
+ "kind": "settings",
195
+ "title": "Set up Time Machine",
196
+ "url": "x-apple.systempreferences:com.apple.Time-Machine-Settings.extension",
197
+ "steps": [
198
+ "Connect an external drive or choose a network backup disk, then click Add Backup Disk.",
199
+ "Choose 'Encrypt backups'."
200
+ ]
201
+ }
202
  },
203
  "gdpr.backup_recent": {
204
+ "macos": {
205
+ "kind": "settings",
206
+ "title": "Back up now",
207
+ "url": "x-apple.systempreferences:com.apple.Time-Machine-Settings.extension",
208
+ "steps": [
209
+ "Connect the backup disk and choose Back Up Now."
210
+ ]
211
+ }
212
  },
213
  "user.account_type": {
214
+ "macos": {
215
+ "kind": "settings",
216
+ "title": "Use a standard account for everyday work",
217
+ "url": "x-apple.systempreferences:com.apple.Users-Groups-Settings.extension",
218
+ "steps": [
219
+ "Create a separate administrator account for installing software.",
220
+ "Then turn off 'Allow this user to administer this computer' for your everyday account. Do this only after the other administrator account works."
221
+ ]
222
+ }
223
  },
224
  "admin.unauthorized": {
225
+ "macos": {
226
+ "kind": "settings",
227
+ "title": "Review administrator accounts",
228
+ "url": "x-apple.systempreferences:com.apple.Users-Groups-Settings.extension",
229
+ "steps": [
230
+ "Turn off 'Allow this user to administer this computer' for accounts that are not approved IT administrators. Keep at least one working administrator."
231
+ ]
232
+ }
233
+ },
234
+ "account.unique_login": {
235
+ "macos": {
236
+ "kind": "settings",
237
+ "title": "Turn off automatic login and shared accounts",
238
+ "url": "x-apple.systempreferences:com.apple.Users-Groups-Settings.extension",
239
+ "steps": [
240
+ "Set 'Automatically log in as' to Off (at the bottom of the page).",
241
+ "Give each person their own account; remove or rename shared accounts such as office or admin, keeping one named IT administrator."
242
+ ]
243
+ }
244
  }
245
  }
246
  }
site/site.js CHANGED
@@ -271,6 +271,7 @@ function handedOverReport() {
271
  async function init() {
272
  initDevice(); initDownloads();
273
  try { await loadLibrary(); } catch (e) { $('checkCount').textContent = 'Could not load the check list.'; console.warn(e); return; }
 
274
  renderRail(); renderFilters(); renderTable();
275
  const showHandedOver = () => { const ev = handedOverReport(); if (ev) { history.replaceState(null, '', location.pathname); showResults(ev); } };
276
  showHandedOver();
 
271
  async function init() {
272
  initDevice(); initDownloads();
273
  try { await loadLibrary(); } catch (e) { $('checkCount').textContent = 'Could not load the check list.'; console.warn(e); return; }
274
+ document.querySelectorAll('[data-count]').forEach(el => { el.textContent = state.checks.length; });
275
  renderRail(); renderFilters(); renderTable();
276
  const showHandedOver = () => { const ev = handedOverReport(); if (ev) { history.replaceState(null, '', location.pathname); showResults(ev); } };
277
  showHandedOver();
synthetic/generate_evidence.py CHANGED
@@ -39,20 +39,20 @@ ORDER = {
39
  "firewall.private.enabled", "firewall.private.inbound", "firewall.private.outbound",
40
  "firewall.public.enabled", "firewall.public.inbound", "firewall.public.outbound",
41
  "screen_lock.enabled", "screen_lock.timeout", "screen_lock.password", "usb.device_access", "usb.read", "usb.write",
42
- "admin.approved", "admin.unauthorized", "user.account_type",
43
- "encryption.feature", "encryption.enabled", "encryption.protection", "encryption.recovery", "vuln.pending_updates", "vuln.outdated_apps", "vuln.known_vulnerabilities"] + GDPR + AIACT + ORG,
44
  "linux": PASSWORD_LOCKOUT + [
45
- "malware.antivirus", "malware.service", "malware.signature_updates", "malware.signatures", "malware.on_access",
46
  "firewall.enabled", "firewall.inbound", "firewall.outbound",
47
  "screen_lock.enabled", "screen_lock.timeout", "screen_lock.password", "usb.device_access", "usb.read", "usb.write",
48
- "admin.approved", "admin.unauthorized", "user.account_type", "encryption.enabled", "encryption.protection", "encryption.recovery",
49
- "vuln.pending_updates", "vuln.outdated_apps", "vuln.known_vulnerabilities"] + GDPR + AIACT + ORG,
50
  "macos": PASSWORD_LOCKOUT + [
51
- "malware.antivirus", "malware.service", "malware.signatures", "malware.signature_updates", "malware.on_access",
52
  "firewall.enabled", "firewall.inbound", "firewall.outbound",
53
  "screen_lock.timeout", "screen_lock.enabled", "screen_lock.password", "usb.device_access", "usb.read", "usb.write",
54
- "admin.approved", "admin.unauthorized", "user.account_type", "encryption.enabled", "encryption.protection", "encryption.recovery",
55
- "vuln.pending_updates", "vuln.outdated_apps", "vuln.known_vulnerabilities"] + GDPR + AIACT + ORG,
56
  }
57
  # Checks that report Error when the collector is not run as administrator/root.
58
  NEEDS_ADMIN = {
@@ -338,6 +338,18 @@ class Device:
338
  return ("NotApplicable", "XProtect only", "on-access scanning", "XProtect scans at launch and download; macOS has no built-in on-access scanning.")
339
 
340
  def c_malware_tamper(self):
 
 
 
 
 
 
 
 
 
 
 
 
341
  if self.third_party_av:
342
  return self._defender_na("on")
343
  ok = self.good()
@@ -567,7 +579,7 @@ class Device:
567
  if self.os != "windows":
568
  self._enc = self.good(0.05)
569
  if self.os == "windows":
570
- return self.result(self._enc, "FullyEncrypted (100%)" if self._enc else self.pick(["FullyDecrypted (0%)", "EncryptionInProgress (42%)"]), "fully encrypted")
571
  if self.os == "linux":
572
  return self.result(self._enc, "root filesystem on LUKS (dm_crypt-0)" if self._enc else "root filesystem not encrypted", "system disk encrypted")
573
  return self.result(self._enc, "FileVault on" if self._enc else "FileVault off", "FileVault on")
@@ -608,6 +620,22 @@ class Device:
608
  return ("Compliant", f"Standard ({shown})", "Standard", "")
609
  return ("Non-Compliant", f"Administrator ({shown})", "Standard", "The signed-in user is a member of the administrators group.")
610
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
611
  def c_vuln_pending_updates(self):
612
  limit = self.n("MAX_PENDING_SECURITY_UPDATES")
613
  expected = f"<= {limit} pending"
@@ -683,6 +711,19 @@ class Device:
683
  rows.append(f"{name} {WINGET_IDS[name]} {a}.{self.rng.randint(0, 9)}.{self.rng.randint(0, 999)} {a + self.pick([0, 1])}.{self.rng.randint(0, 9)}.{self.rng.randint(0, 999)} winget")
684
  return ("Non-Compliant", f"{len(rows)} outdated", expected, "; ".join(rows[:5]) + ".")
685
 
 
 
 
 
 
 
 
 
 
 
 
 
 
686
  def c_vuln_known_vulnerabilities(self):
687
  """Builds a realistic software inventory; the real matcher fills in the result (see VULN_JOBS)."""
688
  expected = f"<= {self.n('MAX_CRITICAL_HIGH_VULNERABILITIES')} critical/high"
 
39
  "firewall.private.enabled", "firewall.private.inbound", "firewall.private.outbound",
40
  "firewall.public.enabled", "firewall.public.inbound", "firewall.public.outbound",
41
  "screen_lock.enabled", "screen_lock.timeout", "screen_lock.password", "usb.device_access", "usb.read", "usb.write",
42
+ "admin.approved", "admin.unauthorized", "user.account_type", "account.unique_login",
43
+ "encryption.feature", "encryption.enabled", "encryption.protection", "encryption.recovery", "vuln.pending_updates", "vuln.outdated_apps", "software.prohibited", "vuln.known_vulnerabilities"] + GDPR + AIACT + ORG,
44
  "linux": PASSWORD_LOCKOUT + [
45
+ "malware.antivirus", "malware.service", "malware.signature_updates", "malware.signatures", "malware.on_access", "malware.tamper",
46
  "firewall.enabled", "firewall.inbound", "firewall.outbound",
47
  "screen_lock.enabled", "screen_lock.timeout", "screen_lock.password", "usb.device_access", "usb.read", "usb.write",
48
+ "admin.approved", "admin.unauthorized", "user.account_type", "account.unique_login", "encryption.enabled", "encryption.protection", "encryption.recovery",
49
+ "vuln.pending_updates", "vuln.outdated_apps", "software.prohibited", "vuln.known_vulnerabilities"] + GDPR + AIACT + ORG,
50
  "macos": PASSWORD_LOCKOUT + [
51
+ "malware.antivirus", "malware.service", "malware.signatures", "malware.signature_updates", "malware.on_access", "malware.tamper",
52
  "firewall.enabled", "firewall.inbound", "firewall.outbound",
53
  "screen_lock.timeout", "screen_lock.enabled", "screen_lock.password", "usb.device_access", "usb.read", "usb.write",
54
+ "admin.approved", "admin.unauthorized", "user.account_type", "account.unique_login", "encryption.enabled", "encryption.protection", "encryption.recovery",
55
+ "vuln.pending_updates", "vuln.outdated_apps", "software.prohibited", "vuln.known_vulnerabilities"] + GDPR + AIACT + ORG,
56
  }
57
  # Checks that report Error when the collector is not run as administrator/root.
58
  NEEDS_ADMIN = {
 
338
  return ("NotApplicable", "XProtect only", "on-access scanning", "XProtect scans at launch and download; macOS has no built-in on-access scanning.")
339
 
340
  def c_malware_tamper(self):
341
+ if self.os == "macos": # System Integrity Protection (csrutil status)
342
+ if self.good(0.2):
343
+ return ("Compliant", "System Integrity Protection on", "on", "")
344
+ state = self.pick(["disabled", "unknown (Custom Configuration)"])
345
+ return ("Non-Compliant", f"System Integrity Protection {state.split(' ')[0]}", "on", f"System Integrity Protection status: {state}.")
346
+ if self.os == "linux": # an enforcing security module; Secure Boot for information
347
+ expected = "SELinux or AppArmor enforcing"
348
+ sb = self.pick(["", "Secure Boot: SecureBoot enabled", "Secure Boot: SecureBoot disabled"])
349
+ if self.good(0.1):
350
+ lsm = "SELinux enforcing" if self.distro == "rhel" else f"AppArmor enforcing ({self.rng.randint(30, 140)} profiles)"
351
+ return ("Compliant", lsm, expected, sb)
352
+ return ("Non-Compliant", "no security module enforcing", expected, sb)
353
  if self.third_party_av:
354
  return self._defender_na("on")
355
  ok = self.good()
 
579
  if self.os != "windows":
580
  self._enc = self.good(0.05)
581
  if self.os == "windows":
582
+ return self.result(self._enc, "BitLocker: FullyEncrypted (100%)" if self._enc else self.pick(["BitLocker: FullyDecrypted (0%)", "BitLocker: EncryptionInProgress (42%)"]), "fully encrypted")
583
  if self.os == "linux":
584
  return self.result(self._enc, "root filesystem on LUKS (dm_crypt-0)" if self._enc else "root filesystem not encrypted", "system disk encrypted")
585
  return self.result(self._enc, "FileVault on" if self._enc else "FileVault off", "FileVault on")
 
620
  return ("Compliant", f"Standard ({shown})", "Standard", "")
621
  return ("Non-Compliant", f"Administrator ({shown})", "Standard", "The signed-in user is a member of the administrators group.")
622
 
623
+ def c_account_unique_login(self):
624
+ expected = "personal accounts, no automatic login"
625
+ if self.good(0.05):
626
+ return ("Compliant", expected, expected, "")
627
+ shared = [n.strip() for n in self.b("SHARED_ACCOUNT_NAMES").split(",") if n.strip()] or ["office"]
628
+ names = sorted(self.rng.sample([n for n in shared if n not in ("administrator",)] or shared, self.rng.choice([1, 1, 2])))
629
+ if self.os == "windows":
630
+ names = [n.capitalize() for n in names]
631
+ issues = []
632
+ kind = self.pick(["auto", "generic", "both"])
633
+ if kind in ("auto", "both"):
634
+ issues.append(f"automatic login as {names[0] if kind == 'both' else self._desktop_users().split(', ')[0]}")
635
+ if kind in ("generic", "both"):
636
+ issues.append(f"shared or generic accounts: {', '.join(names)}")
637
+ return ("Non-Compliant", "; ".join(issues), expected, "")
638
+
639
  def c_vuln_pending_updates(self):
640
  limit = self.n("MAX_PENDING_SECURITY_UPDATES")
641
  expected = f"<= {limit} pending"
 
711
  rows.append(f"{name} {WINGET_IDS[name]} {a}.{self.rng.randint(0, 9)}.{self.rng.randint(0, 999)} {a + self.pick([0, 1])}.{self.rng.randint(0, 9)}.{self.rng.randint(0, 999)} winget")
712
  return ("Non-Compliant", f"{len(rows)} outdated", expected, "; ".join(rows[:5]) + ".")
713
 
714
+ def c_software_prohibited(self):
715
+ listed = self.b("PROHIBITED_SOFTWARE")
716
+ if not listed:
717
+ return ("Compliant", "no list configured", "none of: (empty list)", "PROHIBITED_SOFTWARE in baseline.conf is empty.")
718
+ expected = f"none of: {listed}"
719
+ if self.good(0.12):
720
+ n = self.rng.randint(18, 140)
721
+ return ("Compliant", {"macos": f"none found in {n} applications", "windows": f"none found in {n} programs", "linux": "none found"}[self.os], expected, "")
722
+ found = {"macos": [["Transmission"], ["qBittorrent"], ["Deluge"], ["FrostWire"], ["Transmission", "qBittorrent"]],
723
+ "windows": [["µTorrent"], ["BitTorrent"], ["qBittorrent v4.6.2"], ["KMSpico 10.2.0"], ["KMSAuto Net"], ["µTorrent", "KMSpico 10.2.0"]],
724
+ "linux": [["transmission-gtk", "transmission-common"], ["qbittorrent"], ["deluge", "deluge-gtk"], ["ktorrent"]]}[self.os]
725
+ return ("Non-Compliant", ", ".join(self.pick(found)), expected, "")
726
+
727
  def c_vuln_known_vulnerabilities(self):
728
  """Builds a realistic software inventory; the real matcher fills in the result (see VULN_JOBS)."""
729
  expected = f"<= {self.n('MAX_CRITICAL_HIGH_VULNERABILITIES')} critical/high"