OpenVAPT Self-Assessment Report

lab-vulnerable (simulated) - Ubuntu 18.04.6 LTS - 2026-10-16 02:10 UTC

OpenVAPT is an academic, non-commercial project with source-available code built by AI Cybersecurity Engineers (AI systems, not people or registered engineers). This report was produced by automated, read-only checks run by the user on their own machine, for their own use, 100% at their own risk. It is not a penetration test, an audit, a certification, a service or professional advice, and it may be wrong or incomplete. The developers accept no responsibility or liability for any decision taken from it. OpenVAPT may not be sold or used to provide services. No data from this report was sent anywhere.

Executive Summary

Scope: this report covers one machine, lab-vulnerable (simulated), assessed on 2026-10-16 02:10 UTC, with root access. 310 checks ran, read-only and limited to this machine.

Result: 308 checks failed (14 Critical, 73 High, 89 Medium, 123 Low, 9 Info) and 2 passed. Critical weaknesses require immediate attention.

Coverage: 0 Incomplete, 0 Error and 0 Skipped, plus 3 targets inside other checks that could not be fully read. These areas are not shown to be free of weaknesses; see Coverage Gaps.

Vulnerability snapshot: 2021-01-01 (2114 days old, 7 advisories). Warning: older than 90 days; newer vulnerabilities are not in it. This warning is not a failure.

Limitation: this is an automated, read-only self-assessment, not a penetration test. A clean result does not prove the machine is free of weaknesses.

14Critical
73High
89Medium
123Low
2Passed
0Incomplete
3Incomplete Targets
0Skipped
0Errors
ScopeThis machine only (310 checks, sites: shop.example.test)
Run As RootYes
ToolOpenVAPT v0.1.0-dev (commit unknown) Pre-Release: dev
Vulnerability DataSnapshot 2021-01-01, 2114 days old, 7 advisories Warning: older than 90 days; newer vulnerabilities are not in it (not a failure)

Top 5 Risks

IDRiskSeverityCVSSWhy It Matters
HOST-CTR-001Docker API Exposed Over TCP Without TLSCritical10.0The Docker API is equivalent to root on the host.
HOST-K8S-001Kubelet Allows Anonymous or Unauthorised AccessCritical10.0The kubelet API can run commands in every pod on the node.
HOST-CVE-002Known Exploited Vulnerabilities PresentCritical9.8Known vulnerable package versions can expose a server to documented attacks.
HOST-SSH-003SSH Permits Empty PasswordsCritical9.8Any account without a password becomes an open door to anyone on the network.
NET-DB-002Redis Authentication and Network BindingCritical9.8An unauthenticated network-reachable Redis instance can disclose or alter data and may permit dangerous administrative operations.

Notable Coverage Gaps

Risk Heat Map

Failed checks by security control area and severity.

CategoryCriticalHighMediumLowInfo
Identity and Authentication3813122
Access Control018760
Patch and Vulnerability Management19342
Secure Configuration2519544
Cryptography and TLS071420
Logging and Monitoring001220
Network Exposure26410
Data Services48410
Web Application Security111041
Information Exposure11114170

Compliance Coverage

Coverage shows mapped automated checks and does not certify compliance.

FrameworkSafeguard or SubcategoryChecks RunFailedPassed
CIS Controls v82.2550
CIS Controls v82.5110
CIS Controls v83.351510
CIS Controls v83.1023230
CIS Controls v84.175750
CIS Controls v84.3110
CIS Controls v84.4651
CIS Controls v84.7110
CIS Controls v84.824231
CIS Controls v85.223230
CIS Controls v85.3110
CIS Controls v85.4550
CIS Controls v87.3880
CIS Controls v87.4550
CIS Controls v88.211110
CIS Controls v88.3440
CIS Controls v88.4110
CIS Controls v88.5550
CIS Controls v88.9110
CIS Controls v816.2110
CIS Controls v816.758580
NIST CSF 2.0DE.CM-09110
NIST CSF 2.0ID.RA-0118180
NIST CSF 2.0ID.RA-08110
NIST CSF 2.0PR.AA-0125250
NIST CSF 2.0PR.AA-0556560
NIST CSF 2.0PR.DS-0151510
NIST CSF 2.0PR.DS-0223230
NIST CSF 2.0PR.IR-0130282
NIST CSF 2.0PR.PS-011581571
NIST CSF 2.0PR.PS-0218180
NIST CSF 2.0PR.PS-0422220
NIST CSF 2.0PR.PS-05110

Prioritised Remediation Plan

High-severity, low-effort quick wins appear first.

  1. HOST-CTR-001 - Docker API Exposed Over TCP Without TLS CRITICAL Low Effort

    Remove tcp:// listeners and use the local Unix socket or SSH (docker context with ssh://). If remote access is unavoidable, enable tlsverify with client certificates and restrict the port in the firewall.

  2. HOST-SSH-003 - SSH Permits Empty Passwords CRITICAL Low Effort

    Set PermitEmptyPasswords no in /etc/ssh/sshd_config, reload sshd, and give every account a password or lock it (passwd -l <user>).

  3. NET-DB-002 - Redis Authentication and Network Binding CRITICAL Low Effort

    Set protected-mode yes, configure ACL users with strong secrets, bind to 127.0.0.1 and ::1, and restrict remote access with a firewall.

  4. NET-DB-003 - MongoDB Authorization and Network Binding CRITICAL Low Effort

    Set security.authorization to enabled and net.bindIp to 127.0.0.1, then allow only approved clients through a controlled network path.

  5. NET-DB-004 - PostgreSQL Trust and Broad Client Access CRITICAL Low Effort

    Bind PostgreSQL to required interfaces only and replace trust or unrestricted pg_hba.conf rules with narrow CIDRs and scram-sha-256. Caution: users whose passwords are stored as md5 cannot log in with scram-sha-256 until their password is set again with password_encryption = scram-sha-256, so reset them first and reload, not restart, to test.

  6. NET-DB-007 - Elasticsearch Security and Network Binding CRITICAL Low Effort

    Set xpack.security.enabled true, bind network.host to loopback or an approved private interface, require TLS, and filter access.

  7. WEB-NODE-002 - Node.js Debugger (Inspector) Enabled in a Service CRITICAL Low Effort

    Remove --inspect from the service and from NODE_OPTIONS, run systemctl daemon-reload and restart. Debug on a development machine, or temporarily over an SSH tunnel to 127.0.0.1:9229.

  8. WEB-PY-004 - Python Interactive Debugger Enabled in a Service CRITICAL Low Effort

    Remove the debug switches, run the application under a production WSGI server (Gunicorn, uWSGI or mod_wsgi) behind nginx or Apache, run systemctl daemon-reload and restart the service.

  9. WEB-TOM-002 - Tomcat Administrative Users With Default or Weak Passwords CRITICAL Low Effort

    Remove accounts you do not need. Give the remaining ones long random passwords and store them as digests: configure a CredentialHandler (for example SecretKeyCredentialHandler with PBKDF2) in the Realm and generate hashes with bin/digest.sh. Restart Tomcat.

  10. WEB-TOM-004 - Tomcat AJP Connector Unprotected (Ghostcat) CRITICAL Low Effort

    If you do not use AJP (most sites proxy over HTTP), delete or comment out the AJP <Connector>. Otherwise set address="127.0.0.1", a long random secret="..." with secretRequired="true", and the same secret in the proxy (mod_proxy_ajp: ProxyPass ... secret=...). Upgrade Tomcat to a supported release.

  11. HOST-CRON-001 - Cron Jobs Run Programs Other Users Can Modify HIGH Low Effort

    chmod o-w <program> and its folder; move scripts out of /tmp or user-writable folders into /usr/local/sbin owned by root; have cron run only files owned by root (chown root:root).

  12. HOST-CRON-002 - World-Writable Directory in Cron's PATH HIGH Low Effort

    Remove the writable folder from PATH in /etc/crontab (or chmod o-w it), delete relative entries, and call programs in cron jobs by absolute path.

  13. HOST-CTR-008 - Docker Socket Accessible to Non-Administrators HIGH Low Effort

    chmod 660 /var/run/docker.sock && chown root:docker /var/run/docker.sock (the daemon recreates it with these defaults). Remove users from the docker group (gpasswd -d <user> docker) and give administrators sudo docker, or move to rootless Docker.

  14. HOST-FS-001 - Sensitive Account Files Have Unsafe Permissions HIGH Low Effort

    chown root:root /etc/passwd /etc/group && chmod 644 /etc/passwd /etc/group ; chown root:shadow /etc/shadow /etc/gshadow && chmod 640 /etc/shadow /etc/gshadow (use root:root and 000 on RHEL-family systems).

  15. HOST-FS-002 - Temporary Directory Missing the Sticky Bit HIGH Low Effort

    chmod 1777 /tmp /var/tmp

  16. HOST-FS-005 - Cron Files Writable by Non-Root Users HIGH Low Effort

    chown root:root <path> && chmod go-w <path> for each listed path (600 for /etc/crontab is a common hardening choice).

  17. HOST-FS-007 - Private TLS Keys Readable by Others HIGH Low Effort

    chown root:root <key> && chmod 600 <key> (or 640 with a dedicated group the web server runs in). Rotate any key that was exposed.

  18. HOST-FS-022 - Account Database Files or Their Backups Not Owned and Locked by Root HIGH Low Effort

    chown root:root /etc/passwd /etc/passwd- /etc/group /etc/group- && chmod 644 /etc/passwd /etc/group && chmod 600 /etc/passwd- /etc/group- ; chown root:shadow /etc/shadow /etc/shadow- /etc/gshadow /etc/gshadow- && chmod 640 /etc/shadow /etc/gshadow && chmod 600 /etc/shadow- /etc/gshadow- (use root:root and mode 000 on RHEL family systems).

  19. HOST-K8S-002 - Kubernetes Data Directory Accessible to Others HIGH Low Effort

    chmod 700 /var/lib/etcd && chown etcd:etcd /var/lib/etcd (or root:root for kubeadm static pods). Enable encryption at rest for Secrets.

  20. HOST-K8S-003 - Kubernetes Credential Files Readable by Others HIGH Low Effort

    chmod 600 /etc/kubernetes/*.conf /etc/kubernetes/pki/*.key /etc/kubernetes/pki/etcd/*.key && chown root:root on each.

  21. HOST-PKG-002 - Repository Signature Checks Disabled HIGH Low Effort

    Remove trusted=yes (or Trusted: yes) from the listed source, install the repository's signing key under /etc/apt/keyrings and reference it with signed-by=; remove AllowUnauthenticated and AllowInsecureRepositories settings. On dnf and yum set gpgcheck=1 (and repo_gpgcheck=1 where supported) in each listed repository and import its key with rpm --import.

  22. HOST-SSH-001 - SSH Allows Direct Root Login HIGH Low Effort

    In /etc/ssh/sshd_config set: PermitRootLogin no (or prohibit-password if key-based root login is truly required). Log in as a named user and use sudo. Then run: sshd -t && systemctl reload sshd

  23. HOST-SSH-009 - SSH Host Private Keys Readable by Others HIGH Low Effort

    chown root:root /etc/ssh/ssh_host_*_key && chmod 600 /etc/ssh/ssh_host_*_key (0640 with group ssh_keys is acceptable on RHEL family).

  24. HOST-SSH-010 - SSH Server Configuration Writable by Non-Root Users HIGH Low Effort

    chown root:root /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf && chmod 600 /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf

  25. HOST-SYSD-003 - Service Unit Files Writable by Non-Root Users HIGH Low Effort

    chown root:root <file> && chmod 644 <file> for each listed file, then review its contents for changes you did not make (ExecStart=, User=, ExecStartPre=) and run systemctl daemon-reload.

  26. HOST-SYSD-004 - Service Programs in Writable Locations HIGH Low Effort

    Install the program in a root-owned location (/usr/local/bin or /opt/<app>), chown root:root and chmod 755 it, point ExecStart= at it, then systemctl daemon-reload and restart the service.

  27. HOST-USR-002 - Accounts Without a Password HIGH Low Effort

    For each listed user either set a password (passwd <user>) or lock the account (passwd -l <user>).

  28. HOST-USR-003 - Sudo Rules Without Password (NOPASSWD) HIGH Low Effort

    Edit with visudo and remove NOPASSWD, or restrict it to one specific, harmless command for automation accounts.

  29. HOST-USR-007 - Insecure Trust Files in Home Directories HIGH Low Effort

    Delete .rhosts and .shosts files. Replace .netrc credentials with a secret manager or key-based authentication, then delete the file and rotate the passwords it contained.

  30. NET-AI-001 - AI Model Server or Dashboard Reachable From the Network HIGH Low Effort

    Bind each service to 127.0.0.1 (Ollama: OLLAMA_HOST=127.0.0.1:11434 in its service environment; Ray: --dashboard-host=127.0.0.1; Gradio: server_name="127.0.0.1"), and if others need it, publish it only through a reverse proxy with authentication and TLS.

  31. NET-AI-002 - Jupyter Configuration Weakens Authentication HIGH Low Effort

    Remove the empty token line so Jupyter generates a random token, or set a password with jupyter server password . Remove disable_check_xsrf = True. Bind to 127.0.0.1 and reach it through an SSH tunnel.

  32. NET-APP-001 - Debugger or Application Control Ports Exposed HIGH Low Effort

    Bind each to 127.0.0.1 or a Unix socket (node --inspect=127.0.0.1:9229; Tomcat Connector address="127.0.0.1" or remove the AJP connector; PHP-FPM listen = /run/php/php-fpm.sock; jupyter --ip=127.0.0.1) and never expose a debugger.

  33. NET-DB-001 - Database or Cache Service Exposed to the Network HIGH Low Effort

    Bind the service to 127.0.0.1 (MySQL: bind-address = 127.0.0.1; Redis: bind 127.0.0.1 ::1 and protected-mode yes; MongoDB: net.bindIp: 127.0.0.1) and restart it. Caution: confirm first that no application on another machine connects to it, or that application loses its database. If remote access is needed, allow only specific source IPs in the firewall and require TLS and authentication.

  34. NET-DB-005 - MySQL or MariaDB Unsafe Network Options HIGH Low Effort

    Disable local_infile and skip-grant-tables. Bind to 127.0.0.1 or enable skip-networking when TCP access is unnecessary.

  35. NET-DB-006 - Memcached UDP or Broad Listen Address HIGH Low Effort

    Set UDP_PORT=0 or -U 0 and bind with -l 127.0.0.1. Use a firewall for any explicitly required clients.

  36. NET-DB-008 - Unsafe NFS Export Options HIGH Low Effort

    Restrict every export to explicit client CIDRs, use root_squash, remove insecure, and reload exports.

  37. NET-DB-009 - Unsafe Samba Guest or SMB1 Configuration HIGH Low Effort

    Set guest ok = no, map to guest = Never, and server min protocol = SMB2_02 or newer. Review each share ACL.

  38. NET-DB-010 - BIND Open Recursion HIGH Low Effort

    Disable recursion on authoritative-only servers, or set allow-recursion and allow-query-cache to explicit trusted networks.

  39. NET-DB-011 - BIND Zone Transfers Allowed to Any HIGH Low Effort

    Set allow-transfer to none or explicit secondary server addresses, preferably protected with TSIG.

  40. NET-DB-012 - Postfix Open Relay Controls HIGH Low Effort

    Set smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination and narrow mynetworks.

  41. NET-FW-003 - Firewall Allows Sensitive Services From Anywhere HIGH Low Effort

    Delete the rule or restrict it to the addresses that need it, for example: ufw delete allow 3306 && ufw allow from 203.0.113.10 to any port 3306 proto tcp . Better, bind the service to 127.0.0.1 and reach it through an SSH tunnel or VPN.

  42. NET-SVC-003 - Network Time Service Amplification Risk HIGH Low Effort

    Bind the time daemon to required interfaces, restrict clients to explicit networks, disable monitoring, and use noquery or equivalent controls.

  43. WEB-APA-005 - Apache Allows TLS 1.0 or 1.1 HIGH Low Effort

    Set SSLProtocol -all +TLSv1.2 +TLSv1.3 (Mozilla intermediate) in mods-enabled/ssl.conf or ssl.conf, then apachectl configtest and reload.

  44. WEB-APA-006 - Apache Cipher Suite Includes Weak Suites HIGH Low Effort

    Use the Mozilla intermediate list for SSLCipherSuite and set SSLHonorCipherOrder off , as the Mozilla SSL Configuration Generator produces for Apache.

  45. WEB-APP-001 - Laravel Debug Mode On or Application Key Missing HIGH Low Effort

    Set APP_DEBUG=false and APP_ENV=production in .env, run php artisan key:generate if APP_KEY is empty, then php artisan config:cache. Keep .env outside the web root (Laravel's public/ folder) and readable only by the application user.

  46. WEB-APP-003 - Symfony Running in the Development Environment HIGH Low Effort

    Set APP_ENV=prod and APP_DEBUG=0 in .env (or .env.local), run composer dump-env prod, clear the cache (php bin/console cache:clear) and remove the web profiler bundle from production.

  47. WEB-APP-004 - Rails Master Key or Secrets File Exposed HIGH Low Effort

    chmod 600 config/master.key config/credentials/*.key; keep them out of git (.gitignore) and out of public/; load the key from RAILS_MASTER_KEY in the environment on servers. Rotate the credentials if the key was ever exposed.

  48. WEB-APP-006 - Spring Boot Actuator Endpoints Fully Exposed HIGH Low Effort

    Set management.endpoints.web.exposure.include=health,info (and exclude env,heapdump,configprops), move management.server.port to a port that is not published, and require authentication for every actuator endpoint with Spring Security.

  49. WEB-CMS-004 - CMS Configuration Readable by All Users HIGH Low Effort

    chmod 640 <file> and chown it to the site owner with the web server's group (for example chown deploy:www-data wp-config.php); on PHP-FPM pools that run as the site user, 600 or 400 also works. Rotate the database password if other people have shell access.

  50. WEB-CMS-005 - CMS Configuration Writable by Other Users HIGH Low Effort

    chmod 640 (or 440) <file>. Drupal also expects sites/default to be 555 after installation. Review the file for code you did not add.

  51. WEB-CMS-019 - Drupal update.php Open Without Authentication HIGH Low Effort

    Set $settings['update_free_access'] = FALSE; in settings.php (the default) and run updates as user 1 or with drush updatedb.

  52. WEB-DOC-001 - Secrets or Backups Stored Inside a Web Root HIGH Low Effort

    Move each listed file outside the document root (for example to a 700 folder in the account's home), delete what is not needed, and rotate any secret or key that was exposed. Keep backups in a dedicated location outside every web root.

  53. WEB-DOC-002 - Web Root Files Writable by Other Users HIGH Low Effort

    chmod o-w <file> for each listed file (find <docroot> -type f -perm -0002 -exec chmod o-w {} +). Use 644 for files and 755 for folders, owned by the site account, and grant the web server write access only to upload folders.

  54. WEB-EXP-001 - Git Repository Exposed on the Website HIGH Low Effort

    Block dot-folders in the web server (Apache: RedirectMatch 404 /\.git ; nginx: location ~ /\.(?!well-known) { deny all; }) and deploy without the .git folder in the web root. Rotate any secret that was ever committed.

  55. WEB-EXP-004 - Backup or Database Dump Files Downloadable HIGH Low Effort

    Move backups outside the web root (for example /home/<user>/deploy-backups/ with mode 700), delete the exposed copies and treat their contents as leaked.

  56. WEB-EXP-007 - Other Version Control Metadata Exposed HIGH Low Effort

    Block dot-folders at the web server and deploy without version control metadata in the web root. Rotate any secret ever committed.

  57. WEB-EXP-008 - Log Files Downloadable From the Website HIGH Low Effort

    Move logs outside the web root, deny access to *.log at the web server, disable WP_DEBUG_LOG in production, and review the exposed logs for leaked secrets.

  58. WEB-EXP-012 - Framework Debug Pages Exposed HIGH Low Effort

    Disable debug mode in production (APP_DEBUG=false, DEBUG = False, APP_ENV=prod), remove profiler routes, and show generic error pages.

  59. WEB-NGX-003 - nginx Allows TLS 1.0 or 1.1 HIGH Low Effort

    Set ssl_protocols TLSv1.2 TLSv1.3; in the http block (the Mozilla intermediate profile), run nginx -t and reload.

  60. WEB-NGX-004 - nginx Cipher List Includes Weak Suites HIGH Low Effort

    Use the Mozilla intermediate list, for example ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305; and ssl_prefer_server_ciphers off;

  61. WEB-PHP-003 - PHP Allows Remote File Inclusion HIGH Low Effort

    In php.ini set allow_url_include = Off (the default since PHP 5.2) and restart PHP.

  62. WEB-PY-001 - Django Debug Mode Enabled HIGH Low Effort

    Set DEBUG = False in production, preferably from the environment (DEBUG = os.environ.get('DJANGO_DEBUG') == '1'), set ALLOWED_HOSTS, and restart the application. Run python manage.py check --deploy.

  63. WEB-PY-003 - Django Uses the Generated Development Secret Key HIGH Low Effort

    Generate a new key (python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'), load it from the environment or a root-readable file (SECRET_KEY = os.environ['DJANGO_SECRET_KEY']), and restart. Changing the key logs all users out.

  64. WEB-TOM-001 - Tomcat Manager Reachable Without Address Restriction HIGH Low Effort

    If you do not use them, delete the manager and host-manager folders (or apt remove tomcatN-admin). Otherwise keep the default valve in META-INF/context.xml: <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" /> and reach the Manager through an SSH tunnel.

  65. HOST-CVE-002 - Known Exploited Vulnerabilities Present CRITICAL Medium Effort

    Install the vendor security update. For a source build, run 'make vulndb' to embed a snapshot generated from OSV and CISA KEV, then rebuild.

  66. HOST-K8S-001 - Kubelet Allows Anonymous or Unauthorised Access CRITICAL Medium Effort

    Set authentication.anonymous.enabled: false, authorization.mode: Webhook and readOnlyPort: 0 in the kubelet configuration, then restart the kubelet.

  67. NET-SVC-002 - Control Plane or Remote Desktop Ports Network-Reachable CRITICAL Medium Effort

    Bind control planes to loopback or a dedicated management address, require mutual TLS or strong authentication, and filter access to approved source networks or a VPN.

  68. WEB-EXP-002 - Environment or Secrets File Exposed CRITICAL Medium Effort

    Move secrets out of the web root, block dot-files at the web server, delete backup copies, then rotate every secret in the file because it must be treated as leaked.

  69. HOST-CTR-003 - Privileged or Host-Namespace Containers HIGH Medium Effort

    Recreate each container without --privileged, --pid=host, --net=host and --ipc=host; drop all capabilities and add back only the specific ones needed (--cap-drop=ALL --cap-add=...).

  70. HOST-CTR-004 - Containers Mount the Docker Socket or Host Root HIGH Medium Effort

    Remove these mounts. If a tool genuinely needs the Docker API, use a restricted socket proxy that allows only the required read-only calls.

  71. HOST-CTR-011 - Seccomp or AppArmor Disabled for Containers HIGH Medium Effort

    Remove --security-opt seccomp=unconfined and apparmor=unconfined from the container definitions and recreate them; if an application needs one extra system call, write a custom seccomp profile that adds only that call. Delete seccomp-profile from daemon.json.

  72. HOST-CTR-014 - containerd Remote API or Podman Unconfined Defaults HIGH Medium Effort

    containerd: remove tcp_address or set tcp_tls_cert and tcp_tls_key, then restart containerd. Podman: delete seccomp_profile = "unconfined", set label = true and apparmor_profile = "container-default" in containers.conf.

  73. HOST-CVE-001 - Installed OS Packages With Known Vulnerabilities HIGH Medium Effort

    Install the vendor security update. For a source build, run 'make vulndb' to embed a snapshot generated from OSV and CISA KEV, then rebuild.

  74. HOST-DKR-001 - Users With Root-Equivalent Docker Access HIGH Medium Effort

    Remove users who do not need it from the docker group (gpasswd -d <user> docker); consider rootless Docker or Podman; keep docker.sock at 660 root:docker.

  75. HOST-FS-003 - World-Writable Files in System Configuration HIGH Medium Effort

    For each listed file or directory: chmod o-w <path>. Then find out how it became writable (a deployment script or a careless chmod 777).

  76. HOST-FS-004 - Unexpected SUID or SGID Programs HIGH Medium Effort

    Confirm whether each program is needed. Remove the bit with chmod u-s,g-s <file>, or delete the file if you did not put it there and investigate how it arrived.

  77. HOST-PKG-001 - Security Updates Waiting to Be Installed HIGH Medium Effort

    Debian/Ubuntu: apt-get update && apt-get upgrade . RHEL family: dnf upgrade --security . Consider unattended-upgrades or dnf-automatic for security patches.

  78. HOST-SEC-001 - Secrets in World-Readable Files HIGH Medium Effort

    chmod o-r each listed file (640 with the service's group, or 600). Move secrets into root-only files, systemd credentials or a secrets manager, and rotate every key or password that was readable.

  79. HOST-USR-001 - Extra Accounts With Root Privileges (UID 0) HIGH Medium Effort

    Investigate who created each account. Remove it (userdel <name>) or give it a normal UID (usermod -u <new-uid> <name>). Grant admin rights through sudo instead.

  80. NET-FW-002 - IPv6 Listeners Without IPv6 Firewall HIGH Medium Effort

    Apply equivalent default-deny filtering for IPv6 with nftables or ip6tables and explicitly allow required services. Caution: allow SSH and ICMPv6 neighbour discovery and router messages before applying the default deny, or remote IPv6 sessions and IPv6 connectivity are cut.

  81. NET-SVC-001 - Cleartext Legacy Services Listening HIGH Medium Effort

    Replace with encrypted equivalents: SSH/SFTP instead of Telnet/FTP/rsh, IMAPS (993)/POP3S (995), LDAPS (636), SNMPv3. Disable the old service: systemctl disable --now <unit>.

  82. WEB-CVE-001 - Vulnerable Web Application Libraries HIGH Medium Effort

    Update the affected library or WordPress core and deploy a refreshed lockfile or asset. For a source build, run 'make vulndb' to embed a generated snapshot.

  83. HOST-OS-001 - Operating System Past End of Security Support HIGH High Effort

    Plan an upgrade to a supported release (for example do-release-upgrade on Ubuntu, or a fresh install and migration). Paid extended support (Ubuntu Pro, RHEL ELS) is an alternative while migrating.

  84. WEB-CMS-012 - Drupal Core Past End of Life HIGH High Effort

    Upgrade to a supported Drupal major with composer (drupal/core-recommended), run drush updatedb and test the site; for Drupal 7, migrate with the Migrate module or commission a rebuild.

  85. WEB-CMS-014 - Joomla Core Past End of Life HIGH High Effort

    Update to the current Joomla series through the Joomla Update component (back up first, check extension compatibility, then update), and keep the one-click updater enabled.

  86. WEB-NODE-001 - Node.js Version Past End of Life HIGH High Effort

    Move to an Active or Maintenance LTS release (even-numbered majors), for example with the NodeSource or distribution packages, test the application, then restart its service.

  87. WEB-PHP-004 - PHP Version Past End of Security Support HIGH High Effort

    Upgrade to a supported PHP branch (see php.net/supported-versions) and test the applications, or confirm your distribution still backports security fixes to this version.

  88. HOST-BOOT-003 - Uncommon Filesystem Modules Not Disabled MEDIUM Low Effort

    Create /etc/modprobe.d/openvapt-filesystems.conf with, for each module: install <module> /bin/false and blacklist <module> then unload any loaded one with modprobe -r <module>. Caution: first confirm that no listed module is in use (lsmod, findmnt); blocking a filesystem a mount or package format needs (for example squashfs for snap packages, or vfat for the EFI system partition) breaks those mounts at the next boot.

  89. HOST-BOOT-004 - USB Storage Driver Not Disabled MEDIUM Low Effort

    Create /etc/modprobe.d/openvapt-usb.conf containing install usb-storage /bin/false and blacklist usb-storage then modprobe -r usb-storage. Servers that need USB backups should record the exception instead.

  90. HOST-CTR-010 - Docker Daemon Allows Insecure Registries or Debug Features MEDIUM Low Effort

    Remove insecure-registries (serve the registry over TLS with a trusted certificate, or add its CA to /etc/docker/certs.d/<registry>/ca.crt), set "debug": false and "experimental": false in daemon.json, and remove any --insecure-registry, --debug (-D) or --experimental flag from the dockerd ExecStart in docker.service drop-ins (then systemctl daemon-reload). Restart Docker in a maintenance window: running containers stop unless live-restore is on.

  91. HOST-FS-006 - Boot Loader Configuration Exposed MEDIUM Low Effort

    chown root:root <grub.cfg> && chmod 600 <grub.cfg> (for example /boot/grub/grub.cfg or /boot/grub2/grub.cfg).

  92. HOST-FS-014 - World-Writable Files Outside Temporary Directories MEDIUM Low Effort

    For each listed file: chmod o-w <path>. Then find the deployment step or chmod 777 habit that created it.

  93. HOST-FS-017 - World-Writable Directories Without the Sticky Bit MEDIUM Low Effort

    chmod +t <dir> for directories that must stay shared, or chmod o-w <dir> for those that should not be writable by everyone.

  94. HOST-KRN-001 - Address Space Layout Randomisation Not Fully Enabled MEDIUM Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.randomize_va_space = 2 then apply with: sysctl --system

  95. HOST-KRN-009 - Unprivileged eBPF Allowed MEDIUM Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.unprivileged_bpf_disabled = 1 then apply with: sysctl --system

  96. HOST-PAM-008 - Root PATH Contains Unsafe Entries MEDIUM Low Effort

    Edit the listed file so PATH holds only absolute, root-owned directories, for example PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" , remove any . or trailing colon, and chmod o-w any listed directory. Log out and in again.

  97. HOST-PWD-001 - Weak Password Hashing Algorithm Configured MEDIUM Low Effort

    Set ENCRYPT_METHOD YESCRYPT (or SHA512 on older systems) in /etc/login.defs, and make sure pam_unix uses the same algorithm. Ask users to change passwords so existing hashes are upgraded.

  98. HOST-PWD-002 - Accounts With Obsolete Password Hashes MEDIUM Low Effort

    Configure a modern algorithm (HOST-PWD-001), then force a password change for each listed account (chage -d 0 <user>) or lock unused accounts (passwd -l <user>).

  99. HOST-SSH-002 - SSH Password Authentication Enabled MEDIUM Low Effort

    Install your public key for each admin user (ssh-copy-id), confirm key login works in a second session, then set PasswordAuthentication no and KbdInteractiveAuthentication no in /etc/ssh/sshd_config and reload sshd.

  100. HOST-SSH-004 - SSH Offers Weak Cryptography MEDIUM Low Effort

    Remove the listed algorithms. On OpenSSH 8.x and later the defaults are already strong: delete any custom Ciphers/MACs/KexAlgorithms lines, or set explicit modern lists such as Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com then reload sshd.

  101. HOST-SSH-007 - SSH Forwarding Features Enabled MEDIUM Low Effort

    Set AllowTcpForwarding no, AllowAgentForwarding no, PermitTunnel no and GatewayPorts no globally or in every applicable Match block, then reload sshd.

  102. HOST-SSH-011 - SSH Legacy Trust Options Enabled MEDIUM Low Effort

    Set HostbasedAuthentication no , IgnoreRhosts yes and PermitUserEnvironment no in /etc/ssh/sshd_config, then reload sshd.

  103. HOST-SVC-002 - Telnet Server Installed or Enabled MEDIUM Low Effort

    apt purge telnetd inetutils-telnetd or dnf remove telnet-server , and systemctl disable --now telnet.socket . Use SSH. Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.

  104. HOST-SVC-003 - rsh, rlogin, rexec or finger Server Installed or Enabled MEDIUM Low Effort

    apt purge rsh-server rsh-redone-server fingerd or dnf remove rsh-server finger-server , and systemctl disable --now rsh.socket rlogin.socket rexec.socket finger.socket . Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.

  105. HOST-SVC-004 - TFTP Server Installed or Enabled MEDIUM Low Effort

    apt purge tftpd-hpa atftpd or dnf remove tftp-server , and systemctl disable --now tftpd-hpa.service tftp.socket . Where PXE is required, serve only that directory, read-only, from a dedicated host. Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.

  106. HOST-SVC-005 - FTP Server Installed or Enabled MEDIUM Low Effort

    Move users to SFTP (the OpenSSH internal-sftp subsystem), then apt purge vsftpd proftpd-core pure-ftpd or dnf remove vsftpd proftpd and systemctl disable --now vsftpd . If FTP must stay, enforce TLS (FTPS) and restrict it to named users. Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.

  107. HOST-SVC-006 - NIS Server or Client Installed or Enabled MEDIUM Low Effort

    Replace NIS with a modern directory (SSSD with LDAPS or FreeIPA), then apt purge nis or dnf remove ypserv ypbind and systemctl disable --now ypserv ypbind . Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.

  108. HOST-SYSD-005 - Secrets Written Into Service Unit Files MEDIUM Low Effort

    Move secrets to a root-owned file readable only by root (chmod 600) and load it with EnvironmentFile=, or better use LoadCredential=/SetCredentialEncrypted= so the secret is only visible to the service. Then rotate every secret that was exposed.

  109. HOST-USR-006 - Legacy NIS Entries in Account Files MEDIUM Low Effort

    Remove the '+' lines (with vipw / vigr) and use a modern directory service such as SSSD with LDAPS if central accounts are needed.

  110. HOST-USR-009 - Password and Shadow Files Out of Step MEDIUM Low Effort

    pwconv moves hashes into /etc/shadow and creates missing entries; userdel or vipw/vigr removes orphan lines; run pwck and grpck to confirm the files are consistent.

  111. NET-APP-002 - Application Server Ports Reachable Without a Reverse Proxy MEDIUM Low Effort

    Bind the application to 127.0.0.1 (Node.js: app.listen(3000, '127.0.0.1'); Gunicorn: --bind 127.0.0.1:8000; Tomcat: address="127.0.0.1" on the Connector) and publish it only through nginx or Apache.

  112. NET-DB-013 - Mail Cleartext Authentication Allowed MEDIUM Low Effort

    Set smtpd_tls_auth_only = yes and disable_plaintext_auth = yes. Use implicit TLS on ports 465, 993, and 995. STARTTLS assessment is out of scope.

  113. NET-DB-014 - MySQL Symbolic Links Allowed for Tables MEDIUM Low Effort

    Add symbolic-links=0 (or skip-symbolic-links ) under [mysqld] and restart the service in a maintenance window.

  114. NET-DB-015 - MySQL secure_file_priv Not Restricted MEDIUM Low Effort

    Add secure_file_priv = NULL (no file operations) or secure_file_priv = /var/lib/mysql-files under [mysqld] and restart in a maintenance window.

  115. NET-DB-016 - MySQL Does Not Require Encrypted Client Connections MEDIUM Low Effort

    Provision a server certificate (MySQL creates one by default), then add require_secure_transport = ON under [mysqld] and restart in a maintenance window. Test every application connection string first.

  116. NET-DB-019 - PostgreSQL Uses md5 or password Authentication MEDIUM Low Effort

    Set password_encryption = scram-sha-256 in postgresql.conf, have every role reset its password so a SCRAM verifier is stored, then change the pg_hba.conf methods to scram-sha-256 and reload.

  117. NET-DB-020 - PostgreSQL SSL Not Enabled MEDIUM Low Effort

    Install a certificate and key readable only by the postgres user, set ssl = on , ssl_cert_file and ssl_key_file, reload, then change remote pg_hba.conf rules from host to hostssl.

  118. NET-DB-022 - PostgreSQL Password Encryption Not SCRAM MEDIUM Low Effort

    Set password_encryption = scram-sha-256 , reload, and ask every role to reset its password so the verifier is regenerated. Then move pg_hba.conf to scram-sha-256 (NET-DB-019).

  119. NET-DB-023 - Redis Dangerous Commands Not Restricted MEDIUM Low Effort

    Prefer ACLs on Redis 6 and newer: user app on >secret ~app:* -@all +@read +@write -@dangerous . Otherwise add rename-command FLUSHALL "" (and the same for FLUSHDB, CONFIG, DEBUG, KEYS) and restart.

  120. NET-DNS-002 - BIND DNSSEC Validation Disabled MEDIUM Low Effort

    Set dnssec-validation auto; in options (remove any no ), run named-checkconf and rndc reconfig. Authoritative-only servers with recursion off may leave it unset.

  121. NET-MAIL-001 - Postfix SMTP TLS Not Offered or Has No Certificate MEDIUM Low Effort

    Set smtpd_tls_security_level = may , smtpd_tls_chain_files = /etc/letsencrypt/live/<host>/privkey.pem, /etc/letsencrypt/live/<host>/fullchain.pem (or smtpd_tls_cert_file and smtpd_tls_key_file), then postfix reload.

  122. NET-MAIL-002 - Postfix Allows TLS 1.0 or 1.1 MEDIUM Low Effort

    Add smtpd_tls_protocols = >=TLSv1.2 and smtpd_tls_mandatory_protocols = >=TLSv1.2 (Postfix 3.6 and newer; on older releases use !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 ), then postfix reload.

  123. NET-MAIL-004 - Dovecot Does Not Require TLS MEDIUM Low Effort

    Set ssl = required and ssl_min_protocol = TLSv1.2 in conf.d/10-ssl.conf, then doveadm reload. Prefer implicit TLS ports 993 and 995 for clients. Caution: clients set to plaintext stop connecting, so confirm every mail client uses TLS first.

  124. NET-SVC-004 - Management Panel or Monitoring Ports Network-Reachable MEDIUM Low Effort

    Bind the panel or exporter to 127.0.0.1 or a management address, put it behind a reverse proxy with authentication, or restrict the port to monitoring hosts in the firewall.

  125. NET-TLS-001 - Deprecated TLS 1.0 or 1.1 Accepted MEDIUM Low Effort

    Apache: SSLProtocol -all +TLSv1.2 +TLSv1.3 . nginx: ssl_protocols TLSv1.2 TLSv1.3; . Postfix/Dovecot: set the minimum protocol to TLSv1.2. Reload the service afterwards.

  126. NET-TLS-002 - TLS Certificate Expired or Expiring Soon MEDIUM Low Effort

    Renew the certificate (certbot renew, or your provider's process) and make sure renewal is automated (systemctl list-timers | grep certbot).

  127. NET-TLS-003 - Self-Signed or Mismatched TLS Certificate MEDIUM Low Effort

    Issue a certificate from a public CA covering every site name, for example with certbot --apache or certbot --nginx -d example.com -d www.example.com.

  128. NET-TLS-004 - Weak TLS 1.2 Cipher Suites Accepted MEDIUM Low Effort

    Allow only modern AEAD suites for TLS 1.2 and prefer TLS 1.3. Remove RC4, 3DES, NULL, EXPORT, anonymous, and CBC with SHA-1 suites. Caution: very old clients and devices that support only those suites stop connecting; check the access logs for them first.

  129. WEB-APA-003 - Apache Directory Indexes Enabled in Configuration MEDIUM Low Effort

    Change the block to Options -Indexes +FollowSymLinks (or remove Indexes). Where a listing is wanted, protect that Directory with Require.

  130. WEB-APA-011 - Apache Has No Slow Request Protection MEDIUM Low Effort

    Enable the module (Debian and Ubuntu: a2enmod reqtimeout; other systems: LoadModule reqtimeout_module modules/mod_reqtimeout.so) and keep or set RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500 , then reload.

  131. WEB-APP-002 - Application .env File Readable by All Users MEDIUM Low Effort

    chmod 640 .env && chown <app-user>:<web-group> .env (or 600 when the application runs as its own user). Rotate the secrets if other people have had shell access.

  132. WEB-APP-005 - Rails Production Does Not Force HTTPS MEDIUM Low Effort

    Set config.force_ssl = true in config/environments/production.rb (and config.assume_ssl = true behind a TLS-terminating proxy), then restart the application.

  133. WEB-APP-009 - Git Repository Stored Inside a Web Root MEDIUM Low Effort

    Deploy from a build step that copies only the needed files (git archive, rsync --exclude .git, or a CI artefact), or point the document root at a public/ sub-folder as Laravel, Symfony and Rails expect. Remove the .git folder from the web root and rotate any secret ever committed.

  134. WEB-APP-010 - Framework Writable Folders Open to All Users MEDIUM Low Effort

    chmod -R o-w storage bootstrap/cache var and give the web server group write access instead: chgrp -R www-data storage bootstrap/cache && chmod -R g+w storage bootstrap/cache.

  135. WEB-CMS-006 - WordPress Shows Debug Output to Visitors MEDIUM Low Effort

    In production set define('WP_DEBUG', false);. If you need logs, use define('WP_DEBUG_LOG', '/path/outside/webroot/wp-debug.log'); together with define('WP_DEBUG_DISPLAY', false);.

  136. WEB-CMS-008 - WordPress Automatic Updates Disabled MEDIUM Low Effort

    Remove those lines, or set define('WP_AUTO_UPDATE_CORE', 'minor'); so at least security releases install automatically. Keep backups and enable plugin auto-updates where practical.

  137. WEB-CMS-009 - Joomla Debug or Verbose Error Reporting Enabled MEDIUM Low Effort

    In System, Global Configuration set Debug System to No and Error Reporting to None (or System Default), or set public $debug = false; and public $error_reporting = 'none'; in configuration.php.

  138. WEB-CMS-013 - Drupal Trusted Host Patterns Not Set MEDIUM Low Effort

    Add to settings.php: $settings['trusted_host_patterns'] = ['^www\.example\.com$', '^example\.com$']; then clear caches (drush cr). The status report page should no longer warn about trusted hosts.

  139. WEB-CMS-015 - Magento Not in Production Mode MEDIUM Low Effort

    bin/magento deploy:mode:set production (which also deploys static content and compiles DI), then clear caches. Keep developer mode for staging only.

  140. WEB-CMS-016 - Ghost Configured With a Plain HTTP Site URL MEDIUM Low Effort

    ghost config url https://<your-domain> (or edit config.production.json), set up TLS with ghost setup ssl or your reverse proxy, then ghost restart.

  141. WEB-COR-001 - Cross-Origin Resource Sharing Allows Any Origin With Credentials MEDIUM Low Effort

    Return Access-Control-Allow-Origin only for an explicit allow-list of trusted origins, never '*' or 'null' together with credentials, and add Vary: Origin.

  142. WEB-DOC-003 - Archives or Certificates Inside a Web Root MEDIUM Low Effort

    Confirm each file is meant to be public. Move backups and anything holding a private key outside the document root, rotate any exposed key, and keep published downloads in a dedicated folder such as /downloads/.

  143. WEB-EXP-003 - PHP Information Page Exposed MEDIUM Low Effort

    Delete the file. Never leave diagnostic pages on a production server.

  144. WEB-EXP-005 - Directory Listing Enabled MEDIUM Low Effort

    Apache: Options -Indexes . nginx: autoindex off; (the default). Add an empty index.html to folders that must stay browsable-free.

  145. WEB-EXP-006 - Web Server Status Page Exposed MEDIUM Low Effort

    Restrict to administrators: <Location /server-status> Require local </Location> (Apache), or allow 127.0.0.1; deny all; (nginx). Remove the module if unused.

  146. WEB-EXP-011 - Database Administration Tool Exposed MEDIUM Low Effort

    Remove the tool, or restrict it to administrators by IP allow-list, VPN or an extra authentication layer, and keep it updated.

  147. WEB-HDR-001 - Missing HTTP Strict Transport Security (HSTS) MEDIUM Low Effort

    Apache: Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" . nginx: add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; . Only add 'preload' once every subdomain supports HTTPS.

  148. WEB-HDR-003 - Site Can Be Framed (Clickjacking) MEDIUM Low Effort

    Send Content-Security-Policy: frame-ancestors 'self' (modern) and X-Frame-Options: SAMEORIGIN (older browsers).

  149. WEB-NGX-002 - nginx Directory Listing Enabled in Configuration MEDIUM Low Effort

    Remove autoindex on; or set autoindex off; in that block. Where a listing is really needed, protect the location with auth_basic or an allow list.

  150. WEB-NGX-007 - nginx Serves Hidden Files and Folders MEDIUM Low Effort

    Add to every server block: location ~ /\. { deny all; access_log off; log_not_found off; } and keep .well-known reachable with a more specific location ^~ /.well-known/ block before it.

  151. WEB-PHP-001 - PHP Displays Errors to Visitors MEDIUM Low Effort

    In php.ini set display_errors = Off and log_errors = On , then restart PHP-FPM or the web server.

  152. WEB-PHP-005 - PHP Session Cookies Not Hardened MEDIUM Low Effort

    In php.ini set session.cookie_httponly = 1 , session.use_strict_mode = 1 , session.cookie_samesite = Lax and, for HTTPS sites, session.cookie_secure = 1 , then restart PHP-FPM.

  153. WEB-PY-002 - Django Accepts Any Host Header MEDIUM Low Effort

    List the real domain names: ALLOWED_HOSTS = ['example.com', 'www.example.com'], and restart the application.

  154. WEB-TLS-001 - Site Available Over Plain HTTP Without Redirect MEDIUM Low Effort

    Apache: in the port 80 vhost add Redirect permanent / https://<site>/ . nginx: return 301 https://$host$request_uri; . Get a free certificate with certbot if HTTPS is not set up yet.

  155. WEB-TOM-003 - Tomcat Shutdown Port Uses the Default Command MEDIUM Low Effort

    Disable the port with <Server port="-1" ...> and stop Tomcat through systemd, or set shutdown to a long random string. Restart Tomcat.

  156. WEB-TOM-005 - Tomcat Example and Documentation Applications Deployed MEDIUM Low Effort

    Delete the examples and docs folders from webapps (or apt remove tomcatN-examples tomcatN-docs) and restart Tomcat.

  157. HOST-BOOT-001 - Boot Loader Has No Password MEDIUM Medium Effort

    Run grub-mkpasswd-pbkdf2 (grub2-setpassword on RHEL family), add set superusers="admin" and password_pbkdf2 admin <hash> to /etc/grub.d/40_custom (RHEL family writes /boot/grub2/user.cfg), then regenerate with update-grub or grub2-mkconfig -o /boot/grub2/grub.cfg. Add --unrestricted to the normal menu entry so unattended reboots still work.

  158. HOST-BOOT-006 - No File Integrity Monitoring MEDIUM Medium Effort

    Install AIDE (apt install aide / dnf install aide), initialise the database with aideinit or aide --init, move the new database into place, and enable the daily check (dailyaidecheck.timer on Debian family, or a cron.daily entry) that mails or logs the differences.

  159. HOST-CTR-002 - Docker Daemon Not Hardened MEDIUM Medium Effort

    Add to /etc/docker/daemon.json: "no-new-privileges": true, "icc": false, "userns-remap": "default", "live-restore": true then restart Docker after testing your containers.

  160. HOST-CTR-012 - Containers Run Without Memory or Process Limits MEDIUM Medium Effort

    Recreate each container with --memory (for example 512m) and --pids-limit (for example 256), or set them in the compose file under deploy.resources.limits / pids_limit.

  161. HOST-CTR-013 - Containers Run as Root With a Writable Root Filesystem MEDIUM Medium Effort

    Add USER <uid> to the image or run with --user 1000:1000, and start the container with --read-only plus --tmpfs /tmp for scratch space; recreate the container.

  162. HOST-FS-016 - SUID or SGID Programs Outside the Known Baseline MEDIUM Medium Effort

    For each listed program decide whether the bit is needed. Remove it with chmod u-s,g-s <path> or uninstall the package. Record the ones you keep so the next review is quick. Caution: programs such as passwd, sudo, su, mount and ping need their bit to work for normal users; removing it from those breaks password changes and administrator access.

  163. HOST-PKG-005 - Running Kernel Older Than Installed Kernel MEDIUM Medium Effort

    Schedule a maintenance window and reboot into the newest kernel. Where downtime is a problem, use the distribution's live patching service and still plan regular reboots.

  164. HOST-PWD-004 - No Account Lockout After Failed Logins MEDIUM Medium Effort

    Enable pam_faillock (authselect enable-feature with-faillock on RHEL family; pam-auth-update or a faillock profile on Debian/Ubuntu) with settings such as deny=5 unlock_time=900 in /etc/security/faillock.conf. Keep a root session open and test a login in a second session before closing it: a wrong PAM line can lock every user out, including administrators. Do not lock root (no even_deny_root) unless console access is assured.

  165. HOST-SYSD-001 - Custom Services Run as Root MEDIUM Medium Effort

    Create a dedicated account (useradd --system --no-create-home --shell /usr/sbin/nologin <app>), give it ownership of only the folders the app writes to, then add User=<app> and Group=<app> to the [Service] section (or DynamicUser=yes). Run systemctl daemon-reload and restart the service. Ports below 1024 can be allowed with AmbientCapabilities=CAP_NET_BIND_SERVICE instead of root.

  166. HOST-UPD-002 - Reboot Required to Apply Updates MEDIUM Medium Effort

    Schedule a maintenance window and reboot (or use live patching where supported).

  167. HOST-USR-004 - Duplicate User IDs MEDIUM Medium Effort

    Give each account a unique UID (usermod -u <new-uid> <user>) and fix file ownership (find / -xdev -uid <old-uid>).

  168. HOST-USR-008 - Duplicate Group IDs or Account Names MEDIUM Medium Effort

    groupmod -g <new-gid> <group> for one of each duplicate pair, then fix file ownership (find / -xdev -gid <old-gid>); remove or rename the duplicate name entries with vigr and vipw, which lock the files while editing.

  169. NET-FW-001 - No Active Host Firewall MEDIUM Medium Effort

    Ubuntu: ufw default deny incoming && ufw allow OpenSSH && ufw allow 80,443/tcp && ufw enable . RHEL family: systemctl enable --now firewalld . Always allow SSH before enabling, or you will lock yourself out.

  170. NET-FW-005 - Container Ports Bypass the Host Firewall MEDIUM Medium Effort

    Publish container ports on loopback only (-p 127.0.0.1:8080:80) and put a reverse proxy in front, or add filtering to DOCKER-USER, for example: iptables -I DOCKER-USER -i eth0 ! -s 203.0.113.0/24 -j DROP (persist it with your firewall tooling). Caution: test from an allowed address first; a wrong interface name or source range cuts access to every published container.

  171. NET-TLS-005 - TLS Certificate Public Key Too Small MEDIUM Medium Effort

    Replace the certificate and private key with RSA 2048 bits or stronger, or an approved EC key of at least 256 bits.

  172. NET-TLS-006 - SHA-1 Signed TLS Leaf Certificate MEDIUM Medium Effort

    Reissue the certificate with SHA-256 or stronger and deploy the complete updated chain.

  173. WEB-CK-001 - Cookies Missing Secure, HttpOnly or SameSite MEDIUM Medium Effort

    PHP: session.cookie_secure=1, session.cookie_httponly=1, session.cookie_samesite=Lax in php.ini . Frameworks have equivalent settings (e.g. Laravel config/session.php). Use HttpOnly for every cookie JavaScript does not need to read.

  174. WEB-HDR-002 - Missing Content Security Policy MEDIUM Medium Effort

    Start with a report-only policy to find what the site loads, then enforce, for example: Content-Security-Policy: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'

  175. WEB-PY-005 - Python Development Server Used in a Service MEDIUM Medium Effort

    Serve the application with a production server (Gunicorn or uWSGI for WSGI, Uvicorn without --reload or Hypercorn for ASGI) bound to 127.0.0.1, behind nginx or Apache. Serve static files from the web server.

  176. HOST-BOOT-002 - UEFI Secure Boot Disabled MEDIUM High Effort

    Enable Secure Boot in the firmware set-up and boot a signed shim and kernel (every mainstream distribution ships them). Custom kernels and out-of-tree modules then need signing with a Machine Owner Key. Where the platform cannot do Secure Boot, record the exception. Caution: unsigned kernels and modules (for example DKMS drivers such as NVIDIA or ZFS) stop loading once it is on, so sign or replace them first and keep console access for the first boot.

  177. HOST-AUD-001 - Audit Daemon Not Enabled at Boot LOW Low Effort

    systemctl enable auditd (on some distributions: systemctl enable --now auditd). Then confirm the rules in /etc/audit/rules.d load at boot with augenrules --check.

  178. HOST-AUD-002 - Identity Files Not Audited LOW Low Effort

    Add to /etc/audit/rules.d/50-identity.rules: -w /etc/passwd -p wa -k identity and the same for /etc/group, /etc/shadow, /etc/gshadow, /etc/sudoers and /etc/sudoers.d/ , then run augenrules --load.

  179. HOST-AUD-003 - Login and Logout Events Not Audited LOW Low Effort

    Add to /etc/audit/rules.d/50-login.rules: -w /var/log/lastlog -p wa -k logins , -w /var/run/faillock -p wa -k logins , -w /var/log/wtmp -p wa -k session , -w /var/log/btmp -p wa -k session , then augenrules --load.

  180. HOST-AUD-004 - System Time Changes Not Audited LOW Low Effort

    Add to /etc/audit/rules.d/50-time.rules: -a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -k time-change (and the same with arch=b32), plus -w /etc/localtime -p wa -k time-change , then augenrules --load.

  181. HOST-AUD-005 - Kernel Module Loading Not Audited LOW Low Effort

    Add to /etc/audit/rules.d/50-modules.rules: -a always,exit -F arch=b64 -S init_module,finit_module,delete_module -k modules (and arch=b32), or -a always,exit -F path=/usr/bin/kmod -F perm=x -F auid>=1000 -F auid!=unset -k modules , then augenrules --load.

  182. HOST-AUD-006 - Privileged Command Use Not Audited LOW Low Effort

    Generate rules for every setuid and setgid program: find / -xdev \( -perm -4000 -o -perm -2000 \) -type f | awk '{print "-a always,exit -F path=" $1 " -F perm=x -F auid>=1000 -F auid!=unset -k privileged"}' > /etc/audit/rules.d/50-privileged.rules then augenrules --load.

  183. HOST-AUD-007 - Audit Configuration Not Immutable LOW Low Effort

    Add -e 2 as the last line of the last file in /etc/audit/rules.d (for example 99-finalize.rules), then augenrules --load and reboot. Plan rule changes before enabling it: every later change needs a reboot.

  184. HOST-AUD-008 - Audit Log Files Readable by Others LOW Low Effort

    chmod 0750 /var/log/audit && chmod 0600 /var/log/audit/* && chown -R root:root /var/log/audit , and set log_group = root in /etc/audit/auditd.conf so new files keep these modes.

  185. HOST-AUD-009 - Audit Daemon Ignores a Full Log Disk LOW Low Effort

    In /etc/audit/auditd.conf set max_log_file_action = keep_logs (or rotate with enough num_logs), space_left_action = email (or syslog or exec), and admin_space_left_action = halt or single as policy requires, then systemctl restart auditd. Caution: admin_space_left_action = halt or single stops the server or drops it to single-user mode when the audit disk fills; choose it only where losing audit records is worse than downtime, and give /var/log/audit room and monitoring first.

  186. HOST-AUD-010 - Journal Not Persistent or Not Compressed LOW Low Effort

    In /etc/systemd/journald.conf set Storage=persistent and Compress=yes , create the directory with mkdir -p /var/log/journal && systemd-tmpfiles --create --prefix /var/log/journal , then systemctl restart systemd-journald.

  187. HOST-BOOT-007 - Prelink Installed LOW Low Effort

    Undo and remove it: prelink -ua && apt purge prelink (or dnf remove prelink). Then re-initialise the integrity database (aide --init).

  188. HOST-BOOT-008 - Core Dumps Not Restricted LOW Low Effort

    Add * hard core 0 to /etc/security/limits.conf (or a file in limits.d), set Storage=none and ProcessSizeMax=0 in the [Coredump] section of /etc/systemd/coredump.conf, and keep fs.suid_dumpable = 0.

  189. HOST-CTR-005 - Docker Container Logs Have No Size Limit LOW Low Effort

    Add to /etc/docker/daemon.json: "log-driver": "json-file", "log-opts": {"max-size": "10m", "max-file": "3"} (or use journald) and restart Docker; recreate containers that set their own LogConfig.

  190. HOST-CTR-006 - Docker Userland Proxy Enabled LOW Low Effort

    Add "userland-proxy": false to /etc/docker/daemon.json and restart Docker; test that published ports still answer from the host itself.

  191. HOST-CTR-007 - Docker Default Ulimits Not Set LOW Low Effort

    Add to /etc/docker/daemon.json: "default-ulimits": {"nofile": {"Name": "nofile", "Hard": 65536, "Soft": 32768}, "nproc": {"Name": "nproc", "Hard": 4096, "Soft": 2048}} and restart Docker; tune the numbers to your workloads.

  192. HOST-FS-009 - Default File Creation Mask Too Permissive LOW Low Effort

    Set UMASK 027 in /etc/login.defs (and, if used, in /etc/profile or /etc/bash.bashrc).

  193. HOST-FS-015 - Files With No Known Owner or Group LOW Low Effort

    Decide who should own each listed file and apply chown <user>:<group> <path>, or remove files that belonged to a deleted account after checking their contents.

  194. HOST-FS-018 - Kernel Symbol Map or Initial RAM Disk Readable by Others LOW Low Effort

    chmod 600 /boot/System.map-* /boot/initrd* /boot/initramfs* and, on Debian family systems, set UMASK=0077 in /etc/initramfs-tools/initramfs.conf so new images are created private.

  195. HOST-FS-019 - Cron and At Not Restricted to Allowed Users LOW Low Effort

    Create the allow lists: touch /etc/cron.allow /etc/at.allow && chmod 600 /etc/cron.allow /etc/at.allow && chown root:root /etc/cron.allow /etc/at.allow then add one user name per line for the accounts that need scheduling, and remove /etc/cron.deny and /etc/at.deny. Caution: once cron.allow exists, crontabs of users not listed stop running, so list every service and user account that has a crontab (ls /var/spool/cron/crontabs or /var/spool/cron) before creating it.

  196. HOST-FS-020 - Cron Configuration Readable by Other Users LOW Low Effort

    chown root:root /etc/crontab /etc/cron.* && chmod 600 /etc/crontab && chmod 700 /etc/cron.d /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly

  197. HOST-FS-021 - Shell Profile Sets a Permissive File Creation Mask LOW Low Effort

    Change every umask 022 line in the listed files to umask 027, or remove the line so the login.defs value applies. Users start a new login shell to pick it up.

  198. HOST-IDS-001 - No Brute-Force Protection Service LOW Low Effort

    Install and enable one, for example: apt install fail2ban && systemctl enable --now fail2ban , with an sshd jail enabled.

  199. HOST-KRN-002 - Kernel Pointers Exposed to Unprivileged Users LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.kptr_restrict = 1 then apply with: sysctl --system

  200. HOST-KRN-003 - Kernel Log Readable by Unprivileged Users LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.dmesg_restrict = 1 then apply with: sysctl --system

  201. HOST-KRN-004 - Setuid Programs May Dump Core LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: fs.suid_dumpable = 0 then apply with: sysctl --system

  202. HOST-KRN-005 - IP Forwarding Enabled LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.ip_forward = 0 then apply with: sysctl --system

  203. HOST-KRN-006 - ICMP Redirects Accepted LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.conf.all.accept_redirects = 0 then apply with: sysctl --system

  204. HOST-KRN-007 - Source-Routed Packets Accepted LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.conf.all.accept_source_route = 0 then apply with: sysctl --system

  205. HOST-KRN-008 - TCP SYN Cookies Disabled LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.tcp_syncookies = 1 then apply with: sysctl --system

  206. HOST-KRN-010 - Process Tracing Not Restricted LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.yama.ptrace_scope = 1 then apply with: sysctl --system

  207. HOST-KRN-011 - Symlink Protection Disabled LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: fs.protected_symlinks = 1 then apply with: sysctl --system

  208. HOST-KRN-012 - Hardlink Protection Disabled LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: fs.protected_hardlinks = 1 then apply with: sysctl --system

  209. HOST-KRN-013 - Reverse Path Filtering Disabled LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.conf.all.rp_filter = 1 then apply with: sysctl --system

  210. HOST-KRN-014 - Martian Packets Not Logged LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.conf.all.log_martians = 1 then apply with: sysctl --system

  211. HOST-KRN-015 - Server Sends ICMP Redirects LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.conf.all.send_redirects = 0 then apply with: sysctl --system

  212. HOST-KRN-016 - Broadcast ICMP Echo Answered LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.icmp_echo_ignore_broadcasts = 1 then apply with: sysctl --system

  213. HOST-KRN-017 - IPv6 ICMP Redirects Accepted LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv6.conf.all.accept_redirects = 0 then apply with: sysctl --system

  214. HOST-KRN-018 - Performance Events Open to Unprivileged Users LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.perf_event_paranoid = 2 then apply with: sysctl --system

  215. HOST-KRN-019 - Magic SysRq Key Enabled LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.sysrq = 0 then apply with: sysctl --system

  216. HOST-KRN-020 - FIFO Protection in Shared Directories Disabled LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: fs.protected_fifos = 1 then apply with: sysctl --system

  217. HOST-KRN-021 - Regular File Protection in Shared Directories Disabled LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: fs.protected_regular = 1 then apply with: sysctl --system

  218. HOST-KRN-022 - Unprivileged User Namespaces Allowed LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing kernel.unprivileged_userns_clone = 0 (Debian family) or user.max_user_namespaces = 0 (other kernels), then apply with: sysctl --system. Rootless Docker, Podman, Flatpak and some browsers need user namespaces, so test first.

  219. HOST-KRN-023 - IPv6 Source-Routed Packets Accepted LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv6.conf.all.accept_source_route = 0 then apply with: sysctl --system

  220. HOST-KRN-024 - Secure ICMP Redirects Accepted LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.conf.all.secure_redirects = 0 then apply with: sysctl --system

  221. HOST-KRN-025 - IPv6 Router Advertisements Accepted LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv6.conf.all.accept_ra = 0 then apply with: sysctl --system. Caution: on a host that gets its IPv6 address or default route from router advertisements (SLAAC, most cloud dual-stack VMs), accept_ra = 0 removes the IPv6 default route and cuts IPv6 connectivity. Use it only with static IPv6 addressing; otherwise keep accept_ra = 1 and rely on RA Guard on the switch or a host firewall rule for RA sources.

  222. HOST-KRN-026 - Bogus ICMP Error Responses Logged LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.icmp_ignore_bogus_error_responses = 1 then apply with: sysctl --system

  223. HOST-KRN-027 - Kexec Kernel Replacement Allowed LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.kexec_load_disabled = 1 then apply with: sysctl --system. Caution: kexec_load_disabled = 1 also stops kdump from loading its crash kernel (kdump.service on the RHEL family, kdump-tools on Debian and Ubuntu), so crash dumps are lost. Keep it 0 where kdump is used, or accept that trade-off deliberately. The setting cannot be turned back off without a reboot.

  224. HOST-KRN-028 - Unprivileged userfaultfd Allowed LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: vm.unprivileged_userfaultfd = 0 then apply with: sysctl --system. Caution: unprivileged live migration tools (for example QEMU post-copy migration or CRIU run as a normal user) need userfaultfd; test those first.

  225. HOST-KRN-029 - TTY Line Discipline Autoloading Enabled LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: dev.tty.ldisc_autoload = 0 then apply with: sysctl --system

  226. HOST-KRN-030 - BPF JIT Hardening Off LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.core.bpf_jit_harden = 2 then apply with: sysctl --system

  227. HOST-KRN-031 - io_uring Open to Unprivileged Users LOW Low Effort

    Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.io_uring_disabled = 2 then apply with: sysctl --system. Caution: applications that use io_uring for fast I/O (some databases, proxies and runtimes) fall back or fail to start when it is disabled; test them first, or use 1 to allow only a chosen group.

  228. HOST-LOG-001 - System Logging Not Persistent LOW Low Effort

    Either install and enable rsyslog, or make the journal persistent: mkdir -p /var/log/journal && systemd-tmpfiles --create --prefix /var/log/journal && systemctl restart systemd-journald

  229. HOST-LOG-003 - Security Logs Readable by All Users LOW Low Effort

    chmod o-rwx /var/log/auth.log /var/log/secure /var/log/syslog /var/log/messages and set the matching create mode in /etc/logrotate.d.

  230. HOST-LOG-004 - Log Rotation Not Configured LOW Low Effort

    Install logrotate (apt install logrotate / dnf install logrotate) and keep its daily timer enabled, or set SystemMaxUse= in journald.conf.

  231. HOST-PAM-001 - Password Quality Module Not Enforced LOW Low Effort

    Install libpam-pwquality (Debian/Ubuntu) or libpwquality (RHEL family). Make sure the password stack has password requisite pam_pwquality.so retry=3 before pam_unix (pam-auth-update or authselect enable-feature with-pwquality), and in /etc/security/pwquality.conf keep dictcheck = 1 and usercheck = 1 . Pair it with a breached-password blocklist where possible. Keep a root session open and test a login and a password change in a second session before closing it: a wrong PAM line can lock every user out.

  232. HOST-PAM-002 - Account Lockout Releases Too Quickly LOW Low Effort

    In /etc/security/faillock.conf set unlock_time = 900 (or 0 to require an administrator to run faillock --reset), keeping deny between 3 and 10. Keep a root session open and test in a second session before closing the first: a wrong PAM line can lock every user out, and unlock_time = 0 means locked accounts, administrators included, wait for faillock --reset.

  233. HOST-PAM-003 - su Not Restricted to an Administrative Group LOW Low Effort

    In /etc/pam.d/su uncomment or add auth required pam_wheel.so use_uid group=sudo (group=wheel on the RHEL family), and make sure the group contains only administrators. Caution: add every administrator who uses su to that group first and test from a second session, or they lose su access.

  234. HOST-PAM-004 - Password History Not Enforced LOW Low Effort

    Add password required pam_pwhistory.so remember=5 use_authtok before pam_unix in the password stack (pam-auth-update on Debian/Ubuntu, authselect enable-feature with-pwhistory on the RHEL family), or set remember = 5 in /etc/security/pwhistory.conf. Keep a root session open and test a password change in a second session before closing it: a wrong PAM line can block password changes or logins.

  235. HOST-PAM-005 - Minimum Password Age Not Set LOW Low Effort

    Set PASS_MIN_DAYS 1 in /etc/login.defs, and for existing accounts chage --mindays 1 <user> .

  236. HOST-PAM-007 - Inactive Accounts Never Locked LOW Low Effort

    useradd -D -f 30 (writes INACTIVE=30 to /etc/default/useradd), and for existing accounts chage --inactive 30 <user> . Caution: this locks accounts whose password has expired for 30 days, so exempt break-glass and rarely used administrator accounts or keep their passwords current.

  237. HOST-PAM-009 - No Shell Idle Timeout LOW Low Effort

    Create /etc/profile.d/99-tmout.sh with TMOUT=900 ; readonly TMOUT ; export TMOUT (mode 644, owned by root). Sessions that must stay open should use a multiplexer such as tmux with its own lock, not a longer TMOUT. Caution: a readonly TMOUT ends idle interactive shells, including foreground jobs left waiting in them; run long jobs under nohup, systemd-run or a multiplexer.

  238. HOST-PKG-004 - Many Old Kernels Retained LOW Low Effort

    Debian/Ubuntu: apt-get autoremove --purge removes kernels outside the keep list. RHEL family: set installonly_limit=3 in /etc/dnf/dnf.conf and run dnf remove --oldinstallonly . Never remove the running kernel (uname -r).

  239. HOST-PKG-006 - Package Lists Not Refreshed Automatically LOW Low Effort

    Debian/Ubuntu: create /etc/apt/apt.conf.d/20auto-upgrades with APT::Periodic::Update-Package-Lists "1"; (dpkg-reconfigure unattended-upgrades writes it) and systemctl enable apt-daily.timer . RHEL family: systemctl enable --now dnf-makecache.timer .

  240. HOST-PWD-003 - Short Minimum Password Length LOW Low Effort

    Install libpam-pwquality (Debian/Ubuntu) or libpwquality (RHEL family) and set minlen = 15 (or more) in /etc/security/pwquality.conf.

  241. HOST-SSH-005 - SSH X11 Forwarding Enabled LOW Low Effort

    Set X11Forwarding no in /etc/ssh/sshd_config and reload sshd.

  242. HOST-SSH-006 - SSH Allows Many Authentication Attempts LOW Low Effort

    Set MaxAuthTries 4 (or lower) in /etc/ssh/sshd_config and reload sshd. Consider fail2ban or sshguard for rate limiting.

  243. HOST-SSH-008 - SSH Authentication Controls Too Permissive LOW Low Effort

    Set LoginGraceTime 60 or lower and choose AuthenticationMethods appropriate to the server, such as publickey, then restrict access with AllowUsers or AllowGroups where practical.

  244. HOST-SSH-012 - SSH Logging Level Too Low LOW Low Effort

    Set LogLevel VERBOSE (or INFO) in /etc/ssh/sshd_config and reload sshd.

  245. HOST-SSH-013 - SSH Authorized Keys Without Restrictions or Protection LOW Low Effort

    Prefix each root key with options, for example from="203.0.113.0/24",no-port-forwarding,no-agent-forwarding or command="/usr/local/bin/backup",restrict ; chmod 600 ~/.ssh/authorized_keys and 700 ~/.ssh for every account. Prefer sudo from a personal account over direct root keys.

  246. HOST-SUDO-001 - Sudo Commands Not Logged to a Dedicated File LOW Low Effort

    With visudo add: Defaults use_pty and Defaults logfile="/var/log/sudo.log"

  247. HOST-SVC-001 - Unnecessary Legacy Services Running LOW Low Effort

    systemctl disable --now <service> for each listed service you do not need, or remove its package. Caution: check first that nothing depends on it (systemctl list-dependencies --reverse <service>) and keep console access when disabling network or remote-access services.

  248. HOST-SVC-007 - Avahi or CUPS Installed or Enabled LOW Low Effort

    apt purge avahi-daemon cups cups-daemon or dnf remove avahi cups , and systemctl disable --now avahi-daemon.socket avahi-daemon.service cups.socket cups.service . Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.

  249. HOST-SVC-008 - NFS Server or rpcbind Installed or Enabled LOW Low Effort

    apt purge nfs-kernel-server rpcbind or dnf remove nfs-utils rpcbind where NFS is not served, and systemctl disable --now nfs-server rpcbind.socket rpcbind.service . Where NFS is required, export read-only with root_squash to named hosts and firewall port 2049 and 111. Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.

  250. HOST-SVC-009 - DHCP or DNS Server Installed or Enabled LOW Low Effort

    apt purge isc-dhcp-server bind9 or dnf remove dhcp-server bind , and systemctl disable --now isc-dhcp-server named . If this machine is meant to be a DNS or DHCP server, record that in the suppression file and review NET-SVC findings for its configuration. Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.

  251. HOST-SVC-010 - Samba File Server Installed or Enabled LOW Low Effort

    apt purge samba or dnf remove samba , and systemctl disable --now smbd nmbd (smb nmb on the RHEL family). Where it is required, disable SMB1, require signing and restrict shares to named users. Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.

  252. HOST-SVC-011 - SNMP Agent or Squid Proxy Installed or Enabled LOW Low Effort

    apt purge snmpd squid or dnf remove net-snmp squid , and systemctl disable --now snmpd squid . If monitoring needs SNMP, use version 3 with authPriv and bind the agent to the management network. Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.

  253. HOST-SVC-012 - inetd Super-Server Installed or Enabled LOW Low Effort

    apt purge xinetd openbsd-inetd or dnf remove xinetd , and systemctl disable --now xinetd . Review /etc/inetd.conf and /etc/xinetd.d first so nothing needed disappears. Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.

  254. HOST-TIME-001 - Time Synchronisation Not Active LOW Low Effort

    Enable one time service, for example: systemctl enable --now systemd-timesyncd (or install chrony).

  255. HOST-UPD-001 - Automatic Security Updates Not Configured LOW Low Effort

    Debian/Ubuntu: apt install unattended-upgrades && dpkg-reconfigure -plow unattended-upgrades . RHEL family: dnf install dnf-automatic, set apply_updates = yes and upgrade_type = security, then systemctl enable --now dnf-automatic.timer .

  256. HOST-USR-005 - System Accounts With Login Shells LOW Low Effort

    usermod -s /usr/sbin/nologin <account> for each listed account (use /sbin/nologin on RHEL family).

  257. HOST-USR-010 - Home Directories Accessible to Other Users LOW Low Effort

    chmod 750 /home/<user> for each listed account (700 if group access is not needed), and set HOME_MODE 0750 in /etc/login.defs or DIR_MODE=0750 in /etc/adduser.conf so new accounts start that way.

  258. NET-DB-017 - MySQL Error Log Not Configured LOW Low Effort

    Add log_error = /var/log/mysql/error.log under [mysqld], make the folder writable by the mysql user, and add a logrotate rule.

  259. NET-DB-018 - MySQL Resolves Client Host Names LOW Low Effort

    Rewrite grants that use host names to IP addresses or '%', then add skip-name-resolve under [mysqld] and restart in a maintenance window.

  260. NET-DB-021 - PostgreSQL Connection Logging Off LOW Low Effort

    Set log_connections = on and log_disconnections = on in postgresql.conf and reload. On PostgreSQL 18 and newer, log_connections accepts a list such as receipt,authentication,authorization .

  261. NET-DNS-001 - BIND Version String Disclosed LOW Low Effort

    Add version "not disclosed"; inside the options block and run named-checkconf, then rndc reconfig.

  262. NET-FW-004 - Firewall Rules Open Ports With No Service LOW Low Effort

    Remove rules for services that no longer exist (ufw status numbered, then ufw delete <n>), or note why a rule must stay. Review the firewall whenever a service is retired.

  263. NET-MAIL-003 - Postfix VRFY Command Enabled LOW Low Effort

    Add disable_vrfy_command = yes to main.cf and postfix reload.

  264. WEB-APA-001 - Apache Reveals Version in Header and Footer LOW Low Effort

    Set ServerTokens Prod and ServerSignature Off in apache2.conf or conf-enabled/security.conf (Debian) or httpd.conf (RHEL), then apachectl configtest and reload.

  265. WEB-APA-002 - Apache TRACE Method Enabled LOW Low Effort

    Add TraceEnable Off to the server configuration and reload.

  266. WEB-APA-004 - Apache AllowOverride All Permits .htaccess Control LOW Low Effort

    Set AllowOverride None and move needed rules into the vhost, or allow only what the application needs, for example AllowOverride FileInfo Indexes Limit for WordPress permalinks.

  267. WEB-APA-007 - Apache OCSP Stapling Not Enabled LOW Low Effort

    Add SSLUseStapling On inside the vhost and SSLStaplingCache "shmcb:logs/ssl_stapling(32768)" outside it, as the Mozilla generator produces.

  268. WEB-APA-009 - Apache ETag Reveals Inode Numbers LOW Low Effort

    Set FileETag MTime Size or FileETag None and reload.

  269. WEB-APA-010 - Apache Serves Repository and Environment Files LOW Low Effort

    Add to the server configuration: <DirectoryMatch "/\.(git|svn|hg)"> Require all denied </DirectoryMatch> and <FilesMatch "^\.(env|git|svn)"> Require all denied </FilesMatch> , then reload.

  270. WEB-APP-007 - Flask Debug Mode Enabled in Application Code LOW Low Effort

    Remove debug=True from app.run() and read it from the environment for local work only (app.run(debug=os.environ.get('FLASK_DEBUG') == '1')); serve production with Gunicorn or uWSGI, which never call app.run().

  271. WEB-CMS-001 - WordPress Version Disclosed LOW Low Effort

    Keep WordPress updated (automatic minor updates on). Remove the generator tag (remove_action('wp_head','wp_generator')) and delete readme.html after each update, or block it at the web server.

  272. WEB-CMS-002 - WordPress XML-RPC Interface Enabled LOW Low Effort

    Block it at the web server (<Files xmlrpc.php> Require all denied </Files>) or disable it with a security plugin, unless Jetpack or the mobile app needs it.

  273. WEB-CMS-003 - WordPress User Accounts Enumerable LOW Low Effort

    Restrict the users endpoint to authenticated requests with a security plugin or a small rest_endpoints filter, and use login names that differ from public display names.

  274. WEB-CMS-007 - WordPress Dashboard File Editor Enabled LOW Low Effort

    Add define('DISALLOW_FILE_EDIT', true); to wp-config.php above the line that says to stop editing.

  275. WEB-CMS-010 - Joomla Version Disclosed LOW Low Effort

    Block the folder at the web server (Apache: <Directory "/path/administrator/manifests"> Require all denied </Directory>; nginx: location ^~ /administrator/manifests/ { deny all; }) and keep Joomla updated.

  276. WEB-CMS-011 - Drupal Version Disclosed by Changelog LOW Low Effort

    Delete the changelog files after each update, or deny *.txt files in the Drupal root and core folders at the web server, and keep Drupal updated.

  277. WEB-CMS-018 - WordPress Author Archive Reveals Login Names LOW Low Effort

    Return 404 for author queries by id (a small redirect rule or a security plugin's user enumeration protection), and give administrators a nickname and display name that differ from the login name.

  278. WEB-EXP-009 - Dependency Manifests Exposed LOW Low Effort

    Keep manifests outside the public web root (for example serve only a public/ subfolder), or deny them at the web server.

  279. WEB-EXP-010 - Default Web Server Page Served LOW Low Effort

    Remove the default site or replace its index page, and disable unused virtual hosts.

  280. WEB-HDR-004 - Missing X-Content-Type-Options LOW Low Effort

    Send X-Content-Type-Options: nosniff on every response (Apache: Header always set X-Content-Type-Options nosniff; nginx: add_header X-Content-Type-Options nosniff always;).

  281. WEB-HDR-005 - Missing Referrer-Policy LOW Low Effort

    Send Referrer-Policy: strict-origin-when-cross-origin (or no-referrer). Never use unsafe-url.

  282. WEB-HDR-006 - Missing Permissions-Policy LOW Low Effort

    Send, for example, Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=() adjusted to the features the site really uses.

  283. WEB-HDR-007 - Server Software Version Disclosed LOW Low Effort

    Apache: ServerTokens Prod and ServerSignature Off . nginx: server_tokens off; . PHP: expose_php = Off in php.ini . Remove X-Powered-By in the application or proxy.

  284. WEB-NGX-001 - nginx Version Shown in Server Header LOW Low Effort

    In the http block of nginx.conf add server_tokens off; then run nginx -t and reload.

  285. WEB-NGX-005 - nginx OCSP Stapling Off or Session Tickets On LOW Low Effort

    Add ssl_stapling on; ssl_stapling_verify on; ssl_session_tickets off; and a resolver directive, as the Mozilla generator produces.

  286. WEB-NODE-003 - Node.js Service Not Running in Production Mode LOW Low Effort

    Add Environment=NODE_ENV=production to the [Service] section (systemctl edit <unit>), run systemctl daemon-reload and restart the service.

  287. WEB-PHP-002 - PHP Version Exposed in Headers LOW Low Effort

    In php.ini set expose_php = Off and restart PHP.

  288. HOST-AUD-011 - Logs Not Forwarded to a Remote Collector LOW Medium Effort

    rsyslog: create /etc/rsyslog.d/90-remote.conf with *.* action(type="omfwd" target="logs.example.internal" port="6514" protocol="tcp" StreamDriver="gtls" StreamDriverMode="1" StreamDriverAuthMode="x509/name") and restart rsyslog. Or configure systemd-journal-upload with URL= pointing at a journal-remote collector. Prefer TLS so logs are not readable in transit.

  289. HOST-BOOT-005 - Kernel Module Loading Unrestricted LOW Medium Effort

    Boot with module.sig_enforce=1 (or lockdown=integrity) on the kernel command line and sign any out-of-tree modules, or set kernel.modules_disabled = 1 from a late boot service once every needed module is loaded (it cannot be turned back on without a reboot).

  290. HOST-CTR-015 - Docker Content Trust Not Enabled LOW Medium Effort

    Add DOCKER_CONTENT_TRUST=1 to /etc/environment (or a file in /etc/profile.d) and sign your own images with docker trust sign; images without signatures then need an explicit --disable-content-trust for a deliberate exception.

  291. HOST-CVE-003 - Vulnerability Snapshot Outdated or Test Data LOW Medium Effort

    Install the vendor security update. For a source build, run 'make vulndb' to embed a snapshot generated from OSV and CISA KEV, then rebuild.

  292. HOST-FS-008 - Temporary Filesystems Allow Executables or Devices LOW Medium Effort

    Mount the path as tmpfs or a separate filesystem with options nodev,nosuid (and noexec where software allows), for example via systemd tmp.mount or /etc/fstab, then remount.

  293. HOST-FS-010 - /var/tmp Not a Separate Filesystem LOW Medium Effort

    Mount /var/tmp as a separate filesystem, or bind-mount it onto /tmp: /tmp /var/tmp none bind,nodev,nosuid,noexec 0 0 in /etc/fstab, then reboot or remount. Caution: /var/tmp is meant to survive reboots and some installers and databases run programs from it, so check what uses it before binding it to /tmp with noexec, and keep console access when editing /etc/fstab (a wrong line can stop the boot).

  294. HOST-FS-011 - /home Not a Separate Filesystem With nodev LOW Medium Effort

    Place /home on its own partition or logical volume and add nodev,nosuid to its options in /etc/fstab; remount with: mount -o remount /home . Caution: moving /home to a new volume needs a backup, a maintenance window and console access; a wrong /etc/fstab line can stop the boot.

  295. HOST-FS-012 - Log Directories on the Root Filesystem LOW Medium Effort

    Place /var/log (and ideally /var/log/audit) on its own partition or logical volume, listed in /etc/fstab with nodev,nosuid,noexec. Caution: moving log directories needs a backup, a maintenance window and console access; stop the logging services while copying, and a wrong /etc/fstab line can stop the boot.

  296. HOST-FS-013 - Temporary Filesystems Allow Executables LOW Medium Effort

    Add noexec to the mount options of each temporary filesystem (systemd tmp.mount drop-in or /etc/fstab) and remount. Some package managers need exec on /tmp during installs; set TMPDIR for them rather than removing noexec.

  297. HOST-LOG-002 - Security Audit Daemon Not Running LOW Medium Effort

    Install the audit package (apt install auditd, or dnf install audit), enable it (systemctl enable --now auditd) and load a rule set appropriate to your policy.

  298. HOST-SYSD-002 - Custom Services Lack Sandboxing LOW Medium Effort

    Add the missing lines with systemctl edit <unit> (a drop-in), for example NoNewPrivileges=yes, ProtectSystem=strict, ReadWritePaths=/var/lib/<app>, PrivateTmp=yes, ProtectHome=yes. Restart the service and test it; add ReadWritePaths= for every folder the app must write. systemd-analyze security <unit> suggests further options.

  299. HOST-MAC-001 - No Mandatory Access Control Enforced LOW High Effort

    Ubuntu/Debian: keep AppArmor enabled (systemctl enable --now apparmor) and its profiles in enforce mode. RHEL family: set SELINUX=enforcing in /etc/selinux/config and relabel. Test applications in permissive or complain mode first.

  300. HOST-PAM-006 - Password Expiry Warning Too Short INFO Low Effort

    Set PASS_WARN_AGE 7 in /etc/login.defs, and for existing accounts chage --warndays 7 <user> .

  301. HOST-PWD-005 - Forced Periodic Password Rotation Configured INFO Low Effort

    Prefer long passphrases, a breached-password blocklist and multi-factor authentication over forced rotation. If policy allows, set PASS_MAX_DAYS 365 or 99999 in /etc/login.defs and change passwords when compromise is suspected.

  302. WEB-APA-008 - Apache Has No Request Filtering Module INFO Low Effort

    Consider ModSecurity with the OWASP Core Rule Set in detection-only mode first, or mod_evasive for simple rate limiting, and tune before blocking.

  303. WEB-CMS-017 - WordPress Cron Reachable by Visitors INFO Low Effort

    Add define('DISABLE_WP_CRON', true); to wp-config.php, run */5 * * * * www-data php /var/www/<site>/wp-cron.php from the system cron (or curl the URL from cron), and deny direct requests to wp-cron.php at the web server.

  304. WEB-NGX-006 - nginx Request Limits Not Configured INFO Low Effort

    Set client_max_body_size to what the application needs (the default is 1m) and add limit_req_zone for login and API locations with a sensible rate. See the nginx limit_req and limit_conn module documentation.

  305. WEB-SEC-001 - No security.txt Contact File INFO Low Effort

    Publish /.well-known/security.txt with at least Contact: and Expires: fields (see securitytxt.org).

  306. HOST-PKG-003 - Third-Party Package Repositories Present INFO Medium Effort

    For each listed repository, record who runs it and why it is needed; remove the ones nobody can justify (delete the file under /etc/apt/sources.list.d or /etc/yum.repos.d and apt-get update or dnf clean all). Keep the rest pinned to the packages they are for (apt preferences, dnf includepkgs).

  307. WEB-APP-008 - Dependency Lock Files Older Than a Year INFO Medium Effort

    Run composer update / npm update / bundle update / poetry update in a test environment, run the audit command of each ecosystem (composer audit, npm audit, bundle audit, pip-audit) and deploy. Schedule dependency updates at least quarterly.

  308. HOST-CTR-009 - Docker Not Running in Rootless Mode INFO High Effort

    Where the workloads allow it, install rootless Docker (dockerd-rootless-setuptool.sh install) for the service account and disable the system daemon; otherwise keep userns-remap (HOST-CTR-002) as the fallback.

Findings

CRITICAL

Docker API Exposed Over TCP Without TLS

HOST-CTR-001

Checks whether the Docker daemon is configured to listen on a TCP socket without TLS client verification.

Why it matters. The Docker API is equivalent to root on the host. Exposed over TCP without mutual TLS, anyone who can reach the port can start a privileged container and take over the machine; this is a common cause of cryptomining infections.

docker: Docker API listens on TCP without TLS verification

daemon.json hosts: tcp://0.0.0.0:2375
Fix
Remove tcp:// listeners and use the local Unix socket or SSH (docker context with ssh://). If remote access is unavoidable, enable tlsverify with client certificates and restrict the port in the firewall.
Verify
ss -tlnp | grep -E ':(2375|2376)' and grep -r 'tcp://' /etc/docker /etc/systemd/system/docker.service.d
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Category
Network Exposure
Effort
Low
Confidence
High
Standards
CWE-306, CWE-319, OWASP A05:2021, A07:2021, NIST 800-53 AC-3, SC-8
References
Docker documentation, Protect the Docker daemon socket
OWASP Docker Security Cheat Sheet
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
Source
internal/checks/host/containers.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

CRITICAL

Known Exploited Vulnerabilities Present

HOST-CVE-002

Checks installed packages against an offline vulnerability snapshot.

Why it matters. Known vulnerable package versions can expose a server to documented attacks.

sudo: sudo 1.8.21p2-3ubuntu1.4: LAB-CVE-2021-3156 (CVE-2021-3156), fixed in 1.8.21p2-3ubuntu1.5, severity high

matcher: range
Snapshot date 2021-01-01. An outdated snapshot misses newer vulnerabilities.

policykit-1: policykit-1 0.105-20ubuntu0.18.04.5: LAB-CVE-2021-4034 (CVE-2021-4034), fixed in 0.105-20ubuntu0.18.04.6, severity high

matcher: range
Snapshot date 2021-01-01. An outdated snapshot misses newer vulnerabilities.
Fix
Install the vendor security update. For a source build, run 'make vulndb' to embed a snapshot generated from OSV and CISA KEV, then rebuild.
Verify
Re-run OpenVAPT after patching and confirm the finding is absent.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Patch and Vulnerability Management
Effort
Medium
Confidence
High
Standards
CWE-1104, OWASP A06:2021, NIST 800-53 SI-2, RA-5
References
OSV vulnerability database
NVD
CISA KEV
Learn
P10: Vulnerability Management: CVE, OSV and Known Exploited Vulnerabilities (offline: openvapt learn P10)
Source
internal/checks/host/cve.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

CRITICAL

Kubelet Allows Anonymous or Unauthorised Access

HOST-K8S-001

Checks the kubelet configuration for anonymous authentication, AlwaysAllow authorisation or the unauthenticated read-only port.

Why it matters. The kubelet API can run commands in every pod on the node. With anonymous access or AlwaysAllow, anyone who can reach port 10250 controls the node's workloads; the read-only port 10255 leaks pod and environment details.

/var/lib/kubelet/config.yaml: Kubelet allows unauthenticated or unauthorised access

authentication.anonymous.enabled: true
authorization.mode: AlwaysAllow
readOnlyPort: 10255
Fix
Set authentication.anonymous.enabled: false, authorization.mode: Webhook and readOnlyPort: 0 in the kubelet configuration, then restart the kubelet.
Verify
grep -A2 -E 'anonymous|authorization|readOnlyPort' /var/lib/kubelet/config.yaml
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Category
Identity and Authentication
Effort
Medium
Confidence
High
Standards
CWE-306, CWE-862, OWASP A01:2021, A07:2021, NIST 800-53 AC-3, IA-2
References
Kubernetes documentation, Kubelet authentication and authorization
Kubernetes documentation, Securing a cluster
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
Source
internal/checks/host/containers.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

CRITICAL

SSH Permits Empty Passwords

HOST-SSH-003

Checks whether SSH lets accounts with an empty password log in.

Why it matters. Any account without a password becomes an open door to anyone on the network.

sshd: Empty passwords are accepted

permitemptypasswords yes
Fix
Set PermitEmptyPasswords no in /etc/ssh/sshd_config, reload sshd, and give every account a password or lock it (passwd -l <user>).
Verify
sshd -T | grep -i permitemptypasswords should print 'no'.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-258, NIST 800-53 IA-5(1)
References
OpenBSD, sshd_config(5) manual page
Learn
P2: SSH Security (offline: openvapt learn P2)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/ssh_empty_passwords.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

CRITICAL

Redis Authentication and Network Binding

NET-DB-002

Redis lacks protected mode, authentication, or a loopback-only bind.

Why it matters. An unauthenticated network-reachable Redis instance can disclose or alter data and may permit dangerous administrative operations.

/etc/redis/redis.conf: Redis lacks protected mode, authentication, or a loopback-only bind.

/etc/redis/redis.conf: protected-mode = no
/etc/redis/redis.conf: bind = 0.0.0.0
Fix
Set protected-mode yes, configure ACL users with strong secrets, bind to 127.0.0.1 and ::1, and restrict remote access with a firewall.
Verify
Review redis-server --test-memory only for health, then inspect the effective configuration and listening socket after reload.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Data Services
Effort
Low
Confidence
High
Standards
CWE-306, CWE-1188, OWASP A05:2021, NIST 800-53 AC-3, CM-6, SC-7
References
Redis Security
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
Source
internal/checks/network/data_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

CRITICAL

MongoDB Authorization and Network Binding

NET-DB-003

MongoDB authorization is disabled or it binds beyond loopback.

Why it matters. MongoDB without authorization or with broad exposure can permit unauthenticated database access.

/etc/mongod.conf: MongoDB authorization is disabled or it binds beyond loopback.

/etc/mongod.conf: authorization = disabled
/etc/mongod.conf: bindip = 0.0.0.0
Fix
Set security.authorization to enabled and net.bindIp to 127.0.0.1, then allow only approved clients through a controlled network path.
Verify
Run mongod --config <file> --configExpand none in a maintenance workflow and confirm port 27017 is loopback-only.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Data Services
Effort
Low
Confidence
High
Standards
CWE-306, CWE-1188, OWASP A05:2021, NIST 800-53 AC-3, CM-6, SC-7
References
MongoDB Security Checklist
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
Source
internal/checks/network/data_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

CRITICAL

PostgreSQL Trust and Broad Client Access

NET-DB-004

PostgreSQL accepts trust authentication or unrestricted client networks.

Why it matters. Trust authentication and all-address client rules can allow database access without a password from untrusted networks.

/etc/postgresql/16/main/postgresql.conf: PostgreSQL accepts trust authentication or unrestricted client networks.

/etc/postgresql/16/main/postgresql.conf: broad or trust rule detected
/etc/postgresql/16/main/pg_hba.conf: broad or trust rule detected
Fix
Bind PostgreSQL to required interfaces only and replace trust or unrestricted pg_hba.conf rules with narrow CIDRs and scram-sha-256. Caution: users whose passwords are stored as md5 cannot log in with scram-sha-256 until their password is set again with password_encryption = scram-sha-256, so reset them first and reload, not restart, to test.
Verify
Run pg_ctl reload through normal operations, then use pg_hba_file_rules and ss -tlnp to verify the effective rules.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Data Services
Effort
Low
Confidence
High
Standards
CWE-306, CWE-1188, OWASP A05:2021, NIST 800-53 AC-3, CM-6, SC-7
References
PostgreSQL Client Authentication
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
Source
internal/checks/network/data_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

CRITICAL

Elasticsearch Security and Network Binding

NET-DB-007

Elasticsearch security is disabled or network.host is broadly reachable.

Why it matters. An exposed Elasticsearch cluster without authentication can disclose, alter, or delete indexed data.

/etc/elasticsearch/elasticsearch.yml: Elasticsearch security is disabled or network.host is broadly reachable.

/etc/elasticsearch/elasticsearch.yml: xpack.security.enabled = false
/etc/elasticsearch/elasticsearch.yml: network.host = 0.0.0.0
Fix
Set xpack.security.enabled true, bind network.host to loopback or an approved private interface, require TLS, and filter access.
Verify
Use the local node configuration API with approved credentials and confirm port 9200 is not broadly exposed.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Data Services
Effort
Low
Confidence
High
Standards
CWE-306, CWE-1188, OWASP A05:2021, NIST 800-53 AC-3, CM-6, SC-7
References
Elastic Security Minimal Setup
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
Source
internal/checks/network/data_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

CRITICAL

Control Plane or Remote Desktop Ports Network-Reachable

NET-SVC-002

Docker API, Kubernetes API, kubelet, etcd, VNC or RDP listen on network-reachable addresses.

Why it matters. These services hand out administrative control of the host or the cluster. The unauthenticated Docker API and etcd give code execution or every cluster secret to whoever connects; RDP and VNC are the most attacked remote access services.

sockets: Control plane or remote desktop ports are network-reachable

tcp 0.0.0.0:2375 Docker API without TLS, bound to all interfaces
tcp 0.0.0.0:6443 Kubernetes API, bound to all interfaces
Fix
Bind control planes to loopback or a dedicated management address, require mutual TLS or strong authentication, and filter access to approved source networks or a VPN.
Verify
Review ss -tulpn and the host firewall from a trusted administrative session.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Network Exposure
Effort
Medium
Confidence
High
Standards
CWE-1327, CWE-923, OWASP A05:2021, NIST 800-53 AC-17, CM-7, SC-7
References
Docker Protect the Daemon Socket
Kubernetes Ports and Protocols
IANA Service Name and Transport Protocol Port Number Registry
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
Source
internal/checks/network/services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

CRITICAL

Environment or Secrets File Exposed

WEB-EXP-002

Checks whether .env and similar configuration files can be downloaded.

Why it matters. Framework .env files hold database passwords, mail credentials, encryption keys and API tokens. Downloading one usually means full compromise of the application and its data.

shop.example.test: Exposed: /.env (HTTP 200)

/.env (HTTP 200)
Fix
Move secrets out of the web root, block dot-files at the web server, delete backup copies, then rotate every secret in the file because it must be treated as leaked.
Verify
curl -s -o /dev/null -w '%{http_code}' https://<site>/.env should print 403 or 404.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Information Exposure
Effort
Medium
Confidence
High
Standards
CWE-538, CWE-260, OWASP A05:2021, ASVS 14.3.2, 2.10.4, NIST 800-53 CM-7, SC-28
References
OWASP Secrets Management Cheat Sheet
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

CRITICAL

Node.js Debugger (Inspector) Enabled in a Service

WEB-NODE-002

Checks whether a Node.js service is started with --inspect, which opens the V8 debugger.

Why it matters. The inspector has no authentication: anyone who can connect to it can run any JavaScript inside the application, as the service's user. Bound to 0.0.0.0 that is remote code execution; even on 127.0.0.1 any local user or server-side request forgery bug can reach it.

systemd units: Node.js services start the debugger

shop-api.service: starts the inspector on a network address (--inspect=0.0.0.0:9229 )
Fix
Remove --inspect from the service and from NODE_OPTIONS, run systemctl daemon-reload and restart. Debug on a development machine, or temporarily over an SSH tunnel to 127.0.0.1:9229.
Verify
systemctl show -p ExecStart,Environment <unit> | grep -c inspect prints 0, and nothing listens on 9229.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-489, CWE-306, OWASP A05:2021, ASVS 14.3.2, NIST 800-53 CM-7, CM-6
References
Node.js documentation, Debugging guide (security implications)
OWASP Node.js Security Cheat Sheet
Learn
P13: Application Servers: Tomcat, Node.js and Python (offline: openvapt learn P13)
Source
internal/checks/web/runtimes.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

CRITICAL

Python Interactive Debugger Enabled in a Service

WEB-PY-004

Checks whether a service runs Flask or Werkzeug with the interactive debugger enabled.

Why it matters. The Werkzeug debugger lets a visitor run Python code from an error page. Its PIN has been bypassed and brute-forced in practice, and with WERKZEUG_DEBUG_PIN=off there is no protection at all: this is remote code execution.

systemd units: Services enable the Python interactive debugger

shop-reports.service: enables the debugger (FLASK_DEBUG=1)
Fix
Remove the debug switches, run the application under a production WSGI server (Gunicorn, uWSGI or mod_wsgi) behind nginx or Apache, run systemctl daemon-reload and restart the service.
Verify
systemctl show -p ExecStart,Environment <unit> shows no debug switches.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-489, CWE-94, OWASP A05:2021, ASVS 14.3.2, NIST 800-53 CM-7, CM-6
References
Werkzeug documentation, Debugging Applications
Flask documentation, Debug mode
Learn
P13: Application Servers: Tomcat, Node.js and Python (offline: openvapt learn P13)
Source
internal/checks/web/runtimes.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

CRITICAL

Tomcat Administrative Users With Default or Weak Passwords

WEB-TOM-002

Checks tomcat-users.xml for manager or admin accounts with well-known default passwords, passwords equal to the user name, or short passwords.

Why it matters. Default Tomcat credentials (tomcat/tomcat, admin/admin, tomcat/s3cret) are in every attack tool's word list. A Manager account with such a password lets anyone deploy code on the server.

/etc/tomcat9: Tomcat administrative users have weak credentials

user "tomcat" (roles manager-gui,admin-gui) uses a documented default password
Fix
Remove accounts you do not need. Give the remaining ones long random passwords and store them as digests: configure a CredentialHandler (for example SecretKeyCredentialHandler with PBKDF2) in the Realm and generate hashes with bin/digest.sh. Restart Tomcat.
Verify
Re-run this check; no administrative user should be listed.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-1392, CWE-521, CWE-256, OWASP A07:2021, ASVS 2.1.1, 2.5.4, NIST 800-53 IA-5
References
Apache Tomcat 10.1, Security Considerations
Apache Tomcat 10.1, Realm Configuration How-To (digested passwords)
Learn
P13: Application Servers: Tomcat, Node.js and Python (offline: openvapt learn P13)
Source
internal/checks/web/tomcat.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

CRITICAL

Tomcat AJP Connector Unprotected (Ghostcat)

WEB-TOM-004

Checks for an active AJP connector that has no shared secret and is not bound to loopback, or that disables the secret requirement.

Why it matters. AJP is a trusted, unauthenticated protocol between a web server and Tomcat. CVE-2020-1938 (Ghostcat) showed that a reachable AJP port lets an attacker read any file in the web applications and, where uploads exist, execute code. It is listed in the CISA Known Exploited Vulnerabilities catalogue.

/etc/tomcat9: AJP connector is reachable without protection

AJP connector on port 8009 is not bound to loopback and does not require a secret
Fix
If you do not use AJP (most sites proxy over HTTP), delete or comment out the AJP <Connector>. Otherwise set address="127.0.0.1", a long random secret="..." with secretRequired="true", and the same secret in the proxy (mod_proxy_ajp: ProxyPass ... secret=...). Upgrade Tomcat to a supported release.
Verify
grep -i ajp <conf>/server.xml and ss -tlnp | grep 8009 shows nothing or 127.0.0.1 only.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Web Application Security
Effort
Low
Confidence
High
Standards
CWE-306, CWE-1327, OWASP A05:2021, A06:2021, NIST 800-53 SC-7, AC-3, CM-7
References
Apache Tomcat 10.1, Security Considerations
Apache Tomcat 10.1 Configuration Reference, The AJP Connector
NVD, CVE-2020-1938
Learn
P13: Application Servers: Tomcat, Node.js and Python (offline: openvapt learn P13)
Source
internal/checks/web/tomcat.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Cron Jobs Run Programs Other Users Can Modify

HOST-CRON-001

Resolves the programs and scripts that system and root cron jobs run and checks whether any is world-writable or sits in a world-writable folder.

Why it matters. HOST-FS-005 protects the cron tables themselves, but a root job that runs /usr/local/bin/backup.sh is only as trustworthy as that file. If any user can edit the script, or replace it in a writable folder, their code runs as root at the next scheduled minute.

cron: Cron jobs run programs that other users can modify

0777 /usr/local/bin/backup.sh is world-writable
Fix
chmod o-w <program> and its folder; move scripts out of /tmp or user-writable folders into /usr/local/sbin owned by root; have cron run only files owned by root (chown root:root).
Verify
for p in $(awk '/^[^#]/ && NF>6 {print $7}' /etc/crontab /etc/cron.d/*); do stat -c '%a %U %n' $p; done
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, CWE-426, NIST 800-53 AC-3, AC-6, CM-5
References
crontab(5), Linux man-pages
MITRE ATT&CK T1053.003, Scheduled Task/Job: Cron
Learn
P20: Secrets, Cron and Account Hygiene (offline: openvapt learn P20)
Source
internal/checks/host/hygiene.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

World-Writable Directory in Cron's PATH

HOST-CRON-002

Checks the PATH that system cron jobs search for commands for world-writable or relative entries.

Why it matters. A cron job that calls backup-db rather than /usr/local/sbin/backup-db runs whichever file of that name PATH finds first. If a folder on that PATH is world-writable, or the PATH contains an empty or relative entry, any user can plant a program that root runs on schedule (PATH interception).

cron PATH: Cron's PATH can be hijacked

/etc/crontab: 0777 /opt/scripts is world-writable without the sticky bit
Fix
Remove the writable folder from PATH in /etc/crontab (or chmod o-w it), delete relative entries, and call programs in cron jobs by absolute path.
Verify
grep ^PATH /etc/crontab /etc/cron.d/* ; for d in $(grep ^PATH /etc/crontab | cut -d= -f2 | tr : ' '); do stat -c '%a %n' $d; done
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-426, CWE-427, NIST 800-53 CM-6, AC-6, CM-7
References
MITRE ATT&CK T1574.007, Hijack Execution Flow: Path Interception by PATH Environment Variable
crontab(5), Linux man-pages
Learn
P20: Secrets, Cron and Account Hygiene (offline: openvapt learn P20)
Source
internal/checks/host/hygiene.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Privileged or Host-Namespace Containers

HOST-CTR-003

Looks for containers running privileged, sharing the host's PID, network or IPC namespace, or with dangerous added capabilities.

Why it matters. A privileged container, or one with CAP_SYS_ADMIN or host namespaces, has almost no isolation: a compromise of the application inside is a compromise of the host.

containers: Containers with weak isolation

3f2a9c1d8e7b: privileged, pid=host, network=host, cap-add SYS_ADMIN
Fix
Recreate each container without --privileged, --pid=host, --net=host and --ipc=host; drop all capabilities and add back only the specific ones needed (--cap-drop=ALL --cap-add=...).
Verify
docker inspect --format '{{.Name}} {{.HostConfig.Privileged}} {{.HostConfig.PidMode}} {{.HostConfig.NetworkMode}} {{.HostConfig.CapAdd}}' $(docker ps -aq)
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Category
Secure Configuration
Effort
Medium
Confidence
High
Standards
CWE-250, CWE-653, NIST 800-53 AC-6, SC-39
References
NIST SP 800-190, Application Container Security Guide
OWASP Docker Security Cheat Sheet
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
Source
internal/checks/host/containers.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Containers Mount the Docker Socket or Host Root

HOST-CTR-004

Looks for containers that bind-mount the Docker socket, the host root filesystem or sensitive host paths.

Why it matters. A container with /var/run/docker.sock can control Docker and therefore the host. Mounting / or /etc gives direct write access to host configuration.

containers: Containers mount the Docker socket or sensitive host paths

3f2a9c1d8e7b: /var/run/docker.sock:/var/run/docker.sock
3f2a9c1d8e7b: /:/host
Fix
Remove these mounts. If a tool genuinely needs the Docker API, use a restricted socket proxy that allows only the required read-only calls.
Verify
docker inspect --format '{{.Name}} {{.HostConfig.Binds}}' $(docker ps -aq)
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Category
Access Control
Effort
Medium
Confidence
High
Standards
CWE-250, CWE-732, NIST 800-53 AC-6, SC-39
References
Docker documentation, Protect the Docker daemon socket
NIST SP 800-190, Application Container Security Guide
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
Source
internal/checks/host/containers.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Docker Socket Accessible to Non-Administrators

HOST-CTR-008

Checks the Docker socket's permissions and who belongs to the docker group.

Why it matters. Whoever can write to /var/run/docker.sock is root: one command starts a privileged container with the host's disk mounted. Members of the docker group have that power without sudo, logging or a password prompt, so the group should be empty or hold only administrators.

/var/run/docker.sock: Docker socket is reachable by non-administrators

/var/run/docker.sock mode 0666 is accessible to all users
docker group members (root-equivalent): deploy
Fix
chmod 660 /var/run/docker.sock && chown root:docker /var/run/docker.sock (the daemon recreates it with these defaults). Remove users from the docker group (gpasswd -d <user> docker) and give administrators sudo docker, or move to rootless Docker.
Verify
stat -c '%a %U:%G %n' /var/run/docker.sock ; getent group docker
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, CWE-250, NIST 800-53 AC-3, AC-6, CM-6
References
Docker documentation, Protect the Docker daemon socket
OWASP Docker Security Cheat Sheet
CIS Docker Benchmark (referenced by recommendation number)
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
A5: Container Runtime Hardening Depth (offline: openvapt learn A5)
Source
internal/checks/host/containers_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Seccomp or AppArmor Disabled for Containers

HOST-CTR-011

Looks for the daemon or individual containers turning off the default seccomp profile, AppArmor or SELinux labelling.

Why it matters. Docker's default seccomp profile blocks around 40 dangerous system calls and AppArmor or SELinux confines what a container's root can touch on the host. Running unconfined removes the main barriers between a compromised container and the kernel.

containers: Containers run without seccomp, AppArmor or SELinux confinement

daemon.json seccomp-profile is unconfined
3f2a9c1d8e7b: seccomp=unconfined, apparmor=unconfined
Fix
Remove --security-opt seccomp=unconfined and apparmor=unconfined from the container definitions and recreate them; if an application needs one extra system call, write a custom seccomp profile that adds only that call. Delete seccomp-profile from daemon.json.
Verify
docker inspect --format '{{.Name}} {{.HostConfig.SecurityOpt}}' $(docker ps -aq)
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Category
Secure Configuration
Effort
Medium
Confidence
High
Standards
CWE-653, CWE-250, NIST 800-53 AC-6, SC-39, CM-7
References
Docker documentation, Seccomp security profiles
Docker documentation, AppArmor security profiles
NIST SP 800-190, Application Container Security Guide
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
A5: Container Runtime Hardening Depth (offline: openvapt learn A5)
Source
internal/checks/host/containers_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

containerd Remote API or Podman Unconfined Defaults

HOST-CTR-014

Checks the containerd and Podman configuration files for a TCP API without TLS and for unconfined seccomp or disabled labelling defaults.

Why it matters. containerd's gRPC API is root on the host, like the Docker API; a tcp_address without TLS exposes it to the network. Podman's containers.conf sets the defaults every container inherits: an unconfined seccomp profile or disabled SELinux labelling removes the isolation for all of them.

/etc/containerd/config.toml: containerd listens on TCP without TLS

grpc tcp_address = 0.0.0.0:8888
Fix
containerd: remove tcp_address or set tcp_tls_cert and tcp_tls_key, then restart containerd. Podman: delete seccomp_profile = "unconfined", set label = true and apparmor_profile = "container-default" in containers.conf.
Verify
grep -E 'tcp_address|tcp_tls' /etc/containerd/config.toml ; grep -E 'seccomp_profile|^label|apparmor_profile' /etc/containers/containers.conf
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Secure Configuration
Effort
Medium
Confidence
High
Standards
CWE-306, CWE-1188, NIST 800-53 AC-3, SC-8, CM-6
References
containerd documentation, Operations (configuration)
containers.conf(5), Podman configuration
NIST SP 800-190, Application Container Security Guide
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
A5: Container Runtime Hardening Depth (offline: openvapt learn A5)
Source
internal/checks/host/containers_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Installed OS Packages With Known Vulnerabilities

HOST-CVE-001

Checks installed packages against an offline vulnerability snapshot.

Why it matters. Known vulnerable package versions can expose a server to documented attacks.

sudo: sudo 1.8.21p2-3ubuntu1.4: LAB-CVE-2021-3156 (CVE-2021-3156), fixed in 1.8.21p2-3ubuntu1.5, severity high

matcher: range
Snapshot date 2021-01-01. An outdated snapshot misses newer vulnerabilities.

policykit-1: policykit-1 0.105-20ubuntu0.18.04.5: LAB-CVE-2021-4034 (CVE-2021-4034), fixed in 0.105-20ubuntu0.18.04.6, severity high

matcher: range
Snapshot date 2021-01-01. An outdated snapshot misses newer vulnerabilities.
Fix
Install the vendor security update. For a source build, run 'make vulndb' to embed a snapshot generated from OSV and CISA KEV, then rebuild.
Verify
Re-run OpenVAPT after patching and confirm the finding is absent.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Patch and Vulnerability Management
Effort
Medium
Confidence
High
Standards
CWE-1104, OWASP A06:2021, NIST 800-53 SI-2, RA-5
References
OSV vulnerability database
NVD
CISA KEV
Learn
P10: Vulnerability Management: CVE, OSV and Known Exploited Vulnerabilities (offline: openvapt learn P10)
Source
internal/checks/host/cve.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Users With Root-Equivalent Docker Access

HOST-DKR-001

Checks whether non-root users can control Docker, which is equivalent to root access.

Why it matters. Members of the docker group, or anyone who can write to the Docker socket, can start a container that mounts the host filesystem and become root.

docker: Non-root users can control Docker (root equivalent)

docker group members: deploy
/var/run/docker.sock is world-writable (0666)
Fix
Remove users who do not need it from the docker group (gpasswd -d <user> docker); consider rootless Docker or Podman; keep docker.sock at 660 root:docker.
Verify
getent group docker ; stat -c '%a %U:%G' /var/run/docker.sock
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Category
Identity and Authentication
Effort
Medium
Confidence
High
Standards
CWE-250, CWE-266, NIST 800-53 AC-6
References
Docker documentation, Docker daemon attack surface
Learn
P7: Identity, Passwords and Privilege (offline: openvapt learn P7)
P9: Containers and Kubernetes (offline: openvapt learn P9)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Sensitive Account Files Have Unsafe Permissions

HOST-FS-001

Checks that /etc/shadow and /etc/gshadow are not readable by others, and /etc/passwd and /etc/group are not writable by others.

Why it matters. Readable shadow files let any local user (or a compromised web app) copy password hashes and crack them offline. Writable passwd/group files let them create a root account.

/etc/shadow: /etc/shadow is readable or writable by others

mode 0644

/etc/passwd: /etc/passwd is writable by group or others

mode 0666
Fix
chown root:root /etc/passwd /etc/group && chmod 644 /etc/passwd /etc/group ; chown root:shadow /etc/shadow /etc/gshadow && chmod 640 /etc/shadow /etc/gshadow (use root:root and 000 on RHEL-family systems).
Verify
stat -c '%a %U:%G %n' /etc/passwd /etc/group /etc/shadow /etc/gshadow
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, NIST 800-53 AC-3, AC-6
References
shadow(5), Linux man-pages
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/files.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Temporary Directory Missing the Sticky Bit

HOST-FS-002

Checks that world-writable temp directories have the sticky bit set.

Why it matters. Without the sticky bit any user can delete or replace other users' files in /tmp, enabling symlink attacks against root-run scripts.

/tmp: /tmp is world-writable without the sticky bit

mode 0777
Fix
chmod 1777 /tmp /var/tmp
Verify
stat -c '%a %n' /tmp /var/tmp should print 1777 for both.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-377, CWE-732, NIST 800-53 AC-3
References
chmod(1), Linux man-pages (restricted deletion flag)
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/files.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

World-Writable Files in System Configuration

HOST-FS-003

Looks for files under /etc and in cron directories that any user can modify.

Why it matters. A world-writable config or cron file lets any local user change how a root-owned service behaves, often leading straight to root.

/etc: World-writable files found

0666 /etc/passwd
0666 /etc/app/db.conf
0666 /etc/crontab
0666 /etc/ssh/sshd_config
0666 /etc/systemd/system/shop-api.service
Fix
For each listed file or directory: chmod o-w <path>. Then find out how it became writable (a deployment script or a careless chmod 777).
Verify
find /etc -xdev \( -type f -perm -0002 \) -o \( -type d -perm -0002 ! -perm -1000 \) should print nothing.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Category
Access Control
Effort
Medium
Confidence
High
Standards
CWE-732, NIST 800-53 AC-3, CM-6
References
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/files.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Unexpected SUID or SGID Programs

HOST-FS-004

Looks for set-user-ID or set-group-ID programs in places where packages do not normally install them.

Why it matters. A SUID program runs with its owner's rights (usually root). One placed in /tmp, /home, /var/www or /opt is a common persistence and privilege-escalation trick.

filesystem: SUID/SGID programs outside standard system paths

4755 /home/deploy/.cache/sh
Fix
Confirm whether each program is needed. Remove the bit with chmod u-s,g-s <file>, or delete the file if you did not put it there and investigate how it arrived.
Verify
find /tmp /home /var/www /opt /usr/local -xdev -perm /6000 -type f should print nothing unexpected.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Category
Access Control
Effort
Medium
Confidence
High
Standards
CWE-250, NIST 800-53 CM-7, AC-6
References
MITRE ATT&CK T1548.001, Setuid and Setgid
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/files.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Cron Files Writable by Non-Root Users

HOST-FS-005

Checks that system cron files and directories are owned by root and not writable by others.

Why it matters. Cron runs these jobs as root. Anyone who can edit them can run any command as root at the next scheduled minute.

cron: Cron paths can be modified by non-root users

0666 uid=0 /etc/crontab
Fix
chown root:root <path> && chmod go-w <path> for each listed path (600 for /etc/crontab is a common hardening choice).
Verify
stat -c '%a %U %n' /etc/crontab /etc/cron.*
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, NIST 800-53 AC-3, CM-6
References
crontab(5), Linux man-pages
MITRE ATT&CK T1053.003, Cron
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/files.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Private TLS Keys Readable by Others

HOST-FS-007

Checks that TLS private keys under the standard key directories are not readable by other users.

Why it matters. A stolen private key lets an attacker impersonate your websites and, with older key exchange, decrypt recorded traffic.

/etc/ssl/private/*: 1 file(s) are readable or writable by others

0644 /etc/ssl/private/shop.key
Fix
chown root:root <key> && chmod 600 <key> (or 640 with a dedicated group the web server runs in). Rotate any key that was exposed.
Verify
stat -c '%a %U:%G %n' /etc/ssl/private/* /etc/pki/tls/private/* /etc/letsencrypt/archive/*/privkey*.pem
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-732, NIST 800-53 AC-3, AC-6
References
OWASP Key Management Cheat Sheet
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Account Database Files or Their Backups Not Owned and Locked by Root

HOST-FS-022

Checks the owner and permissions of /etc/passwd, /etc/group, /etc/shadow, /etc/gshadow and their dash-suffixed backup copies.

Why it matters. The tools that edit accounts leave a backup copy (passwd-, shadow-) next to the live file. A readable shadow- backup leaks the same password hashes as shadow itself, and a file not owned by root can be rewritten by whoever owns it. HOST-FS-001 checks the mode of the live files; this check adds ownership and the backups.

/etc/passwd: 3 account file(s) have an unsafe owner or mode

0666 /etc/passwd (writable by group or others)
0644 /etc/shadow (accessible by others)
0644 /etc/shadow- (accessible by others)
Fix
chown root:root /etc/passwd /etc/passwd- /etc/group /etc/group- && chmod 644 /etc/passwd /etc/group && chmod 600 /etc/passwd- /etc/group- ; chown root:shadow /etc/shadow /etc/shadow- /etc/gshadow /etc/gshadow- && chmod 640 /etc/shadow /etc/gshadow && chmod 600 /etc/shadow- /etc/gshadow- (use root:root and mode 000 on RHEL family systems).
Verify
stat -c '%a %U:%G %n' /etc/passwd* /etc/group* /etc/shadow* /etc/gshadow*
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, CWE-522, NIST 800-53 AC-3, AC-6, IA-5
References
shadow(5), Linux man-pages
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/files_mounts.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Kubernetes Data Directory Accessible to Others

HOST-K8S-002

Checks that the etcd data directory is accessible only by its owner.

Why it matters. etcd stores every Kubernetes object, including Secrets, usually unencrypted at rest. Read access to its data directory exposes all cluster credentials.

/var/lib/etcd: etcd data directory is accessible by group or others

mode 0755
Fix
chmod 700 /var/lib/etcd && chown etcd:etcd /var/lib/etcd (or root:root for kubeadm static pods). Enable encryption at rest for Secrets.
Verify
stat -c '%a %U:%G %n' /var/lib/etcd
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, NIST 800-53 AC-3, SC-28
References
Kubernetes documentation, Operating etcd clusters for Kubernetes
Kubernetes documentation, Securing a cluster
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
Source
internal/checks/host/containers.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Kubernetes Credential Files Readable by Others

HOST-K8S-003

Checks that kubeconfig files and Kubernetes PKI private keys are not readable by other users.

Why it matters. admin.conf and the cluster CA key grant full control of the cluster; any local user who can read them becomes a cluster administrator.

/etc/kubernetes/admin.conf: 1 file(s) are readable or writable by group or others

0644 /etc/kubernetes/admin.conf
Fix
chmod 600 /etc/kubernetes/*.conf /etc/kubernetes/pki/*.key /etc/kubernetes/pki/etcd/*.key && chown root:root on each.
Verify
stat -c '%a %n' /etc/kubernetes/*.conf /etc/kubernetes/pki/*.key
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-732, NIST 800-53 AC-3, AC-6
References
Kubernetes documentation, Securing a cluster
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Operating System Past End of Security Support

HOST-OS-001

Checks whether the Linux distribution release still receives free security updates.

Why it matters. Once a release reaches end of life, newly discovered vulnerabilities are never fixed. Every later CVE in the kernel, OpenSSL or the web server stays open forever.

Ubuntu 18.04.6 LTS: Security support ended on 2023-05-31

Fix
Plan an upgrade to a supported release (for example do-release-upgrade on Ubuntu, or a fresh install and migration). Paid extended support (Ubuntu Pro, RHEL ELS) is an alternative while migrating.
Verify
cat /etc/os-release and compare with the vendor lifecycle page.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Patch and Vulnerability Management
Effort
High
Confidence
High
Standards
CWE-1104, OWASP A06:2021, NIST 800-53 SA-22, SI-2
References
Ubuntu release cycle
Debian releases and LTS
Red Hat Enterprise Linux life cycle
endoflife.date (community-maintained lifecycle data)
Learn
F3: Vulnerabilities, CVE, CWE and CVSS (offline: openvapt learn F3)
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/os_patch.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Security Updates Waiting to Be Installed

HOST-PKG-001

Checks the package manager for published security updates that are not installed yet.

Why it matters. Most real-world compromises use vulnerabilities for which a fix was already available. Pending security updates are known, public weaknesses.

apt: 2 security updates pending

openssl
sudo
Fix
Debian/Ubuntu: apt-get update && apt-get upgrade . RHEL family: dnf upgrade --security . Consider unattended-upgrades or dnf-automatic for security patches.
Verify
Re-run openvapt; this check should pass.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Patch and Vulnerability Management
Effort
Medium
Confidence
High
Standards
CWE-1104, OWASP A06:2021, NIST 800-53 SI-2, RA-5
References
NIST SP 800-40 Rev. 4, Guide to Enterprise Patch Management Planning
Debian, UnattendedUpgrades
Learn
F3: Vulnerabilities, CVE, CWE and CVSS (offline: openvapt learn F3)
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/os_patch.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Repository Signature Checks Disabled

HOST-PKG-002

Checks that the package manager verifies repository signatures, so a tampered mirror or intercepted download cannot install code as root.

Why it matters. Package installation runs as root. apt and dnf verify a signature over the repository index before trusting any package in it; an entry marked trusted=yes, AllowUnauthenticated or gpgcheck=0 switches that off, and a mirror operator or anyone on the network path can then deliver a modified package at the next update.

package repositories: Repository signature verification is disabled

/etc/apt/sources.list.d/lab-ppa.list: ppa.launchpadcontent.net marked trusted=yes (signature check off)
Fix
Remove trusted=yes (or Trusted: yes) from the listed source, install the repository's signing key under /etc/apt/keyrings and reference it with signed-by=; remove AllowUnauthenticated and AllowInsecureRepositories settings. On dnf and yum set gpgcheck=1 (and repo_gpgcheck=1 where supported) in each listed repository and import its key with rpm --import.
Verify
grep -r 'trusted=yes' /etc/apt/ ; grep -r 'gpgcheck=0' /etc/yum.repos.d/ /etc/dnf/dnf.conf 2>/dev/null
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Patch and Vulnerability Management
Effort
Low
Confidence
High
Standards
CWE-494, CWE-347, OWASP A08:2021, NIST 800-53 SI-7, CM-14, SR-3, SR-11
References
apt-secure(8), Debian manual pages
dnf.conf(5), Ubuntu noble manual pages (gpgcheck)
NIST SP 800-40 Rev. 4, Guide to Enterprise Patch Management Planning
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/pkg_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Secrets in World-Readable Files

HOST-SEC-001

Looks inside world-readable configuration files under /etc and the web roots for private keys, cloud access keys and password assignments.

Why it matters. A password or key in a file every local account can read is available to every website, service account and compromised process on the machine. Secrets found this way are the usual first step from a small web compromise to the database, the cloud account or root.

filesystem: 3 world-readable file(s) contain secrets

/etc/app/db.conf (mode 0666): credential assignment
/etc/backup/backup-key.pem (mode 0644): private key
/var/www/shop/.env (mode 0644): AWS access key id, credential assignment
Fix
chmod o-r each listed file (640 with the service's group, or 600). Move secrets into root-only files, systemd credentials or a secrets manager, and rotate every key or password that was readable.
Verify
find /etc /var/www -type f -perm -0004 -name '.env*' -o -type f -perm -0004 -name '*.key' then re-run this check.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
Category
Information Exposure
Effort
Medium
Confidence
High
Standards
CWE-312, CWE-732, CWE-798, OWASP A02:2021, A05:2021, NIST 800-53 IA-5, SC-28, AC-3
References
OWASP Secrets Management Cheat Sheet
NIST SP 800-53 Rev. 5, IA-5 Authenticator Management
NIST SP 800-123, Guide to General Server Security
Learn
P20: Secrets, Cron and Account Hygiene (offline: openvapt learn P20)
Source
internal/checks/host/hygiene.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

SSH Allows Direct Root Login

HOST-SSH-001

Checks whether the SSH daemon accepts logins as root with a password.

Why it matters. Root is the one account name every attacker knows. Allowing it over SSH turns any password guess into full control of the server, and removes the audit trail of which person used root.

sshd: Root may log in over SSH with a password

permitrootlogin yes
Fix
In /etc/ssh/sshd_config set: PermitRootLogin no (or prohibit-password if key-based root login is truly required). Log in as a named user and use sudo. Then run: sshd -t && systemctl reload sshd
Verify
sshd -T | grep -i permitrootlogin should print 'permitrootlogin no'.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-250, NIST 800-53 AC-6(2), IA-2
References
OpenBSD, sshd_config(5) manual page
NIST SP 800-123, Guide to General Server Security
Learn
P2: SSH Security (offline: openvapt learn P2)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
P23: Test Design for Security Checks (offline: openvapt learn P23)
A2: Remediation and Verification (offline: openvapt learn A2)
Source
internal/checks/host/ssh_root_login.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

SSH Host Private Keys Readable by Others

HOST-SSH-009

Checks that SSH host private keys are readable only by root.

Why it matters. Anyone who can read a host private key can impersonate the server and intercept SSH sessions from users who trust it.

/etc/ssh/ssh_host_*_key: 1 file(s) are readable or writable by others

0644 /etc/ssh/ssh_host_ed25519_key
Fix
chown root:root /etc/ssh/ssh_host_*_key && chmod 600 /etc/ssh/ssh_host_*_key (0640 with group ssh_keys is acceptable on RHEL family).
Verify
stat -c '%a %U:%G %n' /etc/ssh/ssh_host_*_key
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-732, NIST 800-53 AC-3, AC-6
References
OpenBSD, sshd_config(5) manual page
Learn
P2: SSH Security (offline: openvapt learn P2)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

SSH Server Configuration Writable by Non-Root Users

HOST-SSH-010

Checks that the SSH daemon configuration cannot be modified by group or other users.

Why it matters. Whoever can edit sshd_config can enable root login, add their own keys file location or weaken authentication.

/etc/ssh/sshd_config: 1 file(s) are writable by group or others

0666 /etc/ssh/sshd_config
Fix
chown root:root /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf && chmod 600 /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf
Verify
stat -c '%a %U %n' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, NIST 800-53 AC-3, AC-6
References
OpenBSD, sshd_config(5) manual page
Learn
P2: SSH Security (offline: openvapt learn P2)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Service Unit Files Writable by Non-Root Users

HOST-SYSD-003

Checks whether any systemd service unit or drop-in file can be changed by a user other than root.

Why it matters. systemd starts services as root by default. Whoever can edit a unit file can change ExecStart= or User= and have their own program run as root at the next restart or reboot, a well-known privilege escalation and persistence technique.

systemd units: Service unit files can be changed by non-root users

/etc/systemd/system/shop-api.service mode 0666 uid 0
Fix
chown root:root <file> && chmod 644 <file> for each listed file, then review its contents for changes you did not make (ExecStart=, User=, ExecStartPre=) and run systemctl daemon-reload.
Verify
stat -c '%U %a %n' /etc/systemd/system/*.service shows root and 644 (or stricter).
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, NIST 800-53 AC-3, CM-5
References
systemd.unit(5), unit configuration
MITRE ATT&CK T1543.002, Create or Modify System Process: Systemd Service
Learn
P11: Service Hardening With systemd (offline: openvapt learn P11)
Source
internal/checks/host/systemd.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Service Programs in Writable Locations

HOST-SYSD-004

Checks whether a service starts a program from a temporary folder, or a program file that other users can replace.

Why it matters. If the program a root service starts lives in /tmp or is writable by other users, any local user (or a compromised web application) can replace it and gain root the next time the service restarts.

systemd units: Services start programs that other users can replace

shop-worker.service: starts /tmp/shop-worker from a temporary folder
Fix
Install the program in a root-owned location (/usr/local/bin or /opt/<app>), chown root:root and chmod 755 it, point ExecStart= at it, then systemctl daemon-reload and restart the service.
Verify
stat -c '%U %a %n' $(systemctl show -p ExecStart --value <unit> | awk '{print $2}' | sed 's/path=//;s/;//')
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, CWE-427, NIST 800-53 AC-3, CM-5
References
systemd.exec(5), execution environment configuration
MITRE ATT&CK T1574.010, Hijack Execution Flow: Services File Permissions Weakness
Learn
P11: Service Hardening With systemd (offline: openvapt learn P11)
Source
internal/checks/host/systemd.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Extra Accounts With Root Privileges (UID 0)

HOST-USR-001

Checks /etc/passwd for accounts other than root that have user id 0.

Why it matters. Any account with UID 0 is root, whatever its name. Extra UID 0 accounts are a classic backdoor and bypass sudo logging.

/etc/passwd: Accounts other than root have UID 0

toor:x:0:0
Fix
Investigate who created each account. Remove it (userdel <name>) or give it a normal UID (usermod -u <new-uid> <name>). Grant admin rights through sudo instead.
Verify
awk -F: '$3==0' /etc/passwd should print only the root line.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Category
Identity and Authentication
Effort
Medium
Confidence
High
Standards
CWE-250, CWE-266, NIST 800-53 AC-2, AC-6
References
passwd(5), Linux man-pages
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P7: Identity, Passwords and Privilege (offline: openvapt learn P7)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/accounts.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Accounts Without a Password

HOST-USR-002

Checks /etc/shadow for accounts whose password field is empty.

Why it matters. An empty password field means the account can log in with no password at all on any service that allows password logins. The score uses a local attack vector: any local user can switch to the account (su) without a password, while the SSH daemon refuses empty passwords unless PermitEmptyPasswords is yes. If HOST-SSH-003 also fails, the same account is open from the network and should be treated as Critical.

/etc/shadow: Accounts have an empty password

deploy
Fix
For each listed user either set a password (passwd <user>) or lock the account (passwd -l <user>).
Verify
awk -F: '$2==""' /etc/shadow should print nothing.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-258, CWE-521, NIST 800-53 IA-5
References
shadow(5), Linux man-pages
Learn
P7: Identity, Passwords and Privilege (offline: openvapt learn P7)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/accounts.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Sudo Rules Without Password (NOPASSWD)

HOST-USR-003

Checks sudoers files for rules that grant root without asking for a password.

Why it matters. NOPASSWD means anyone who takes over that user (a stolen SSH key, a hijacked session, a web shell running as that user) becomes root instantly.

/etc/sudoers: Sudo rules grant root without a password

/etc/sudoers: deploy ALL=(ALL) NOPASSWD: ALL
Fix
Edit with visudo and remove NOPASSWD, or restrict it to one specific, harmless command for automation accounts.
Verify
grep -r NOPASSWD /etc/sudoers /etc/sudoers.d should print nothing, or only narrowly scoped commands.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-306, NIST 800-53 AC-6, IA-11
References
sudoers(5) manual
Learn
F1: Security Basics (offline: openvapt learn F1)
P7: Identity, Passwords and Privilege (offline: openvapt learn P7)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/accounts.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Insecure Trust Files in Home Directories

HOST-USR-007

Looks for .rhosts, .shosts and .netrc files in user home directories.

Why it matters. .rhosts and .shosts grant password-less trust to other hosts. .netrc files usually hold plain-text passwords for FTP or other services.

home directories: Insecure trust or credential files found

/home/deploy/.netrc
Fix
Delete .rhosts and .shosts files. Replace .netrc credentials with a secret manager or key-based authentication, then delete the file and rotate the passwords it contained.
Verify
Re-run this check; no files should be listed.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-256, CWE-290, NIST 800-53 IA-5, CM-6
References
MITRE ATT&CK T1552.001, Unsecured Credentials: Credentials In Files
Learn
P7: Identity, Passwords and Privilege (offline: openvapt learn P7)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/passwords.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

AI Model Server or Dashboard Reachable From the Network

NET-AI-001

Checks whether a self-hosted AI model server, AI web interface, AI cluster dashboard or vector database listens on a network-reachable address.

Why it matters. Many self-hosted AI tools have no login enabled by default. Reached from the network, anyone can use the models and the computing power, read stored documents and embeddings, pull or delete models, and on some dashboards submit jobs that run code.

sockets: AI services are network-reachable

tcp6 [::]:11434 Ollama model API, bound to all interfaces
a web server listens on port 80 or 443 on this machine: bind the application to 127.0.0.1 and publish it through that proxy
Fix
Bind each service to 127.0.0.1 (Ollama: OLLAMA_HOST=127.0.0.1:11434 in its service environment; Ray: --dashboard-host=127.0.0.1; Gradio: server_name="127.0.0.1"), and if others need it, publish it only through a reverse proxy with authentication and TLS.
Verify
ss -tlnp shows these ports on 127.0.0.1 or ::1 only.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:L
Category
Network Exposure
Effort
Low
Confidence
High
Standards
CWE-306, CWE-1327, OWASP A05:2021, A07:2021, NIST 800-53 SC-7, CM-7, AC-3
References
Ollama FAQ, How do I configure Ollama server?
Ray documentation, Security
OWASP Top 10 for Large Language Model Applications
Learn
P24: Securing Self-Hosted AI Services (offline: openvapt learn P24)
Source
internal/checks/network/ai_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Jupyter Configuration Weakens Authentication

NET-AI-002

Checks whether a Jupyter configuration blanks the login token without setting a password, or turns off cross-site request protection.

Why it matters. Jupyter runs any code typed into it with the rights of the account that started it. With the token blanked and no password, anyone who can reach the port, or any local user, gets that account. With XSRF checks off, a web page a user visits can send it commands.

/etc/jupyter/jupyter_server_config.py: Jupyter configuration weakens authentication or request forgery protection

token is an empty string and no login password is set, so anyone who reaches the server can run code
disable_check_xsrf = True: other websites can send requests to the server through a visitor's browser
Fix
Remove the empty token line so Jupyter generates a random token, or set a password with jupyter server password . Remove disable_check_xsrf = True. Bind to 127.0.0.1 and reach it through an SSH tunnel.
Verify
grep -nE 'token|password|disable_check_xsrf' <config file> shows no empty token and no disabled XSRF check, and the server log prints a URL with a token at start-up.
CVSS v3.1
CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-306, CWE-352, OWASP A07:2021, A05:2021, NIST 800-53 IA-2, AC-3
References
Jupyter Server documentation, Security in the Jupyter Server
Learn
P24: Securing Self-Hosted AI Services (offline: openvapt learn P24)
Source
internal/checks/network/ai_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Debugger or Application Control Ports Exposed

NET-APP-001

Checks whether the Node.js inspector, Tomcat AJP or shutdown port, PHP-FPM FastCGI or Jupyter listen on network-reachable addresses.

Why it matters. These ports are not web pages: the Node.js inspector and Jupyter run code for whoever connects, Tomcat AJP has been abused for file read and code execution (Ghostcat), the shutdown port stops the server, and PHP-FPM executes scripts handed to it. None of them is designed to face a network.

sockets: Debugger or application control ports are network-reachable

tcp 0.0.0.0:8009 Tomcat AJP connector, bound to all interfaces
tcp 0.0.0.0:9229 Node.js inspector (debugger), bound to all interfaces
a web server listens on port 80 or 443 on this machine: bind the application to 127.0.0.1 and publish it through that proxy
Fix
Bind each to 127.0.0.1 or a Unix socket (node --inspect=127.0.0.1:9229; Tomcat Connector address="127.0.0.1" or remove the AJP connector; PHP-FPM listen = /run/php/php-fpm.sock; jupyter --ip=127.0.0.1) and never expose a debugger.
Verify
ss -tlnp shows these ports on 127.0.0.1 or ::1 only.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:L
Category
Network Exposure
Effort
Low
Confidence
High
Standards
CWE-489, CWE-1327, OWASP A05:2021, NIST 800-53 SC-7, CM-7
References
Node.js, Inspector security implications
Apache Tomcat 9, AJP Connector
Learn
P13: Application Servers: Tomcat, Node.js and Python (offline: openvapt learn P13)
Source
internal/checks/network/firewall_exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Database or Cache Service Exposed to the Network

NET-DB-001

Checks whether databases, caches, search engines or the Docker API listen on a network-reachable address.

Why it matters. Exposed databases and caches (Redis, MongoDB, Elasticsearch, Memcached) are among the most common causes of mass data breaches and ransom wipes, often because they ship without authentication.

sockets: Data services listen on network-reachable addresses

tcp 0.0.0.0:3306 MySQL/MariaDB
tcp 0.0.0.0:6379 Redis
Fix
Bind the service to 127.0.0.1 (MySQL: bind-address = 127.0.0.1; Redis: bind 127.0.0.1 ::1 and protected-mode yes; MongoDB: net.bindIp: 127.0.0.1) and restart it. Caution: confirm first that no application on another machine connects to it, or that application loses its database. If remote access is needed, allow only specific source IPs in the firewall and require TLS and authentication.
Verify
ss -tlnp | grep -E ':(3306|5432|6379|27017|9200|11211)' should show only 127.0.0.1 or ::1.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Data Services
Effort
Low
Confidence
High
Standards
CWE-1327, CWE-306, OWASP A05:2021, NIST 800-53 SC-7, CM-7
References
OWASP Database Security Cheat Sheet
Redis security
Learn
F1: Security Basics (offline: openvapt learn F1)
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
Source
internal/checks/network/listeners.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

MySQL or MariaDB Unsafe Network Options

NET-DB-005

MySQL or MariaDB enables local file loading, skips grants, or listens broadly with networking enabled.

Why it matters. These options can bypass authorization, expand file access, or expose the database to untrusted networks.

/etc/mysql/mysql.conf.d/mysqld.cnf: MySQL or MariaDB enables local file loading, skips grants, or listens broadly with networking enabled.

/etc/mysql/mysql.conf.d/mysqld.cnf: local_infile = ON
/etc/mysql/mysql.conf.d/mysqld.cnf: skip-grant-tables = 
/etc/mysql/mysql.conf.d/mysqld.cnf: skip-networking = OFF
/etc/mysql/mysql.conf.d/mysqld.cnf: bind-address = 0.0.0.0
Fix
Disable local_infile and skip-grant-tables. Bind to 127.0.0.1 or enable skip-networking when TCP access is unnecessary.
Verify
Inspect SHOW VARIABLES through an approved administrator session and confirm the listening address locally.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Data Services
Effort
Low
Confidence
High
Standards
CWE-306, CWE-1188, OWASP A05:2021, NIST 800-53 AC-3, CM-6, SC-7
References
MySQL Server Security Guidelines
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
Source
internal/checks/network/data_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Memcached UDP or Broad Listen Address

NET-DB-006

Memcached enables UDP or listens on a non-loopback address.

Why it matters. Unauthenticated Memcached exposure can disclose cached data and UDP mode has been abused for amplification attacks.

/etc/memcached.conf: Memcached enables UDP or listens on a non-loopback address.

/etc/memcached.conf: -l 0.0.0.0
/etc/memcached.conf: -U 11211
Fix
Set UDP_PORT=0 or -U 0 and bind with -l 127.0.0.1. Use a firewall for any explicitly required clients.
Verify
Confirm ss -ltnup shows Memcached only on loopback and no UDP port 11211.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Data Services
Effort
Low
Confidence
High
Standards
CWE-406, CWE-1188, OWASP A05:2021, NIST 800-53 SC-5, CM-6, SC-7
References
memcached Configuration
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
Source
internal/checks/network/data_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Unsafe NFS Export Options

NET-DB-008

NFS exports are world-accessible or use no_root_squash or insecure.

Why it matters. These export options can grant untrusted clients filesystem access or preserve remote root privileges.

/etc/exports: NFS exports are world-accessible or use no_root_squash or insecure.

/srv/share *(rw,no_root_squash,insecure)
Fix
Restrict every export to explicit client CIDRs, use root_squash, remove insecure, and reload exports.
Verify
Run exportfs -v during approved administration and confirm only intended networks and safe options appear.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Data Services
Effort
Low
Confidence
High
Standards
CWE-732, CWE-306, OWASP A05:2021, NIST 800-53 AC-3, CM-6, SC-7
References
Linux exports(5)
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
Source
internal/checks/network/services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Unsafe Samba Guest or SMB1 Configuration

NET-DB-009

Samba permits guest access, maps unknown users to guest, or allows SMB1.

Why it matters. Guest shares weaken accountability, while SMB1 lacks modern protocol protections and has a long history of severe flaws.

/etc/samba/smb.conf: Samba permits guest access, maps unknown users to guest, or allows SMB1.

guest ok enabled
unknown users map to guest
SMB1 NT1 enabled
Fix
Set guest ok = no, map to guest = Never, and server min protocol = SMB2_02 or newer. Review each share ACL.
Verify
Run testparm -s during approved administration and confirm the effective values.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Data Services
Effort
Low
Confidence
High
Standards
CWE-732, CWE-306, OWASP A05:2021, NIST 800-53 AC-3, CM-6, SC-7
References
Samba smb.conf Manual
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
Source
internal/checks/network/services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

BIND Open Recursion

NET-DB-010

BIND enables recursion without restricting recursive clients.

Why it matters. An open recursive resolver can be abused for reflection attacks and permits outsiders to consume resolver resources.

/etc/bind/named.conf.options: BIND enables recursion without restricting recursive clients.

recursion yes without a client ACL
Fix
Disable recursion on authoritative-only servers, or set allow-recursion and allow-query-cache to explicit trusted networks.
Verify
Run named-checkconf and query recursion from an untrusted test network under an approved test plan.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:H
Category
Data Services
Effort
Low
Confidence
High
Standards
CWE-406, OWASP A05:2021, NIST 800-53 SC-5, CM-6, SC-7
References
BIND 9 Administrator Reference Manual - Access Control
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
Source
internal/checks/network/services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

BIND Zone Transfers Allowed to Any

NET-DB-011

BIND permits zone transfers to any client.

Why it matters. Unrestricted transfers disclose the complete DNS namespace and provide attackers with a detailed target inventory.

/etc/bind/named.conf.options: BIND permits zone transfers to any client.

allow-transfer includes any
Fix
Set allow-transfer to none or explicit secondary server addresses, preferably protected with TSIG.
Verify
Run named-checkconf and verify AXFR is refused from an unauthorized test host.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Data Services
Effort
Low
Confidence
High
Standards
CWE-497, OWASP A05:2021, NIST 800-53 AC-3, CM-6, SC-7
References
BIND 9 Administrator Reference Manual - allow-transfer
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
Source
internal/checks/network/services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Postfix Open Relay Controls

NET-DB-012

Postfix relay restrictions are missing or mynetworks trusts overly broad ranges.

Why it matters. An open relay enables spam and phishing, damages domain reputation, and can expose the host to blocklisting.

/etc/postfix/main.cf: Postfix relay restrictions are missing or mynetworks trusts overly broad ranges.

reject_unauth_destination missing
mynetworks trusts all addresses
Fix
Set smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination and narrow mynetworks.
Verify
Run postconf -n during approved administration and perform only an authorized relay test.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:L
Category
Data Services
Effort
Low
Confidence
High
Standards
CWE-441, OWASP A05:2021, NIST 800-53 AC-3, CM-6, SC-7
References
Postfix SMTP Relay and Access Control
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
Source
internal/checks/network/services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

IPv6 Listeners Without IPv6 Firewall

NET-FW-002

Network-reachable IPv6 listeners exist without a default-deny IPv6 firewall policy.

Why it matters. An IPv4-only firewall does not protect IPv6 services, creating an alternate path that bypasses intended filtering.

IPv6 firewall: IPv6 listeners exist but ip6tables input policy is not deny

Fix
Apply equivalent default-deny filtering for IPv6 with nftables or ip6tables and explicitly allow required services. Caution: allow SSH and ICMPv6 neighbour discovery and router messages before applying the default deny, or remote IPv6 sessions and IPv6 connectivity are cut.
Verify
Run ip6tables -S and nft list ruleset, then confirm the input chain has a default drop or reject policy.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Network Exposure
Effort
Medium
Confidence
High
Standards
CWE-923, NIST 800-53 SC-7
References
NIST SP 800-119, Guidelines for the Secure Deployment of IPv6
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
Source
internal/checks/network/network_controls.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Firewall Allows Sensitive Services From Anywhere

NET-FW-003

Checks whether the host firewall explicitly opens a listening database, administrative or application server port to every address on the internet.

Why it matters. A default-deny firewall only protects what it does not allow. A single "allow 3306 from anywhere" rule, often added while debugging, makes a database or admin panel as exposed as if there were no firewall at all.

firewall: Sensitive services are open to every address

tcp 0.0.0.0:3306 (MySQL/MariaDB) allowed from anywhere by iptables rule: -A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT
Fix
Delete the rule or restrict it to the addresses that need it, for example: ufw delete allow 3306 && ufw allow from 203.0.113.10 to any port 3306 proto tcp . Better, bind the service to 127.0.0.1 and reach it through an SSH tunnel or VPN.
Verify
ufw status numbered or nft list ruleset shows no rule opening that port to Anywhere.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Network Exposure
Effort
Low
Confidence
High
Standards
CWE-923, CWE-1327, OWASP A05:2021, NIST 800-53 SC-7, AC-4, CM-7
References
NIST SP 800-41 Rev. 1, Guidelines on Firewalls and Firewall Policy
ufw(8) manual (Ubuntu)
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P12: Firewall Policy Versus What Is Listening (offline: openvapt learn P12)
Source
internal/checks/network/firewall_exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Cleartext Legacy Services Listening

NET-SVC-001

Checks for Telnet, FTP, rsh/rlogin, TFTP, plain POP3/IMAP/LDAP, SNMP v1/v2c and rsync daemons on network-reachable addresses.

Why it matters. These protocols send passwords and data unencrypted, so anyone on the path can read or alter them. Most also have weak or no authentication.

sockets: Cleartext services are network-reachable

tcp 0.0.0.0:21 FTP
udp 0.0.0.0:161 SNMP (v1/v2c community strings)
Fix
Replace with encrypted equivalents: SSH/SFTP instead of Telnet/FTP/rsh, IMAPS (993)/POP3S (995), LDAPS (636), SNMPv3. Disable the old service: systemctl disable --now <unit>.
Verify
ss -tulpn should not show ports 21, 23, 69, 110, 143, 161, 389, 512-514 or 873 on public addresses.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
Category
Network Exposure
Effort
Medium
Confidence
High
Standards
CWE-319, OWASP A02:2021, NIST 800-53 SC-8, CM-7
References
NIST SP 800-123, Guide to General Server Security
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
Source
internal/checks/network/listeners.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Network Time Service Amplification Risk

NET-SVC-003

NTP or chrony serves broad clients or permits legacy monitoring commands that can amplify traffic.

Why it matters. Internet-reachable time services with broad client access or legacy mode 6 or 7 controls can be abused for reflection and amplification.

/etc/ntp.conf: Time service access controls allow amplification-prone queries

Fix
Bind the time daemon to required interfaces, restrict clients to explicit networks, disable monitoring, and use noquery or equivalent controls.
Verify
Confirm UDP port 123 is filtered from untrusted networks and review the daemon's effective access restrictions.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Category
Network Exposure
Effort
Low
Confidence
High
Standards
CWE-406, NIST 800-53 SC-5, SC-7
References
CISA Alert TA14-013A, NTP Amplification Attacks Using CVE-2013-5211
chrony Documentation - Access Control
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
Source
internal/checks/network/network_controls.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Apache Allows TLS 1.0 or 1.1

WEB-APA-005

SSLProtocol permits SSLv3, TLSv1 or TLSv1.1, or is not set on a TLS-enabled server (the default all -SSLv3 allows TLS 1.0 and 1.1).

Why it matters. TLS 1.0 and 1.1 are deprecated by RFC 8996 and lack the protections of TLS 1.2 and 1.3. Apache's default still allows them, so an explicit SSLProtocol is required. The directive is not the last word: mod_ssl uses the system OpenSSL, and when its configuration already sets a floor of TLS 1.2 (MinProtocol in openssl.cnf on Debian 12 and Ubuntu 22.04 and later, or a crypto policy of DEFAULT, FUTURE or FIPS on the RHEL family) the old versions cannot be negotiated whatever the directive lists. In that case the check reports Pass and names the floor, because rating a server High for a line that has no effect would contradict the live handshake checks (WEB-TLS). The directive is still worth tidying so the configuration says what it does.

/etc/apache2/apache2.conf: SSLProtocol permits SSLv3, TLSv1 or TLSv1.1, or is not set on a TLS-enabled server (the default all -SSLv3 allows TLS 1.0 and 1.1).

/etc/apache2/mods-enabled/ssl.conf: SSLProtocol all -SSLv2 (allows sslv3, tlsv1, tlsv1.1)
Fix
Set SSLProtocol -all +TLSv1.2 +TLSv1.3 (Mozilla intermediate) in mods-enabled/ssl.conf or ssl.conf, then apachectl configtest and reload.
Verify
openssl s_client -connect 127.0.0.1:443 -servername <site> -tls1_1 should fail to connect.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-326, CWE-327, OWASP A02:2021, ASVS 9.1.3, NIST 800-53 SC-8, SC-13
References
Apache HTTP Server, SSLProtocol directive
Mozilla, Server Side TLS guidelines
NIST SP 800-52 Rev. 2, Guidelines for TLS Implementations
OpenSSL, config(5): system default TLS settings (MinProtocol)
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Apache Cipher Suite Includes Weak Suites

WEB-APA-006

SSLCipherSuite includes NULL, export, DES or 3DES, RC4, MD5, anonymous or other legacy suites, or SSLHonorCipherOrder forces a legacy order.

Why it matters. Weak suites allow recorded traffic to be decrypted or sessions to be hijacked. The Mozilla guidelines give a short explicit list that modern clients all support.

/etc/apache2/apache2.conf: SSLCipherSuite includes NULL, export, DES or 3DES, RC4, MD5, anonymous or other legacy suites, or SSLHonorCipherOrder forces a legacy order.

/etc/apache2/mods-enabled/ssl.conf: weak tokens all, rc4-sha
SSLHonorCipherOrder on (Mozilla recommends off for modern and intermediate profiles)
Fix
Use the Mozilla intermediate list for SSLCipherSuite and set SSLHonorCipherOrder off , as the Mozilla SSL Configuration Generator produces for Apache.
Verify
Run the nmap ssl-enum-ciphers script against 127.0.0.1 port 443 under your own test plan; it should list only grade A suites.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-327, OWASP A02:2021, ASVS 9.1.2, NIST 800-53 SC-8, SC-13
References
Mozilla SSL Configuration Generator
Apache HTTP Server, SSLCipherSuite directive
RFC 7525, Recommendations for Secure Use of TLS and DTLS
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Laravel Debug Mode On or Application Key Missing

WEB-APP-001

Checks Laravel .env files for APP_DEBUG=true or an empty APP_KEY.

Why it matters. With APP_DEBUG on, Laravel's error page prints the environment, including database and mail passwords, to any visitor who triggers an error. APP_KEY encrypts sessions and cookies; with it empty or default the application refuses to run or signs nothing.

/srv/shop-laravel/.env: Laravel runs in debug mode or without an application key

APP_DEBUG is true
APP_KEY is empty
Fix
Set APP_DEBUG=false and APP_ENV=production in .env, run php artisan key:generate if APP_KEY is empty, then php artisan config:cache. Keep .env outside the web root (Laravel's public/ folder) and readable only by the application user.
Verify
grep -E '^APP_(DEBUG|KEY)=' .env shows APP_DEBUG=false and a base64 key.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-489, CWE-209, CWE-321, OWASP A05:2021, ASVS 14.3.2, 2.10.4, NIST 800-53 CM-6, SI-11, IA-5
References
Laravel documentation, Deployment
Laravel documentation, Configuration (debug mode, environment files)
OWASP ASVS 4.0.3, V14 Configuration
Learn
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/frameworks.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Symfony Running in the Development Environment

WEB-APP-003

Checks Symfony .env files for APP_ENV=dev or APP_DEBUG=1.

Why it matters. The dev environment enables the web profiler and debug toolbar, which show requests, queries, configuration, the container and sometimes credentials to any visitor, and it skips the caches that production relies on.

/srv/shop-crm/.env: Symfony runs in the development environment

APP_ENV is dev
APP_DEBUG is on
Fix
Set APP_ENV=prod and APP_DEBUG=0 in .env (or .env.local), run composer dump-env prod, clear the cache (php bin/console cache:clear) and remove the web profiler bundle from production.
Verify
php bin/console about shows Environment prod and Debug false.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-489, CWE-215, OWASP A05:2021, ASVS 14.3.2, NIST 800-53 CM-6, SI-11
References
Symfony documentation, Configuring Symfony (environments)
Symfony documentation, How to Deploy a Symfony Application
OWASP ASVS 4.0.3, V14 Configuration
Learn
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/frameworks.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Rails Master Key or Secrets File Exposed

WEB-APP-004

Checks Rails config/master.key, credentials key files and secrets.yml for world-read permissions or a location inside a web root.

Why it matters. master.key decrypts credentials.yml.enc, which holds every production secret, and secrets.yml holds the secret_key_base that signs sessions. Anyone who reads them can forge sessions and read the database password. Both are meant to stay out of version control and out of any public folder.

/srv/shop-rails/config/master.key: Rails key or secrets file is exposed

mode 0644 is readable by all users
Fix
chmod 600 config/master.key config/credentials/*.key; keep them out of git (.gitignore) and out of public/; load the key from RAILS_MASTER_KEY in the environment on servers. Rotate the credentials if the key was ever exposed.
Verify
stat -c '%a %n' config/master.key shows 600, and git ls-files config/master.key prints nothing.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, CWE-312, CWE-321, OWASP A02:2021, A05:2021, ASVS 2.10.4, 14.1.3, NIST 800-53 AC-3, SC-28, IA-5
References
Ruby on Rails Guides, Securing Rails Applications
Ruby on Rails Guides, Custom Credentials
OWASP Secrets Management Cheat Sheet
Learn
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/frameworks.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Spring Boot Actuator Endpoints Fully Exposed

WEB-APP-006

Checks Spring Boot application properties for management.endpoints.web.exposure.include=* and probes the local site for an open /actuator/env.

Why it matters. Actuator's env, configprops, heapdump and threaddump endpoints print environment variables, configuration (including credentials) and process memory. Exposing them all over HTTP without authentication is one of the most common Java application leaks.

/opt/shop-api/application.properties: Spring Boot actuator endpoints are fully exposed

management.endpoints.web.exposure.include exposes sensitive actuator endpoints on the application port
Fix
Set management.endpoints.web.exposure.include=health,info (and exclude env,heapdump,configprops), move management.server.port to a port that is not published, and require authentication for every actuator endpoint with Spring Security.
Verify
curl -s -o /dev/null -w '%{http_code}' https://<site>/actuator/env prints 401, 403 or 404.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-306, CWE-497, OWASP A05:2021, A01:2021, ASVS 14.3.2, 4.3.2, NIST 800-53 CM-7, AC-3, SI-11
References
Spring Boot documentation, Actuator endpoints
Spring Boot documentation, Securing HTTP endpoints
OWASP WSTG-CONF-02, Test Application Platform Configuration
Learn
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/frameworks.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

CMS Configuration Readable by All Users

WEB-CMS-004

Checks whether wp-config.php, Joomla configuration.php or Drupal settings.php can be read by every local user.

Why it matters. These files hold the database password and the keys that sign logins. If every account on the machine can read them, any other site, user or compromised process on the server can take over the CMS and its data.

/var/www/shop/wp-config.php: CMS configuration is readable by all users

WordPress configuration has mode 0666 (readable by all users)

/var/www/shop/configuration.php: CMS configuration is readable by all users

Joomla configuration has mode 0644 (readable by all users)

/var/www/shop/sites/default/settings.php: CMS configuration is readable by all users

Drupal configuration has mode 0664 (readable by all users)
Fix
chmod 640 <file> and chown it to the site owner with the web server's group (for example chown deploy:www-data wp-config.php); on PHP-FPM pools that run as the site user, 600 or 400 also works. Rotate the database password if other people have shell access.
Verify
stat -c '%a %U:%G %n' <file> shows 640, 600 or 400.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, CWE-260, OWASP A05:2021, NIST 800-53 AC-3, SC-28
References
WordPress Developer Resources, Hardening WordPress
Drupal.org, Securing file permissions and ownership
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
Source
internal/checks/web/cms_more.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

CMS Configuration Writable by Other Users

WEB-CMS-005

Checks whether wp-config.php, Joomla configuration.php or Drupal settings.php is group- or world-writable.

Why it matters. These files are PHP code that runs on every request. Whoever can write them can add a backdoor that runs as the web server, which is how many shared-hosting compromises spread from one site to the next.

/var/www/shop/wp-config.php: CMS configuration is writable by other users

WordPress configuration has mode 0666 (writable by group or others)

/var/www/shop/sites/default/settings.php: CMS configuration is writable by other users

Drupal configuration has mode 0664 (writable by group or others)
Fix
chmod 640 (or 440) <file>. Drupal also expects sites/default to be 555 after installation. Review the file for code you did not add.
Verify
stat -c '%a %n' <file> shows no write bit for group or others.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, OWASP A05:2021, NIST 800-53 AC-3, CM-5
References
WordPress Developer Resources, Hardening WordPress
Drupal.org, Securing file permissions and ownership
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
Source
internal/checks/web/cms_more.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Drupal Core Past End of Life

WEB-CMS-012

Reads the installed Drupal core version from disk and compares its major release with the Drupal security coverage dates.

Why it matters. Drupal 7, 8 and 9 no longer receive security advisories from the Drupal Security Team. Drupalgeddon (CVE-2014-3704) and Drupalgeddon 2 (CVE-2018-7600) showed how quickly unpatched Drupal sites are taken over at scale.

/var/www/shop: Drupal 8 reached end of life on 2020-11-02

Fix
Upgrade to a supported Drupal major with composer (drupal/core-recommended), run drush updatedb and test the site; for Drupal 7, migrate with the Migrate module or commission a rebuild.
Verify
drush status --field=drupal-version or grep VERSION core/lib/Drupal.php
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Patch and Vulnerability Management
Effort
High
Confidence
High
Standards
CWE-1104, OWASP A06:2021, ASVS 14.2.1, NIST 800-53 SI-2, SA-22
References
Drupal.org, Drupal core release cycle and end of life
NVD, CVE-2018-7600
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/cms_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Joomla Core Past End of Life

WEB-CMS-014

Reads the installed Joomla version from administrator/manifests/files/joomla.xml on disk and compares it with the Joomla support dates.

Why it matters. Joomla 3 left security support in August 2023 and Joomla 4 in October 2025. Sites on those series receive no fixes for new core vulnerabilities, while the exact version remains easy to fingerprint.

/var/www/shop: Joomla 3.9 left security support on 2023-08-17

Fix
Update to the current Joomla series through the Joomla Update component (back up first, check extension compatibility, then update), and keep the one-click updater enabled.
Verify
grep '<version>' administrator/manifests/files/joomla.xml
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Patch and Vulnerability Management
Effort
High
Confidence
High
Standards
CWE-1104, OWASP A06:2021, ASVS 14.2.1, NIST 800-53 SI-2, SA-22
References
Joomla Documentation, Joomla Release and Support Cycle
Joomla Documentation, Security Checklist
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/cms_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Drupal update.php Open Without Authentication

WEB-CMS-019

Checks Drupal settings.php for $settings['update_free_access'] = TRUE.

Why it matters. update_free_access lets anyone run update.php, which executes database update hooks as the site. It exists for one-off maintenance and Drupal's own status report warns when it is left on.

/var/www/shop/sites/intranet/settings.php: Drupal update.php runs without authentication

$settings['update_free_access'] is TRUE
Fix
Set $settings['update_free_access'] = FALSE; in settings.php (the default) and run updates as user 1 or with drush updatedb.
Verify
grep update_free_access sites/default/settings.php shows FALSE.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:H
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-306, OWASP A01:2021, A05:2021, ASVS 4.3.2, NIST 800-53 AC-3, CM-6
References
Drupal.org, Running update.php (update_free_access)
Drupal.org, Securing file permissions and ownership
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/cms_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Vulnerable Web Application Libraries

WEB-CVE-001

Matches local web library versions against offline OSV advisories; WordPress core is inventoried and reported Incomplete because OSV publishes no WordPress feed.

Why it matters. Unpatched web libraries can expose users and server data to known vulnerabilities.

jquery: jquery 3.4.1: LAB-CVE-2020-11022 (CVE-2020-11022), severity high

matcher: range
source: /var/www/shop/package-lock.json
Snapshot date 2021-01-01. An outdated snapshot misses newer vulnerabilities.

rack: rack 2.2.3: LAB-CVE-2022-30123 (CVE-2022-30123), severity critical

matcher: range
source: /var/www/shop/admin/Gemfile.lock
Snapshot date 2021-01-01. An outdated snapshot misses newer vulnerabilities.

wordpress: wordpress 5.2.1: LAB-CVE-2019-17671 (CVE-2019-17671), severity high

matcher: range
source: /var/www/shop/wp-includes/version.php
Snapshot date 2021-01-01. An outdated snapshot misses newer vulnerabilities.

flask: flask 2.0.1: LAB-CVE-2023-30861 (CVE-2023-30861), severity high

matcher: range
source: /var/www/shop/api/requirements.txt
Snapshot date 2021-01-01. An outdated snapshot misses newer vulnerabilities.
Fix
Update the affected library or WordPress core and deploy a refreshed lockfile or asset. For a source build, run 'make vulndb' to embed a generated snapshot.
Verify
Re-run OpenVAPT and verify that the vulnerable version is no longer deployed.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Patch and Vulnerability Management
Effort
Medium
Confidence
High
Standards
CWE-1104, OWASP A06:2021, ASVS 14.2.1, NIST 800-53 SI-2, RA-5
References
OSV
OSV schema, defined ecosystems (WordPress)
NVD
Learn
P10: Vulnerability Management: CVE, OSV and Known Exploited Vulnerabilities (offline: openvapt learn P10)
A7: Security Testing in Agile Teams and CI (offline: openvapt learn A7)
Source
internal/checks/web/cve.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Secrets or Backups Stored Inside a Web Root

WEB-DOC-001

Looks on disk inside each web document root for environment files, database dumps, backups, archives and private keys.

Why it matters. Anything inside a document root may be downloadable, now or after a configuration change. Dumps, backups and keys there are a leading cause of data breaches; finding them on disk catches files the URL checks cannot guess.

/var/www/shop: 2 sensitive file(s) inside the web root

/var/www/shop/backup.sql (database dump)
/var/www/shop/.env (environment secrets)
Fix
Move each listed file outside the document root (for example to a 700 folder in the account's home), delete what is not needed, and rotate any secret or key that was exposed. Keep backups in a dedicated location outside every web root.
Verify
Re-run this check; no files should be listed.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-530, CWE-538, CWE-312, OWASP A05:2021, ASVS 12.5.1, NIST 800-53 SC-28, CM-6
References
OWASP WSTG-CONF-04, Review Old Backup and Unreferenced Files for Sensitive Information
OWASP Secrets Management Cheat Sheet
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/docroot.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Web Root Files Writable by Other Users

WEB-DOC-002

Looks for world-writable files inside web document roots.

Why it matters. A world-writable PHP or HTML file lets any local user, or any other compromised site on the same server, plant a web shell or inject malware into pages served to visitors.

/var/www/shop: 2 world-writable file(s) in the web root

0666 /var/www/shop/wp-config.php
0666 /var/www/shop/index.php
Fix
chmod o-w <file> for each listed file (find <docroot> -type f -perm -0002 -exec chmod o-w {} +). Use 644 for files and 755 for folders, owned by the site account, and grant the web server write access only to upload folders.
Verify
find <docroot> -type f -perm -0002 should print nothing.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, OWASP A05:2021, NIST 800-53 AC-3, AC-6
References
OWASP WSTG-CONF-09, Test File Permission
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/docroot.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Git Repository Exposed on the Website

WEB-EXP-001

Checks whether the .git folder can be downloaded from each site.

Why it matters. An exposed .git folder lets anyone rebuild the full source code and history, often including passwords, API keys and database credentials committed by mistake.

shop.example.test: Exposed: /.git/HEAD (HTTP 200)

/.git/HEAD (HTTP 200)
Fix
Block dot-folders in the web server (Apache: RedirectMatch 404 /\.git ; nginx: location ~ /\.(?!well-known) { deny all; }) and deploy without the .git folder in the web root. Rotate any secret that was ever committed.
Verify
curl -s -o /dev/null -w '%{http_code}' https://<site>/.git/HEAD should print 403 or 404.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-527, CWE-538, OWASP A05:2021, ASVS 12.5.1, NIST 800-53 CM-7, SC-28
References
OWASP WSTG, Review Old Backup and Unreferenced Files (WSTG-CONF-04)
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Backup or Database Dump Files Downloadable

WEB-EXP-004

Checks for common backup archives and SQL dumps left in the web root.

Why it matters. Backups contain the whole site and often the whole database, including customer data and password hashes.

shop.example.test: Exposed: /db.sql (HTTP 200)

/db.sql (HTTP 200)
Fix
Move backups outside the web root (for example /home/<user>/deploy-backups/ with mode 700), delete the exposed copies and treat their contents as leaked.
Verify
curl -s -o /dev/null -w '%{http_code}' https://<site>/backup.zip should print 404.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-530, OWASP A05:2021, ASVS 12.5.1, NIST 800-53 CM-7, SC-28
References
OWASP WSTG-CONF-04, Review Old Backup and Unreferenced Files
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Other Version Control Metadata Exposed

WEB-EXP-007

Checks for exposed Subversion, Mercurial and Bazaar metadata folders.

Why it matters. Like .git, these folders let anyone reconstruct source code and history, including secrets that were committed by mistake.

shop.example.test: Exposed: /.svn/entries (HTTP 200)

/.svn/entries (HTTP 200)
Fix
Block dot-folders at the web server and deploy without version control metadata in the web root. Rotate any secret ever committed.
Verify
curl -s -o /dev/null -w '%{http_code}' https://<site>/.svn/entries should print 403 or 404.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-527, OWASP A05:2021, ASVS 12.5.1, NIST 800-53 CM-7, SC-28
References
OWASP WSTG-CONF-04, Review Old Backup and Unreferenced Files for Sensitive Information
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Log Files Downloadable From the Website

WEB-EXP-008

Checks for application and debug logs published under the web root.

Why it matters. Logs expose file paths, SQL queries, user data, session identifiers and sometimes credentials or API keys.

shop.example.test: Exposed: /wp-content/debug.log (HTTP 200)

/wp-content/debug.log (HTTP 200)
Fix
Move logs outside the web root, deny access to *.log at the web server, disable WP_DEBUG_LOG in production, and review the exposed logs for leaked secrets.
Verify
curl -s -o /dev/null -w '%{http_code}' https://<site>/wp-content/debug.log should print 403 or 404.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-532, CWE-538, OWASP A09:2021, A05:2021, ASVS 12.5.1, NIST 800-53 CM-7, SC-28
References
OWASP WSTG-CONF-04, Review Old Backup and Unreferenced Files for Sensitive Information
OWASP Logging Cheat Sheet
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Framework Debug Pages Exposed

WEB-EXP-012

Checks for development debug tools and verbose error pages left enabled in production.

Why it matters. Debug pages such as the Symfony profiler, Laravel's Whoops/Ignition pages or Django's debug 404 reveal source code, configuration, environment variables and sometimes allow code execution.

shop.example.test: Exposed: /_profiler/ (HTTP 200)

/_profiler/ (HTTP 200)
Fix
Disable debug mode in production (APP_DEBUG=false, DEBUG = False, APP_ENV=prod), remove profiler routes, and show generic error pages.
Verify
Re-run this check; no debug pages should be detected.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-489, CWE-209, OWASP A05:2021, ASVS 14.3.2, 7.4.1, NIST 800-53 CM-7, SI-11
References
OWASP WSTG-ERRH-01, Testing for Improper Error Handling
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

nginx Allows TLS 1.0 or 1.1

WEB-NGX-003

ssl_protocols lists SSLv3, TLSv1 or TLSv1.1, or is not set on a TLS-enabled server, so the allowed version depends on the nginx build.

Why it matters. TLS 1.0 and 1.1 are deprecated by RFC 8996 and lack the protections of TLS 1.2 and 1.3. Clients that negotiate them are exposed to downgrade and known cipher weaknesses. The directive is not the last word: nginx uses the system OpenSSL, and when its configuration already sets a floor of TLS 1.2 (MinProtocol in openssl.cnf on Debian 12 and Ubuntu 22.04 and later, or a crypto policy of DEFAULT, FUTURE or FIPS on the RHEL family) the old versions cannot be negotiated whatever the directive lists. In that case the check reports Pass and names the floor, because rating a server High for a line that has no effect would contradict the live handshake checks (WEB-TLS). The directive is still worth tidying so the configuration says what it does.

/etc/nginx/nginx.conf: ssl_protocols lists SSLv3, TLSv1 or TLSv1.1, or is not set on a TLS-enabled server, so the allowed version depends on the nginx build.

/etc/nginx/nginx.conf: ssl_protocols TLSv1 TLSv1.1 TLSv1.2 (allows tlsv1, tlsv1.1)
Fix
Set ssl_protocols TLSv1.2 TLSv1.3; in the http block (the Mozilla intermediate profile), run nginx -t and reload.
Verify
openssl s_client -connect 127.0.0.1:443 -servername <site> -tls1_1 should fail to connect.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-326, CWE-327, OWASP A02:2021, ASVS 9.1.3, NIST 800-53 SC-8, SC-13
References
nginx documentation, ngx_http_ssl_module
Mozilla, Server Side TLS guidelines
NIST SP 800-52 Rev. 2, Guidelines for TLS Implementations
RFC 8996, Deprecating TLS 1.0 and TLS 1.1
OpenSSL, config(5): system default TLS settings (MinProtocol)
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

nginx Cipher List Includes Weak Suites

WEB-NGX-004

ssl_ciphers includes NULL, export, DES or 3DES, RC4, MD5, anonymous or other legacy suites, or ssl_prefer_server_ciphers forces a legacy order.

Why it matters. Weak suites allow recorded traffic to be decrypted or sessions to be hijacked. Modern clients already prefer strong suites, so the Mozilla guidelines recommend a short explicit list and ssl_prefer_server_ciphers off.

/etc/nginx/nginx.conf: ssl_ciphers includes NULL, export, DES or 3DES, RC4, MD5, anonymous or other legacy suites, or ssl_prefer_server_ciphers forces a legacy order.

/etc/nginx/nginx.conf: weak tokens all, rc4-sha, des-cbc3-sha
ssl_prefer_server_ciphers on (Mozilla recommends off for modern and intermediate profiles)
Fix
Use the Mozilla intermediate list, for example ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305; and ssl_prefer_server_ciphers off;
Verify
Run the nmap ssl-enum-ciphers script against 127.0.0.1 port 443 under your own test plan; it should list only grade A suites.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-327, OWASP A02:2021, ASVS 9.1.2, NIST 800-53 SC-8, SC-13
References
Mozilla SSL Configuration Generator
Mozilla, Server Side TLS guidelines
RFC 7525, Recommendations for Secure Use of TLS and DTLS
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Node.js Version Past End of Life

WEB-NODE-001

Checks whether the installed Node.js runtime is a release line that no longer receives security fixes.

Why it matters. After end of life the Node.js project publishes no more security releases, so every later vulnerability in the runtime, its bundled OpenSSL or its HTTP parser stays open for good.

node: Node.js v18.19.1 reached end of life on 2025-04-30

Fix
Move to an Active or Maintenance LTS release (even-numbered majors), for example with the NodeSource or distribution packages, test the application, then restart its service.
Verify
node --version shows a supported LTS major.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Patch and Vulnerability Management
Effort
High
Confidence
High
Standards
CWE-1104, OWASP A06:2021, ASVS 14.2.1, NIST 800-53 SI-2, SA-22
References
Node.js Release Working Group, release schedule
endoflife.date, Node.js (community-maintained lifecycle data)
Learn
P13: Application Servers: Tomcat, Node.js and Python (offline: openvapt learn P13)
Source
internal/checks/web/runtimes.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

PHP Allows Remote File Inclusion

WEB-PHP-003

Checks whether include() and require() may load code from URLs.

Why it matters. With allow_url_include on, a single file-inclusion bug lets an attacker run their own PHP code from their own server (remote file inclusion).

php: allow_url_include = 1

Fix
In php.ini set allow_url_include = Off (the default since PHP 5.2) and restart PHP.
Verify
php -r "echo ini_get('allow_url_include');" and check the FPM pool's php.ini or php_admin_value settings.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-98, OWASP A03:2021, A05:2021, ASVS 12.3.3, NIST 800-53 CM-6, CM-7
References
PHP manual, php.ini directives
OWASP PHP Configuration Cheat Sheet
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/php.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

PHP Version Past End of Security Support

WEB-PHP-004

Checks whether the installed PHP branch still receives security fixes from the PHP project.

Why it matters. Unsupported PHP versions never get fixes for newly found vulnerabilities, some of which allow remote code execution.

php: PHP 7.2 security support ended on 2020-11-30

Check whether your distribution backports security fixes to this version
Fix
Upgrade to a supported PHP branch (see php.net/supported-versions) and test the applications, or confirm your distribution still backports security fixes to this version.
Verify
php -v
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Patch and Vulnerability Management
Effort
High
Confidence
High
Standards
CWE-1104, OWASP A06:2021, ASVS 14.2.1, NIST 800-53 SI-2
References
PHP, Supported Versions
Learn
F3: Vulnerabilities, CVE, CWE and CVSS (offline: openvapt learn F3)
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/php.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Django Debug Mode Enabled

WEB-PY-001

Checks Django settings files for DEBUG = True with no production override.

Why it matters. With DEBUG on, every error page shows source code, local variables, SQL queries and most settings, and Django keeps every SQL query in memory. Attackers trigger errors on purpose to read them.

/srv/shopadmin/shopadmin: Django debug mode is on

/srv/shopadmin/shopadmin/settings.py: DEBUG = True
Fix
Set DEBUG = False in production, preferably from the environment (DEBUG = os.environ.get('DJANGO_DEBUG') == '1'), set ALLOWED_HOSTS, and restart the application. Run python manage.py check --deploy.
Verify
python manage.py check --deploy reports no DEBUG warning.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-489, CWE-215, OWASP A05:2021, ASVS 14.3.2, NIST 800-53 CM-6
References
Django documentation, Deployment checklist
Django settings reference, DEBUG
Learn
P13: Application Servers: Tomcat, Node.js and Python (offline: openvapt learn P13)
Source
internal/checks/web/runtimes.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Django Uses the Generated Development Secret Key

WEB-PY-003

Checks Django settings for a SECRET_KEY that starts with django-insecure-, the marker of the key generated by startproject.

Why it matters. SECRET_KEY signs sessions, password-reset tokens and other data. The generated key sits in source files that are usually copied into repositories and backups; anyone who has it can forge signed data and, with some session backends, take over accounts.

/srv/shopadmin/shopadmin: Django uses the generated development SECRET_KEY

/srv/shopadmin/shopadmin/settings.py: uses the generated django-insecure SECRET_KEY
Fix
Generate a new key (python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'), load it from the environment or a root-readable file (SECRET_KEY = os.environ['DJANGO_SECRET_KEY']), and restart. Changing the key logs all users out.
Verify
python manage.py check --deploy reports no SECRET_KEY warning.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-798, CWE-321, OWASP A02:2021, A05:2021, ASVS 2.10.4, NIST 800-53 IA-5, SC-12
References
Django documentation, Deployment checklist
Django settings reference, SECRET_KEY
Learn
P13: Application Servers: Tomcat, Node.js and Python (offline: openvapt learn P13)
Source
internal/checks/web/runtimes.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

HIGH

Tomcat Manager Reachable Without Address Restriction

WEB-TOM-001

Checks whether the Tomcat Manager or Host Manager application is deployed without an address filter limiting it to localhost.

Why it matters. The Manager deploys WAR files, which means it runs any code it is given. Exposed to the network it is one stolen or guessed password away from full compromise, and it is a standard target of automated attacks.

/etc/tomcat9: Tomcat Manager is deployed without an address restriction

/usr/share/tomcat9-admin/manager is deployed with no RemoteAddrValve or RemoteCIDRValve restriction
Fix
If you do not use them, delete the manager and host-manager folders (or apt remove tomcatN-admin). Otherwise keep the default valve in META-INF/context.xml: <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" /> and reach the Manager through an SSH tunnel.
Verify
grep -A2 RemoteAddrValve <webapps>/manager/META-INF/context.xml
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Web Application Security
Effort
Low
Confidence
High
Standards
CWE-1188, CWE-923, OWASP A01:2021, A05:2021, NIST 800-53 AC-3, CM-7
References
Apache Tomcat 10.1, Security Considerations
Apache Tomcat 10.1, Manager App How-To
Learn
P13: Application Servers: Tomcat, Node.js and Python (offline: openvapt learn P13)
Source
internal/checks/web/tomcat.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Boot Loader Has No Password

HOST-BOOT-001

Checks that GRUB is configured with a superuser and a hashed password so the boot entries cannot be edited at the console.

Why it matters. Without a boot loader password anyone at the console or virtual console can edit the kernel command line (for example add init=/bin/bash) and get a root shell without any credentials, bypassing every control on the running system.

/boot/grub: No superuser or password directive in 1 GRUB file(s)

Fix
Run grub-mkpasswd-pbkdf2 (grub2-setpassword on RHEL family), add set superusers="admin" and password_pbkdf2 admin <hash> to /etc/grub.d/40_custom (RHEL family writes /boot/grub2/user.cfg), then regenerate with update-grub or grub2-mkconfig -o /boot/grub2/grub.cfg. Add --unrestricted to the normal menu entry so unattended reboots still work.
Verify
grep -E 'set superusers|password_pbkdf2' /boot/grub/grub.cfg /boot/grub2/grub.cfg /boot/grub2/user.cfg /etc/grub.d/* 2>/dev/null | sed 's/grub.pbkdf2.*/<hash>/'
CVSS v3.1
CVSS:3.1/AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Access Control
Effort
Medium
Confidence
High
Standards
CWE-306, NIST 800-53 AC-3, AC-6, CM-6
References
GNU GRUB Manual, Security
NIST SP 800-123, Guide to General Server Security
Learn
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/boot.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

UEFI Secure Boot Disabled

HOST-BOOT-002

Checks the firmware's SecureBoot variable to see whether the boot chain is verified.

Why it matters. Secure Boot makes the firmware refuse unsigned boot loaders and kernels, which blocks boot kits and unsigned kernels planted by an attacker with disk or console access. Without it, anything written to the boot partition runs at the next reboot.

/sys/firmware/efi/efivars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c: Secure Boot is disabled

SecureBoot = 0
Fix
Enable Secure Boot in the firmware set-up and boot a signed shim and kernel (every mainstream distribution ships them). Custom kernels and out-of-tree modules then need signing with a Machine Owner Key. Where the platform cannot do Secure Boot, record the exception. Caution: unsigned kernels and modules (for example DKMS drivers such as NVIDIA or ZFS) stop loading once it is on, so sign or replace them first and keep console access for the first boot.
Verify
mokutil --sb-state or od -An -t u1 /sys/firmware/efi/efivars/SecureBoot-* (the fifth byte is 1 when enabled).
CVSS v3.1
CVSS:3.1/AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Category
Secure Configuration
Effort
High
Confidence
High
Standards
CWE-1326, NIST 800-53 SI-7, CM-6
References
UEFI Specification, Secure Boot and Driver Signing
NIST SP 800-123, Guide to General Server Security
Learn
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/boot.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Uncommon Filesystem Modules Not Disabled

HOST-BOOT-003

Checks that the cramfs, freevxfs, jffs2, hfs, hfsplus, udf and squashfs kernel modules are disabled in modprobe.d.

Why it matters. Each filesystem driver is kernel code that parses untrusted data. A local user who can mount removable media or a loop device gets the kernel to parse a crafted image with one of these rarely maintained drivers, and several have had memory-corruption bugs. Removing drivers nobody uses removes that attack surface.

/etc/modprobe.d: Filesystem modules not disabled: cramfs, freevxfs, jffs2, hfs, hfsplus, udf, squashfs

Fix
Create /etc/modprobe.d/openvapt-filesystems.conf with, for each module: install <module> /bin/false and blacklist <module> then unload any loaded one with modprobe -r <module>. Caution: first confirm that no listed module is in use (lsmod, findmnt); blocking a filesystem a mount or package format needs (for example squashfs for snap packages, or vfat for the EFI system partition) breaks those mounts at the next boot.
Verify
for m in cramfs freevxfs jffs2 hfs hfsplus udf squashfs; do modprobe -n -v $m; lsmod | grep -w $m; done
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:L
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, NIST 800-53 CM-7, CM-6
References
modprobe.d(5), Linux man-pages
Kernel Self Protection Project, Recommended Settings
Learn
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/boot.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

USB Storage Driver Not Disabled

HOST-BOOT-004

Checks that the usb-storage kernel module is disabled in modprobe.d on servers that do not need removable media.

Why it matters. A USB stick plugged into a server is the simplest way to copy data out or bring malware in without touching the network. Disabling the driver makes the device invisible to the kernel.

/etc/modprobe.d: usb-storage is not disabled in modprobe.d

Fix
Create /etc/modprobe.d/openvapt-usb.conf containing install usb-storage /bin/false and blacklist usb-storage then modprobe -r usb-storage. Servers that need USB backups should record the exception instead.
Verify
modprobe -n -v usb-storage should print install /bin/false; lsmod | grep usb_storage should print nothing.
CVSS v3.1
CVSS:3.1/AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, NIST 800-53 MP-7, CM-7
References
modprobe.d(5), Linux man-pages
MITRE ATT&CK T1091, Replication Through Removable Media
Learn
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/boot.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

No File Integrity Monitoring

HOST-BOOT-006

Checks that a file integrity tool (AIDE, Tripwire, Samhain or equivalent) is installed and scheduled to run.

Why it matters. After a compromise the first question is which files changed. Without a baseline and a scheduled comparison, a replaced binary, an added SUID file or an edited PAM stack stays invisible for months.

integrity: No file integrity tool found (AIDE, Tripwire, Samhain, osquery or OSSEC)

Fix
Install AIDE (apt install aide / dnf install aide), initialise the database with aideinit or aide --init, move the new database into place, and enable the daily check (dailyaidecheck.timer on Debian family, or a cron.daily entry) that mails or logs the differences.
Verify
aide --check (or your tool's check command) runs and reports; systemctl list-timers | grep -i aide or ls /etc/cron.daily | grep -i aide
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U/C:N/I:H/A:N
Category
Logging and Monitoring
Effort
Medium
Confidence
High
Standards
CWE-778, NIST 800-53 SI-7, CM-3
References
AIDE, Advanced Intrusion Detection Environment
NIST SP 800-53 Rev. 5, Security and Privacy Controls
NIST SP 800-123, Guide to General Server Security
Learn
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/boot.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Docker Daemon Not Hardened

HOST-CTR-002

Checks the Docker daemon defaults: no-new-privileges, inter-container communication, user namespace remapping and live restore.

Why it matters. Hardened daemon defaults limit what a compromised container can do: no-new-privileges blocks setuid escalation, disabling icc isolates containers, and user namespaces map container root to an unprivileged host user.

/etc/docker/daemon.json: Docker daemon hardening options are missing

no-new-privileges is not true
icc is not false
userns-remap is not set
live-restore is not true
Fix
Add to /etc/docker/daemon.json: "no-new-privileges": true, "icc": false, "userns-remap": "default", "live-restore": true then restart Docker after testing your containers.
Verify
cat /etc/docker/daemon.json ; docker info | grep -Ei 'security|userns'
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:L
Category
Secure Configuration
Effort
Medium
Confidence
High
Standards
CWE-250, CWE-1188, NIST 800-53 CM-6, AC-6
References
Docker documentation, Docker Engine security
NIST SP 800-190, Application Container Security Guide
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
Source
internal/checks/host/containers.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Docker Daemon Allows Insecure Registries or Debug Features

HOST-CTR-010

Checks daemon.json for insecure-registries, debug mode and experimental features.

Why it matters. An insecure registry is pulled over plain HTTP or with an unverified certificate, so anyone on the path can swap the image for a malicious one. Debug logging and experimental features widen the daemon's attack surface and leak internal detail into logs.

docker daemon: Docker daemon allows insecure registries or debug features

daemon.json insecure-registries: registry.example.test:5000
daemon.json debug is true
daemon.json experimental is true
Fix
Remove insecure-registries (serve the registry over TLS with a trusted certificate, or add its CA to /etc/docker/certs.d/<registry>/ca.crt), set "debug": false and "experimental": false in daemon.json, and remove any --insecure-registry, --debug (-D) or --experimental flag from the dockerd ExecStart in docker.service drop-ins (then systemctl daemon-reload). Restart Docker in a maintenance window: running containers stop unless live-restore is on.
Verify
docker info | grep -Ei 'insecure|debug|experimental'
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-494, CWE-1188, NIST 800-53 SI-7, CM-7
References
Docker documentation, dockerd daemon reference
NIST SP 800-190, Application Container Security Guide
CIS Docker Benchmark (referenced by recommendation number)
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
A5: Container Runtime Hardening Depth (offline: openvapt learn A5)
Source
internal/checks/host/containers_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Containers Run Without Memory or Process Limits

HOST-CTR-012

Looks for containers with no memory limit and no PID limit.

Why it matters. A container with no limits can use all the host's memory or fork until the kernel runs out of process slots, taking the host and every neighbour down (a fork bomb or a memory leak is enough). Limits turn that into a problem for one container.

containers: Containers have neither a memory nor a PID limit

3f2a9c1d8e7b: no memory limit, no PID limit
Fix
Recreate each container with --memory (for example 512m) and --pids-limit (for example 256), or set them in the compose file under deploy.resources.limits / pids_limit.
Verify
docker inspect --format '{{.Name}} mem={{.HostConfig.Memory}} pids={{.HostConfig.PidsLimit}}' $(docker ps -aq)
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
Category
Secure Configuration
Effort
Medium
Confidence
High
Standards
CWE-770, NIST 800-53 SC-6, SC-5
References
Docker documentation, Resource constraints
NIST SP 800-190, Application Container Security Guide
CIS Docker Benchmark (referenced by recommendation number)
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
A5: Container Runtime Hardening Depth (offline: openvapt learn A5)
Source
internal/checks/host/containers_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Containers Run as Root With a Writable Root Filesystem

HOST-CTR-013

Looks for containers whose process runs as root and whose root filesystem is writable.

Why it matters. Root inside the container is the first half of most container escapes, and a writable root filesystem lets an attacker install tools and persist. A non-root user plus --read-only with a few tmpfs mounts removes both at once for most services.

containers: Containers run as root on a writable root filesystem

3f2a9c1d8e7b: runs as root with a writable root filesystem
Fix
Add USER <uid> to the image or run with --user 1000:1000, and start the container with --read-only plus --tmpfs /tmp for scratch space; recreate the container.
Verify
docker inspect --format '{{.Name}} user={{.Config.User}} ro={{.HostConfig.ReadonlyRootfs}}' $(docker ps -aq)
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L
Category
Secure Configuration
Effort
Medium
Confidence
High
Standards
CWE-250, CWE-732, NIST 800-53 AC-6, CM-7
References
OWASP Docker Security Cheat Sheet
NIST SP 800-190, Application Container Security Guide
CIS Docker Benchmark (referenced by recommendation number)
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
A5: Container Runtime Hardening Depth (offline: openvapt learn A5)
Source
internal/checks/host/containers_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Boot Loader Configuration Exposed

HOST-FS-006

Checks that the GRUB configuration is not readable or writable by normal users.

Why it matters. The boot loader configuration controls kernel parameters at boot. If writable, it allows boot-time privilege escalation; if readable, it may expose a boot password hash.

/boot/grub/grub.cfg: 1 file(s) are accessible by group or others

0644 /boot/grub/grub.cfg
Fix
chown root:root <grub.cfg> && chmod 600 <grub.cfg> (for example /boot/grub/grub.cfg or /boot/grub2/grub.cfg).
Verify
stat -c '%a %U %n' /boot/grub/grub.cfg /boot/grub2/grub.cfg
CVSS v3.1
CVSS:3.1/AV:P/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, NIST 800-53 AC-3, AC-6
References
GNU GRUB Manual, Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

World-Writable Files Outside Temporary Directories

HOST-FS-014

Looks for files that any user can modify in program, service and home locations other than /etc (which HOST-FS-003 covers).

Why it matters. A world-writable script, binary or data file lets any local account, including a compromised web application, change what other users and services run or read.

filesystem: 4 world-writable file(s) found

0666 /srv/app/upload.sh
0666 /var/www/shop/index.php
0666 /var/www/shop/wp-config.php
0777 /usr/local/bin/backup.sh
Fix
For each listed file: chmod o-w <path>. Then find the deployment step or chmod 777 habit that created it.
Verify
find /usr/local /opt /srv /var/www /home /usr/bin /usr/sbin -xdev -type f -perm -0002 should print nothing.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:N
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, NIST 800-53 AC-3, AC-6, CM-6
References
NIST SP 800-123, Guide to General Server Security
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/files_mounts.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

SUID or SGID Programs Outside the Known Baseline

HOST-FS-016

Lists set-user-ID and set-group-ID programs in the system binary directories that are not on the documented baseline of what distributions ship.

Why it matters. Every SUID program is a door into another account, usually root. Programs such as nmap, vim, find, python or a custom helper with the SUID bit are a known route to instant root; the fewer unexplained SUID programs, the smaller that door.

filesystem: 1 SUID/SGID program(s) are not on the baseline

4755 /usr/bin/nmap
Fix
For each listed program decide whether the bit is needed. Remove it with chmod u-s,g-s <path> or uninstall the package. Record the ones you keep so the next review is quick. Caution: programs such as passwd, sudo, su, mount and ping need their bit to work for normal users; removing it from those breaks password changes and administrator access.
Verify
find /bin /sbin /usr/bin /usr/sbin /usr/libexec /usr/lib -xdev -type f -perm /6000 and compare with your record.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N
Category
Access Control
Effort
Medium
Confidence
High
Standards
CWE-250, NIST 800-53 AC-6, CM-7
References
MITRE ATT&CK T1548.001, Setuid and Setgid
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/files_mounts.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

World-Writable Directories Without the Sticky Bit

HOST-FS-017

Looks for shared writable directories outside /tmp and /etc that let any user delete or replace other users' files.

Why it matters. In a world-writable directory without the sticky bit, any user can remove or swap a file placed there by another user or by a service, which turns upload folders and spool directories into file-replacement attacks.

filesystem: 4 shared directory(ies) lack the sticky bit

0777 /opt/scripts/ (directory, no sticky bit)
0777 /srv/shop-laravel/bootstrap/cache/ (directory, no sticky bit)
0777 /srv/shop-laravel/storage/ (directory, no sticky bit)
0777 /var/www/uploads/ (directory, no sticky bit)
Fix
chmod +t <dir> for directories that must stay shared, or chmod o-w <dir> for those that should not be writable by everyone.
Verify
find /var /home /opt /srv /usr/local -xdev -type d -perm -0002 ! -perm -1000 should print nothing.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:N
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, CWE-377, NIST 800-53 AC-3, CM-6
References
chmod(1), Linux man-pages (restricted deletion flag)
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/files_mounts.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Address Space Layout Randomisation Not Fully Enabled

HOST-KRN-001

Checks that the kernel randomises memory layout for stack, libraries, heap and VDSO.

Why it matters. ASLR makes memory-corruption exploits much harder because attackers cannot predict where code lives.

kernel.randomize_va_space: kernel.randomize_va_space = 0 (hardened value: 2)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.randomize_va_space = 2 then apply with: sysctl --system
Verify
sysctl kernel.randomize_va_space should print 2.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-344, NIST 800-53 CM-6, SI-16
References
Linux kernel documentation, /proc/sys/kernel
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Unprivileged eBPF Allowed

HOST-KRN-009

Checks that normal users cannot load eBPF programs into the kernel.

Why it matters. Unprivileged eBPF has been the entry point for many local privilege-escalation bugs.

kernel.unprivileged_bpf_disabled: kernel.unprivileged_bpf_disabled = 0 (hardened value: 1)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.unprivileged_bpf_disabled = 1 then apply with: sysctl --system
Verify
sysctl kernel.unprivileged_bpf_disabled should print 1.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:L
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-749, NIST 800-53 CM-6, SI-16
References
Linux kernel documentation, /proc/sys/kernel
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Root PATH Contains Unsafe Entries

HOST-PAM-008

Checks that the PATH set for root does not include the current directory, empty entries, relative paths or directories other users can write to.

Why it matters. When root's PATH contains . or an empty element, typing ls in a directory an attacker controls runs the attacker's ls as root. A world-writable directory on the PATH has the same effect for every command name that is not found earlier. This is one of the oldest Unix privilege escalations and still common in copied dotfiles.

root PATH: Root's PATH contains unsafe entries

/root/.bashrc: entry . (current directory)
/root/.bashrc: empty entry (trailing colon) means the current directory
Fix
Edit the listed file so PATH holds only absolute, root-owned directories, for example PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" , remove any . or trailing colon, and chmod o-w any listed directory. Log out and in again.
Verify
sudo -i sh -c 'echo $PATH' should show no . or empty element; ls -ld $(echo $PATH | tr : ' ')
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:R/S:U/C:H/I:H/A:H
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-426, CWE-427, NIST 800-53 CM-6, AC-6
References
MITRE ATT&CK T1574.007, Hijack Execution Flow: Path Interception by PATH Environment Variable
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/pam_login.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Running Kernel Older Than Installed Kernel

HOST-PKG-005

Checks that the kernel in memory is the newest kernel installed, so kernel security fixes are actually in effect.

Why it matters. A kernel update protects nothing until the machine boots into it. The package manager reports the update as installed, so the gap is invisible unless the running version is compared with the installed one. HOST-UPD-002 reads the Debian reboot marker; this check works on every distribution by comparing versions.

kernel: Running kernel 4.15.0-100-generic is older than installed kernel 4.15.0-150-generic; a reboot is needed

Fix
Schedule a maintenance window and reboot into the newest kernel. Where downtime is a problem, use the distribution's live patching service and still plan regular reboots.
Verify
uname -r should match the newest version in dpkg -l 'linux-image-*' | grep ^ii or rpm -q kernel-core .
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:L
Category
Patch and Vulnerability Management
Effort
Medium
Confidence
High
Standards
CWE-1104, OWASP A06:2021, NIST 800-53 SI-2, RA-5
References
NIST SP 800-40 Rev. 4, Guide to Enterprise Patch Management Planning
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/pkg_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Weak Password Hashing Algorithm Configured

HOST-PWD-001

Checks that new passwords are hashed with a modern, slow algorithm (SHA-512 or yescrypt).

Why it matters. If the shadow file ever leaks, fast or obsolete hashes such as MD5 or DES can be cracked in minutes. Slow, salted algorithms make offline cracking far more expensive.

/etc/login.defs: ENCRYPT_METHOD MD5 is weak

Fix
Set ENCRYPT_METHOD YESCRYPT (or SHA512 on older systems) in /etc/login.defs, and make sure pam_unix uses the same algorithm. Ask users to change passwords so existing hashes are upgraded.
Verify
grep -i '^ENCRYPT_METHOD' /etc/login.defs
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U/C:H/I:N/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-916, CWE-328, OWASP A02:2021, NIST 800-53 IA-5(1)
References
login.defs(5), Linux man-pages
NIST SP 800-63B-4, Digital Identity Guidelines: Authentication and Authenticator Management
Learn
P7: Identity, Passwords and Privilege (offline: openvapt learn P7)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/passwords.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Accounts With Obsolete Password Hashes

HOST-PWD-002

Checks /etc/shadow for passwords still stored with MD5 or traditional DES crypt.

Why it matters. Old hashes survive configuration changes until the user changes the password. MD5-crypt and DES hashes can be cracked quickly with commodity hardware.

/etc/shadow: Accounts use obsolete password hashes

olduser (MD5-crypt)
Fix
Configure a modern algorithm (HOST-PWD-001), then force a password change for each listed account (chage -d 0 <user>) or lock unused accounts (passwd -l <user>).
Verify
Re-run this check; no accounts should be listed.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-916, CWE-328, OWASP A02:2021, NIST 800-53 IA-5(1)
References
crypt(5), libxcrypt, Debian trixie manual pages (hashing methods)
NIST SP 800-63B-4, Digital Identity Guidelines: Authentication and Authenticator Management
Learn
P7: Identity, Passwords and Privilege (offline: openvapt learn P7)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/passwords.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

No Account Lockout After Failed Logins

HOST-PWD-004

Checks that PAM temporarily locks accounts after repeated failed logins.

Why it matters. Without lockout, local and PAM-backed remote logins can be guessed indefinitely. A temporary lock after a few failures slows attacks and makes them visible. This check covers whether lockout exists and its deny threshold; HOST-PAM-002 covers only how long the lock lasts (unlock_time), so one missing lockout is reported once, here.

pam: No effective account lockout in the authentication stack

/etc/pam.d/common-auth: pam_faillock deny=100 (need 1 to 10)
Fix
Enable pam_faillock (authselect enable-feature with-faillock on RHEL family; pam-auth-update or a faillock profile on Debian/Ubuntu) with settings such as deny=5 unlock_time=900 in /etc/security/faillock.conf. Keep a root session open and test a login in a second session before closing it: a wrong PAM line can lock every user out, including administrators. Do not lock root (no even_deny_root) unless console access is assured.
Verify
grep -E 'pam_faillock|pam_tally2' /etc/pam.d/common-auth /etc/pam.d/system-auth
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N
Category
Identity and Authentication
Effort
Medium
Confidence
High
Standards
CWE-307, OWASP A07:2021, NIST 800-53 AC-7
References
pam_faillock(8), Linux-PAM
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P7: Identity, Passwords and Privilege (offline: openvapt learn P7)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/passwords.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

SSH Password Authentication Enabled

HOST-SSH-002

Checks whether SSH accepts passwords instead of only keys.

Why it matters. Internet-facing SSH receives constant automated password guessing. Public-key authentication cannot be guessed, phished as easily, or reused from another breached site.

sshd: Password logins are accepted (PasswordAuthentication defaults to yes)

passwordauthentication yes
Fix
Install your public key for each admin user (ssh-copy-id), confirm key login works in a second session, then set PasswordAuthentication no and KbdInteractiveAuthentication no in /etc/ssh/sshd_config and reload sshd.
Verify
sshd -T | grep -Ei 'passwordauthentication|kbdinteractive' should show 'no' for both.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-307, CWE-521, NIST 800-53 IA-2(1), IA-5
References
OpenBSD, sshd_config(5) manual page
NIST SP 800-63B-4, Digital Identity Guidelines: Authentication and Authenticator Management
Learn
P2: SSH Security (offline: openvapt learn P2)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/ssh_password_auth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

SSH Offers Weak Cryptography

HOST-SSH-004

Checks the SSH ciphers, MACs, key exchange and host key algorithms for outdated choices.

Why it matters. CBC-mode ciphers, RC4, MD5/SHA-1 MACs and 1024-bit Diffie-Hellman have known practical weaknesses. Offering them lets a network attacker downgrade or weaken the session.

sshd: Weak SSH algorithms are offered

ciphers: aes128-cbc
macs: hmac-md5
kexalgorithms: diffie-hellman-group1-sha1
hostkeyalgorithms: ssh-rsa
Fix
Remove the listed algorithms. On OpenSSH 8.x and later the defaults are already strong: delete any custom Ciphers/MACs/KexAlgorithms lines, or set explicit modern lists such as Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com then reload sshd.
Verify
sshd -T | grep -Ei '^(ciphers|macs|kexalgorithms)' should list no cbc, arcfour, md5 or sha1 entries, and hostkeyalgorithms should not list ssh-rsa.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-327, OWASP A02:2021, NIST 800-53 SC-8, SC-13
References
OpenBSD, sshd_config(5) manual page
RFC 9142, Key Exchange Method Updates for SSH
NIST SP 800-131A Rev. 2, Transitioning Cryptographic Algorithms
Learn
P2: SSH Security (offline: openvapt learn P2)
Source
internal/checks/host/ssh_weak_crypto.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

SSH Forwarding Features Enabled

HOST-SSH-007

Checks effective SSH Match contexts for TCP, agent, tunnel and gateway forwarding.

Why it matters. Forwarding can turn an SSH account into a route to protected services or expose a user's authentication agent.

sshd: SSH forwarding is enabled in at least one evaluated context

allowtcpforwarding default yes
allowagentforwarding default yes
Fix
Set AllowTcpForwarding no, AllowAgentForwarding no, PermitTunnel no and GatewayPorts no globally or in every applicable Match block, then reload sshd.
Verify
Run sshd -T -C user=nobody,host=localhost,addr=192.0.2.1 and confirm each forwarding option is no.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-441, NIST 800-53 AC-4, CM-7
References
OpenBSD, sshd_config(5) manual page
Learn
P2: SSH Security (offline: openvapt learn P2)
Source
internal/checks/host/ssh_forwarding.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

SSH Legacy Trust Options Enabled

HOST-SSH-011

Checks for host-based trust and user environment options that weaken SSH authentication.

Why it matters. HostbasedAuthentication and ignoring .rhosts trust other machines instead of users. PermitUserEnvironment lets users set variables such as LD_PRELOAD that can bypass restrictions.

sshd: Legacy trust options are enabled

hostbasedauthentication yes
ignorerhosts no
permituserenvironment yes
Fix
Set HostbasedAuthentication no , IgnoreRhosts yes and PermitUserEnvironment no in /etc/ssh/sshd_config, then reload sshd.
Verify
sshd -T | grep -Ei 'hostbasedauthentication|ignorerhosts|permituserenvironment'
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:L
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-290, CWE-15, NIST 800-53 IA-2, CM-6
References
OpenBSD, sshd_config(5) manual page
Learn
P2: SSH Security (offline: openvapt learn P2)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Telnet Server Installed or Enabled

HOST-SVC-002

Checks whether a Telnet server is installed or set to start at boot.

Why it matters. Telnet sends user names, passwords and every keystroke in the clear. Anyone on the network path reads them. SSH replaced it decades ago; a Telnet server on a modern server is almost always forgotten rather than needed.

services: 2 legacy service component(s) present

package telnetd is installed
unit telnet.socket is enabled at boot
Fix
apt purge telnetd inetutils-telnetd or dnf remove telnet-server , and systemctl disable --now telnet.socket . Use SSH. Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.
Verify
dpkg -l telnetd inetutils-telnetd telnetd-ssl telnet-server 2>/dev/null | grep '^ii' ; systemctl is-enabled telnet.socket telnetd.service inetutils-telnetd.service 2>/dev/null
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-319, CWE-1188, NIST 800-53 CM-7, CM-7(1), SC-8
References
MITRE ATT&CK T1040, Network Sniffing
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/legacy_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

rsh, rlogin, rexec or finger Server Installed or Enabled

HOST-SVC-003

Checks whether the Berkeley r-services (rsh, rlogin, rexec) or a finger server is installed or enabled.

Why it matters. The r-services trust the client's claim of who it is and send everything unencrypted; .rhosts files (HOST-USR-007) exist for them. finger lists account names and login times to anyone who asks, which is reconnaissance for password guessing.

services: 1 legacy service component(s) present

package rsh-server is installed
Fix
apt purge rsh-server rsh-redone-server fingerd or dnf remove rsh-server finger-server , and systemctl disable --now rsh.socket rlogin.socket rexec.socket finger.socket . Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.
Verify
dpkg -l rsh-server rsh-redone-server fingerd finger-server efingerd cfingerd 2>/dev/null | grep '^ii' ; systemctl is-enabled rsh.socket rlogin.socket rexec.socket finger.socket rsh-redone-server.service fingerd.service 2>/dev/null
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-319, CWE-1188, NIST 800-53 CM-7, CM-7(1), SC-8
References
MITRE ATT&CK T1040, Network Sniffing
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/legacy_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

TFTP Server Installed or Enabled

HOST-SVC-004

Checks whether a TFTP server is installed or set to start at boot.

Why it matters. TFTP has no authentication and no encryption: any client that can reach it can read, and often write, every file in its directory. It is needed only on network boot (PXE) servers and for some network equipment, and is a frequent source of leaked configuration files. If this machine is one of the network boot (PXE) servers that legitimately run it, record the reason in the suppression file so the finding stays visible but accepted.

services: 1 legacy service component(s) present

package tftpd-hpa is installed
Fix
apt purge tftpd-hpa atftpd or dnf remove tftp-server , and systemctl disable --now tftpd-hpa.service tftp.socket . Where PXE is required, serve only that directory, read-only, from a dedicated host. Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.
Verify
dpkg -l tftpd-hpa atftpd tftp-server tftpd 2>/dev/null | grep '^ii' ; systemctl is-enabled tftpd-hpa.service atftpd.service tftp.socket tftp.service 2>/dev/null
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-306, CWE-1188, NIST 800-53 CM-7, CM-7(1), SC-8
References
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/legacy_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

FTP Server Installed or Enabled

HOST-SVC-005

Checks whether an FTP server (vsftpd, ProFTPD or Pure-FTPd) is installed or set to start at boot.

Why it matters. Plain FTP sends passwords and files unencrypted and needs a wide range of ports open. SFTP over SSH, which the SSH server already provides, does the same job encrypted. An FTP server is usually a leftover from a web hosting panel. If this machine is one of the hosts that must serve legacy FTP clients that legitimately run it, record the reason in the suppression file so the finding stays visible but accepted.

services: 2 legacy service component(s) present

package vsftpd is installed
unit vsftpd.service is enabled at boot
Fix
Move users to SFTP (the OpenSSH internal-sftp subsystem), then apt purge vsftpd proftpd-core pure-ftpd or dnf remove vsftpd proftpd and systemctl disable --now vsftpd . If FTP must stay, enforce TLS (FTPS) and restrict it to named users. Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.
Verify
dpkg -l vsftpd proftpd-core proftpd-basic proftpd pure-ftpd pure-ftpd-common 2>/dev/null | grep '^ii' ; systemctl is-enabled vsftpd.service proftpd.service pure-ftpd.service 2>/dev/null
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-319, CWE-1188, NIST 800-53 CM-7, CM-7(1), SC-8
References
MITRE ATT&CK T1040, Network Sniffing
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/legacy_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

NIS Server or Client Installed or Enabled

HOST-SVC-006

Checks whether the Network Information Service (NIS, ypserv or ypbind) is installed or enabled.

Why it matters. NIS distributes account and password hash databases over the network without encryption or strong authentication; anyone who can reach the server can request the whole password map. HOST-USR-006 looks for its + entries in the account files; this check looks for the software itself.

services: 1 legacy service component(s) present

package nis is installed
Fix
Replace NIS with a modern directory (SSSD with LDAPS or FreeIPA), then apt purge nis or dnf remove ypserv ypbind and systemctl disable --now ypserv ypbind . Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.
Verify
dpkg -l nis ypserv ypbind yp-tools 2>/dev/null | grep '^ii' ; systemctl is-enabled ypserv.service ypbind.service nis.service yppasswdd.service 2>/dev/null
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-319, CWE-522, NIST 800-53 CM-7, CM-7(1), SC-8
References
MITRE ATT&CK T1040, Network Sniffing
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/legacy_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Custom Services Run as Root

HOST-SYSD-001

Checks whether long-running services written by the administrator run as root instead of a dedicated user.

Why it matters. Application services (Node.js, Python, Java, custom daemons) are the code most exposed to attackers. If one runs as root, any bug in it gives the attacker full control of the machine instead of one unprivileged account.

systemd units: 4 custom service(s) run as root

shop-admin.service: no User= or DynamicUser=, runs as root (/etc/systemd/system/shop-admin.service)
shop-api.service: no User= or DynamicUser=, runs as root (/etc/systemd/system/shop-api.service)
shop-reports.service: no User= or DynamicUser=, runs as root (/etc/systemd/system/shop-reports.service)
shop-worker.service: no User= or DynamicUser=, runs as root (/etc/systemd/system/shop-worker.service)
Fix
Create a dedicated account (useradd --system --no-create-home --shell /usr/sbin/nologin <app>), give it ownership of only the folders the app writes to, then add User=<app> and Group=<app> to the [Service] section (or DynamicUser=yes). Run systemctl daemon-reload and restart the service. Ports below 1024 can be allowed with AmbientCapabilities=CAP_NET_BIND_SERVICE instead of root.
Verify
systemctl show -p User,DynamicUser <unit> and ps -o user= -p $(systemctl show -p MainPID --value <unit>)
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:L
Category
Identity and Authentication
Effort
Medium
Confidence
High
Standards
CWE-250, NIST 800-53 AC-6, CM-7
References
systemd.exec(5), execution environment configuration
NIST SP 800-123, Guide to General Server Security (least privilege for services)
Learn
P11: Service Hardening With systemd (offline: openvapt learn P11)
Source
internal/checks/host/systemd.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Secrets Written Into Service Unit Files

HOST-SYSD-005

Checks whether passwords, tokens or keys are set with Environment= in systemd unit files.

Why it matters. Unit files are normally readable by every user, and systemctl show prints a service's Environment= values to any local user. A database password or API token placed there is effectively public on the machine.

systemd units: Service unit files store secrets

shop-api.service (values not shown): Environment= sets DB_PASSWORD, STRIPE_API_KEY
Fix
Move secrets to a root-owned file readable only by root (chmod 600) and load it with EnvironmentFile=, or better use LoadCredential=/SetCredentialEncrypted= so the secret is only visible to the service. Then rotate every secret that was exposed.
Verify
systemctl show -p Environment <unit> should show no secret values.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-526, CWE-312, OWASP A05:2021, NIST 800-53 IA-5, SC-28
References
systemd.exec(5), execution environment configuration
systemd, System and Service Credentials
Learn
P11: Service Hardening With systemd (offline: openvapt learn P11)
Source
internal/checks/host/systemd.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Reboot Required to Apply Updates

HOST-UPD-002

Checks whether installed updates (often kernel or core library fixes) are waiting for a reboot.

Why it matters. Updated packages do not protect anything until the running kernel and libraries are replaced. A pending reboot means known-fixed vulnerabilities are still live.

reboot: A reboot is required to apply installed updates

/var/run/reboot-required exists
linux-image-generic
libc6
Fix
Schedule a maintenance window and reboot (or use live patching where supported).
Verify
ls /var/run/reboot-required should not exist after the reboot.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L
Category
Patch and Vulnerability Management
Effort
Medium
Confidence
High
Standards
CWE-1104, NIST 800-53 SI-2
References
NIST SP 800-40 Rev. 4
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Duplicate User IDs

HOST-USR-004

Checks that no two accounts share the same numeric user id.

Why it matters. Accounts with the same UID are the same user to the kernel: they own each other's files and processes, and audit logs cannot tell them apart.

/etc/passwd: Accounts share user ids

UID 0: root, toor
Fix
Give each account a unique UID (usermod -u <new-uid> <user>) and fix file ownership (find / -xdev -uid <old-uid>).
Verify
cut -d: -f3 /etc/passwd | sort | uniq -d should print nothing.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N
Category
Identity and Authentication
Effort
Medium
Confidence
High
Standards
CWE-286, NIST 800-53 AC-2, IA-2
References
passwd(5), Linux man-pages
Learn
P7: Identity, Passwords and Privilege (offline: openvapt learn P7)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/passwords.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Legacy NIS Entries in Account Files

HOST-USR-006

Checks /etc/passwd, /etc/shadow and /etc/group for legacy '+' NIS inclusion entries.

Why it matters. '+' entries pull accounts from NIS, an unencrypted legacy directory service. If NIS is gone, the entry can still be abused to create unexpected accounts.

account files: Legacy NIS '+' entries found

/etc/passwd: +
Fix
Remove the '+' lines (with vipw / vigr) and use a modern directory service such as SSSD with LDAPS if central accounts are needed.
Verify
grep '^+' /etc/passwd /etc/shadow /etc/group should print nothing.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-288, NIST 800-53 IA-2, CM-7
References
nsswitch.conf(5), Linux man-pages (compat mode)
Learn
P7: Identity, Passwords and Privilege (offline: openvapt learn P7)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/passwords.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Duplicate Group IDs or Account Names

HOST-USR-008

Checks /etc/group for duplicate GIDs and group names, and /etc/passwd for duplicate user names.

Why it matters. Two groups with one GID are the same group to the kernel, so file permissions granted to one are granted to both. Duplicate names make tools and audit logs act on the wrong entry, and are a sign that the account files were edited by hand or by a broken script.

/etc/group: Duplicate group ids or names in the account files

GID 4: adm, staff
Fix
groupmod -g <new-gid> <group> for one of each duplicate pair, then fix file ownership (find / -xdev -gid <old-gid>); remove or rename the duplicate name entries with vigr and vipw, which lock the files while editing.
Verify
cut -d: -f3 /etc/group | sort | uniq -d ; cut -d: -f1 /etc/group /etc/passwd | sort | uniq -d print nothing.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N
Category
Identity and Authentication
Effort
Medium
Confidence
High
Standards
CWE-286, NIST 800-53 AC-2, AC-3
References
group(5), Linux man-pages
passwd(5), Linux man-pages
Learn
P7: Identity, Passwords and Privilege (offline: openvapt learn P7)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
P20: Secrets, Cron and Account Hygiene (offline: openvapt learn P20)
Source
internal/checks/host/hygiene.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Password and Shadow Files Out of Step

HOST-USR-009

Checks that every /etc/passwd account has a /etc/shadow entry, that no password hash sits in /etc/passwd, and that /etc/shadow has no orphan entries.

Why it matters. A hash in the world-readable /etc/passwd can be cracked offline by any user. An account with 'x' in passwd but no shadow line has an undefined password state that differs between tools, and shadow lines for deleted accounts are leftovers of a removal that did not finish.

/etc/passwd: Account files are inconsistent

olduser: /etc/shadow entry has no /etc/passwd account
daemon: /etc/passwd account has no /etc/shadow entry
toor: /etc/passwd account has no /etc/shadow entry
Fix
pwconv moves hashes into /etc/shadow and creates missing entries; userdel or vipw/vigr removes orphan lines; run pwck and grpck to confirm the files are consistent.
Verify
pwck -r reports no errors.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-256, CWE-522, NIST 800-53 IA-5, AC-2
References
shadow(5), Linux man-pages
passwd(5), Linux man-pages
pwck(8), Linux man-pages
Learn
P7: Identity, Passwords and Privilege (offline: openvapt learn P7)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
P20: Secrets, Cron and Account Hygiene (offline: openvapt learn P20)
Source
internal/checks/host/hygiene.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Application Server Ports Reachable Without a Reverse Proxy

NET-APP-002

Checks whether application servers and developer tools (Node.js, Tomcat, Django, Flask, Vite) serve HTTP on network-reachable addresses.

Why it matters. Application servers are designed to sit behind a reverse proxy that adds TLS, security headers, logging and request limits. Reached directly they bypass all of that, and development servers on these ports often run with debug pages on. The port number alone does not prove a weakness, so this is rated Medium and should be reviewed.

sockets: Application server ports are network-reachable

tcp 0.0.0.0:3000 Node.js / Express app server, bound to all interfaces
a web server listens on port 80 or 443 on this machine: bind the application to 127.0.0.1 and publish it through that proxy
Fix
Bind the application to 127.0.0.1 (Node.js: app.listen(3000, '127.0.0.1'); Gunicorn: --bind 127.0.0.1:8000; Tomcat: address="127.0.0.1" on the Connector) and publish it only through nginx or Apache.
Verify
ss -tlnp shows these ports on 127.0.0.1 or ::1 only.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L
Category
Network Exposure
Effort
Low
Confidence
High
Standards
CWE-1188, CWE-1327, OWASP A05:2021, NIST 800-53 SC-7, CM-7
References
OWASP Node.js Security Cheat Sheet
Gunicorn documentation, Deploying Gunicorn (behind a proxy)
Learn
P13: Application Servers: Tomcat, Node.js and Python (offline: openvapt learn P13)
Source
internal/checks/network/firewall_exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Mail Cleartext Authentication Allowed

NET-DB-013

Postfix or Dovecot permits plaintext authentication without requiring TLS.

Why it matters. Credentials sent before transport encryption can be observed by any party able to intercept the connection.

/etc/postfix/main.cf, /etc/dovecot/conf.d/10-auth.conf: Postfix or Dovecot permits plaintext authentication without requiring TLS.

smtpd_tls_auth_only is no
disable_plaintext_auth is no
Fix
Set smtpd_tls_auth_only = yes and disable_plaintext_auth = yes. Use implicit TLS on ports 465, 993, and 995. STARTTLS assessment is out of scope.
Verify
Confirm the effective mail configuration and that unauthenticated plaintext sessions do not advertise AUTH.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-319, CWE-523, OWASP A02:2021, ASVS 9.1.1, NIST 800-53 SC-8, IA-5(1)
References
Dovecot Authentication Settings
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
Source
internal/checks/network/services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

MySQL Symbolic Links Allowed for Tables

NET-DB-014

MySQL or MariaDB does not disable symbolic links for table files (skip-symbolic-links or symbolic-links=0).

Why it matters. With symlinks allowed, a user who can create tables can point table files at paths outside the data directory and read or overwrite them with the server's privileges. The MySQL manual recommends disabling the feature unless it is needed.

/etc/mysql/mysql.conf.d/mysqld.cnf: MySQL or MariaDB does not disable symbolic links for table files (skip-symbolic-links or symbolic-links=0).

no symbolic-links setting; MySQL 5.x (dpkg status mysql-server-5.7) allows symbolic links by default
Fix
Add symbolic-links=0 (or skip-symbolic-links ) under [mysqld] and restart the service in a maintenance window.
Verify
SHOW VARIABLES LIKE 'have_symlink'; from an administrator session should print DISABLED.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L
Category
Data Services
Effort
Low
Confidence
High
Standards
CWE-59, CWE-732, OWASP A05:2021, ASVS 14.1.3, NIST 800-53 CM-6, AC-6
References
MySQL 8.4 Reference Manual, Using Symbolic Links
MySQL 8.4 Reference Manual, Security Guidelines
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
P19: Database, Mail and DNS Hardening (offline: openvapt learn P19)
Source
internal/checks/network/data_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

MySQL secure_file_priv Not Restricted

NET-DB-015

secure_file_priv is not set, or is set to an empty value, so LOAD DATA and SELECT ... INTO OUTFILE can read and write anywhere the server process can.

Why it matters. File import and export statements run with the database server's filesystem rights. Limiting them to one folder, or disabling them with NULL, stops an injected query from reading /etc files or dropping a web shell into the document root.

/etc/mysql/mysql.conf.d/mysqld.cnf: secure_file_priv is not set, or is set to an empty value, so LOAD DATA and SELECT ... INTO OUTFILE can read and write anywhere the server process can.

secure_file_priv is not set in the option files; MySQL 5.x (dpkg status mysql-server-5.7) leaves it empty by default
Fix
Add secure_file_priv = NULL (no file operations) or secure_file_priv = /var/lib/mysql-files under [mysqld] and restart in a maintenance window.
Verify
SHOW VARIABLES LIKE 'secure_file_priv'; should print NULL or the chosen folder.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:L/A:N
Category
Data Services
Effort
Low
Confidence
High
Standards
CWE-73, CWE-250, OWASP A05:2021, ASVS 14.1.3, NIST 800-53 CM-6, AC-6, SI-10
References
MySQL 8.4 Reference Manual, secure_file_priv
MySQL 8.4 Reference Manual, Security Guidelines
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
P19: Database, Mail and DNS Hardening (offline: openvapt learn P19)
Source
internal/checks/network/data_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

MySQL Does Not Require Encrypted Client Connections

NET-DB-016

require_secure_transport is not ON, so clients may log in and query over plaintext TCP.

Why it matters. Without the requirement, a client that is misconfigured or downgraded sends credentials and data in the clear across the network. The setting is harmless for Unix socket connections and makes TLS a server-side rule rather than a client choice. When bind-address keeps the server on loopback (127.0.0.1, ::1 or localhost) the plaintext path never leaves the machine and only a local root user could read it, so the check reports Pass with a note instead of a Medium finding; the Medium applies to servers reachable from the network.

/etc/mysql/mysql.conf.d/mysqld.cnf: require_secure_transport is not ON, so clients may log in and query over plaintext TCP.

require_secure_transport is not set; the default is OFF
Fix
Provision a server certificate (MySQL creates one by default), then add require_secure_transport = ON under [mysqld] and restart in a maintenance window. Test every application connection string first.
Verify
SHOW VARIABLES LIKE 'require_secure_transport'; should print ON, and a client that disables TLS (ssl-mode DISABLED) connecting to 127.0.0.1 should be refused.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-319, OWASP A02:2021, ASVS 9.2.2, NIST 800-53 SC-8, SC-13
References
MySQL 8.4 Reference Manual, Configuring MySQL to Use Encrypted Connections
NIST SP 800-53 Rev. 5, SC-8 Transmission Confidentiality and Integrity
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
P19: Database, Mail and DNS Hardening (offline: openvapt learn P19)
Source
internal/checks/network/data_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

PostgreSQL Uses md5 or password Authentication

NET-DB-019

pg_hba.conf has active rules with the md5 or password method instead of scram-sha-256.

Why it matters. The password method sends the password in clear text unless the connection is encrypted; md5 is a fast unsalted construction whose stored hashes work as passwords themselves (pass-the-hash) and which the PostgreSQL documentation describes as obsolete. SCRAM-SHA-256 fixes both.

/etc/postgresql/16/main/pg_hba.conf: pg_hba.conf has active rules with the md5 or password method instead of scram-sha-256.

/etc/postgresql/16/main/pg_hba.conf: host all all 10.0.0.0/8 md5
Fix
Set password_encryption = scram-sha-256 in postgresql.conf, have every role reset its password so a SCRAM verifier is stored, then change the pg_hba.conf methods to scram-sha-256 and reload.
Verify
SELECT * FROM pg_hba_file_rules WHERE auth_method IN ('md5','password'); should return no rows.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-328, CWE-916, OWASP A02:2021, A07:2021, ASVS 2.4.1, NIST 800-53 IA-5, IA-5(1), SC-13
References
PostgreSQL, Authentication Methods
PostgreSQL, Password Authentication
NIST SP 800-63B, Digital Identity Guidelines: Authentication
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
P19: Database, Mail and DNS Hardening (offline: openvapt learn P19)
Source
internal/checks/network/data_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

PostgreSQL SSL Not Enabled

NET-DB-020

postgresql.conf does not set ssl = on, so TCP clients cannot encrypt their sessions and hostssl rules cannot apply.

Why it matters. Without SSL every query and result crosses the network in the clear. Enabling it costs one certificate and lets pg_hba.conf require hostssl for remote clients. When listen_addresses keeps the server on loopback (the PostgreSQL default, localhost) the plaintext path never leaves the machine and only a local root user could read it, so the check reports Pass with a note instead of a Medium finding; the Medium applies to servers reachable from the network.

/etc/postgresql/16/main/postgresql.conf: postgresql.conf does not set ssl = on, so TCP clients cannot encrypt their sessions and hostssl rules cannot apply.

ssl is not set; the default is off
Fix
Install a certificate and key readable only by the postgres user, set ssl = on , ssl_cert_file and ssl_key_file, reload, then change remote pg_hba.conf rules from host to hostssl.
Verify
SHOW ssl; should print on, and psql "sslmode=require host=127.0.0.1" should connect.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-319, OWASP A02:2021, ASVS 9.2.2, NIST 800-53 SC-8, SC-13
References
PostgreSQL, Secure TCP/IP Connections with SSL
NIST SP 800-53 Rev. 5, SC-8 Transmission Confidentiality and Integrity
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
P19: Database, Mail and DNS Hardening (offline: openvapt learn P19)
Source
internal/checks/network/data_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

PostgreSQL Password Encryption Not SCRAM

NET-DB-022

password_encryption is set to md5, so new and changed passwords are stored as md5 verifiers that work as pass-the-hash credentials.

Why it matters. The stored md5 value is itself sufficient to authenticate, so a leaked catalog is a leaked set of passwords. SCRAM-SHA-256 stores a salted, iterated verifier that is not usable directly. PostgreSQL 14 and newer default to scram-sha-256; older clusters often carry an explicit md5 line.

/etc/postgresql/16/main/postgresql.conf: password_encryption is set to md5, so new and changed passwords are stored as md5 verifiers that work as pass-the-hash credentials.

/etc/postgresql/16/main/postgresql.conf: password_encryption = md5
Fix
Set password_encryption = scram-sha-256 , reload, and ask every role to reset its password so the verifier is regenerated. Then move pg_hba.conf to scram-sha-256 (NET-DB-019).
Verify
SELECT rolname FROM pg_authid WHERE rolpassword LIKE 'md5%'; should return no rows after the resets.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-916, CWE-328, OWASP A02:2021, ASVS 2.4.1, NIST 800-53 IA-5(1), SC-13
References
PostgreSQL, Password Authentication
PostgreSQL, Connections and Authentication
NIST SP 800-63B, Digital Identity Guidelines: Authentication
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
P19: Database, Mail and DNS Hardening (offline: openvapt learn P19)
Source
internal/checks/network/data_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Redis Dangerous Commands Not Restricted

NET-DB-023

redis.conf neither renames nor disables CONFIG, FLUSHALL, FLUSHDB, DEBUG and KEYS, and no ACL user excludes the @dangerous category.

Why it matters. An attacker who reaches Redis with any credential can wipe data with FLUSHALL, rewrite the configuration with CONFIG SET to write files (the classic path to a cron job or SSH key), or stall the server with KEYS *. Removing or renaming these for application users limits what a stolen credential can do.

/etc/redis/redis.conf: redis.conf neither renames nor disables CONFIG, FLUSHALL, FLUSHDB, DEBUG and KEYS, and no ACL user excludes the @dangerous category.

no rename-command, user or aclfile directive
Fix
Prefer ACLs on Redis 6 and newer: user app on >secret ~app:* -@all +@read +@write -@dangerous . Otherwise add rename-command FLUSHALL "" (and the same for FLUSHDB, CONFIG, DEBUG, KEYS) and restart.
Verify
redis-cli -a <secret> ACL LIST or redis-cli CONFIG GET dir should be refused for the application user.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:L
Category
Data Services
Effort
Low
Confidence
High
Standards
CWE-749, OWASP A01:2021, A05:2021, ASVS 14.1.3, NIST 800-53 AC-6, CM-7
References
Redis Security
Redis ACL
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
P19: Database, Mail and DNS Hardening (offline: openvapt learn P19)
Source
internal/checks/network/data_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

BIND DNSSEC Validation Disabled

NET-DNS-002

named.conf sets dnssec-validation no, so the resolver accepts forged answers for signed zones.

Why it matters. DNSSEC validation lets a recursive resolver reject spoofed records for zones that are signed, which blocks cache poisoning of those names. BIND 9.16 and newer default to auto with the built-in root trust anchor, so an explicit no is a deliberate weakening.

/etc/bind/named.conf.options: named.conf sets dnssec-validation no, so the resolver accepts forged answers for signed zones.

dnssec-validation no
Fix
Set dnssec-validation auto; in options (remove any no ), run named-checkconf and rndc reconfig. Authoritative-only servers with recursion off may leave it unset.
Verify
dig @127.0.0.1 dnssec-failed.org a should return SERVFAIL, and a signed name should show the ad flag.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N
Category
Data Services
Effort
Low
Confidence
High
Standards
CWE-347, CWE-350, OWASP A08:2021, NIST 800-53 SC-20, SC-21
References
BIND 9 Administrator Reference Manual, dnssec-validation
NIST SP 800-81 Rev. 2, Secure Domain Name System Deployment Guide
Learn
P19: Database, Mail and DNS Hardening (offline: openvapt learn P19)
Source
internal/checks/network/data_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

No Active Host Firewall

NET-FW-001

Checks whether a host firewall (nftables, iptables, ufw or firewalld) is filtering incoming traffic.

Why it matters. A default-deny host firewall is a safety net: a service that is installed or misconfigured by mistake is still not reachable from the internet.

firewall: iptables has no drop or reject rules (input policy ACCEPT)

Fix
Ubuntu: ufw default deny incoming && ufw allow OpenSSH && ufw allow 80,443/tcp && ufw enable . RHEL family: systemctl enable --now firewalld . Always allow SSH before enabling, or you will lock yourself out.
Verify
ufw status verbose or firewall-cmd --list-all or nft list ruleset
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L
Category
Network Exposure
Effort
Medium
Confidence
High
Standards
CWE-923, NIST 800-53 SC-7
References
NIST SP 800-41 Rev. 1, Guidelines on Firewalls and Firewall Policy
nftables wiki
Learn
F1: Security Basics (offline: openvapt learn F1)
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
Source
internal/checks/network/firewall.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Container Ports Bypass the Host Firewall

NET-FW-005

Checks whether Docker publishes container ports through its own iptables chains with no DOCKER-USER filtering.

Why it matters. Docker inserts its NAT and FORWARD rules ahead of ufw and of the INPUT chain, so a port published with -p 8080:80 is reachable from the internet even when ufw says the port is denied. Administrators routinely believe the firewall protects these containers when it does not.

iptables: 1 published container port rule(s) are not filtered by the host firewall

-A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT
Fix
Publish container ports on loopback only (-p 127.0.0.1:8080:80) and put a reverse proxy in front, or add filtering to DOCKER-USER, for example: iptables -I DOCKER-USER -i eth0 ! -s 203.0.113.0/24 -j DROP (persist it with your firewall tooling). Caution: test from an allowed address first; a wrong interface name or source range cuts access to every published container.
Verify
docker ps --format '{{.Ports}}' shows 127.0.0.1 bindings, or iptables -S DOCKER-USER shows DROP rules.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L
Category
Network Exposure
Effort
Medium
Confidence
High
Standards
CWE-923, CWE-1327, OWASP A05:2021, NIST 800-53 SC-7, CM-7
References
Docker documentation, Packet filtering and firewalls
NIST SP 800-41 Rev. 1, Guidelines on Firewalls and Firewall Policy
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P12: Firewall Policy Versus What Is Listening (offline: openvapt learn P12)
Source
internal/checks/network/firewall_exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Postfix SMTP TLS Not Offered or Has No Certificate

NET-MAIL-001

smtpd_tls_security_level is none or unset, or is may or encrypt without a server certificate, so incoming SMTP sessions cannot be encrypted.

Why it matters. Without STARTTLS every message and every authentication exchange that other servers and clients send to this host crosses the network in the clear. Opportunistic TLS (may) with a valid certificate is the baseline that other mail servers expect.

/etc/postfix/main.cf: smtpd_tls_security_level is none or unset, or is may or encrypt without a server certificate, so incoming SMTP sessions cannot be encrypted.

/etc/postfix/main.cf: smtpd_tls_security_level = may
TLS is enabled but no smtpd_tls_cert_file or smtpd_tls_chain_files is set
Fix
Set smtpd_tls_security_level = may , smtpd_tls_chain_files = /etc/letsencrypt/live/<host>/privkey.pem, /etc/letsencrypt/live/<host>/fullchain.pem (or smtpd_tls_cert_file and smtpd_tls_key_file), then postfix reload.
Verify
postconf smtpd_tls_security_level smtpd_tls_chain_files and an authorised openssl s_client -starttls smtp -connect 127.0.0.1:25 showing a certificate.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-319, OWASP A02:2021, ASVS 9.2.2, NIST 800-53 SC-8, SC-13
References
Postfix TLS Support
Postfix Configuration Parameters
NIST SP 800-177 Rev. 1, Trustworthy Email
Learn
P19: Database, Mail and DNS Hardening (offline: openvapt learn P19)
Source
internal/checks/network/data_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Postfix Allows TLS 1.0 or 1.1

NET-MAIL-002

smtpd_tls_protocols or smtpd_tls_mandatory_protocols is unset or still allows TLSv1 or TLSv1.1.

Why it matters. The Postfix default for opportunistic TLS still admits TLS 1.0 and 1.1, which RFC 8996 deprecates. Setting a floor of TLS 1.2 is compatible with every current mail server and client. Severity is Medium rather than High because SMTP opportunistic TLS already tolerates fallback to plaintext. Postfix uses the system OpenSSL, so when its configuration already sets a floor of TLS 1.2 (MinProtocol in openssl.cnf on Debian 12 and Ubuntu 22.04 and later, or a crypto policy of DEFAULT, FUTURE or FIPS on the RHEL family) the old versions cannot be negotiated whatever main.cf says; the check then reports Pass and names the floor, and the directives remain worth setting so the configuration says what it does.

/etc/postfix/main.cf: smtpd_tls_protocols or smtpd_tls_mandatory_protocols is unset or still allows TLSv1 or TLSv1.1.

smtpd_tls_protocols = !SSLv2, !SSLv3 (allows TLS 1.0 or 1.1)
smtpd_tls_mandatory_protocols is not set; the default allows TLS 1.0 and 1.1
Fix
Add smtpd_tls_protocols = >=TLSv1.2 and smtpd_tls_mandatory_protocols = >=TLSv1.2 (Postfix 3.6 and newer; on older releases use !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 ), then postfix reload.
Verify
postconf smtpd_tls_protocols smtpd_tls_mandatory_protocols
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-326, CWE-327, OWASP A02:2021, ASVS 9.1.3, NIST 800-53 SC-8, SC-13
References
Postfix TLS Support
RFC 8996, Deprecating TLS 1.0 and TLS 1.1
NIST SP 800-52 Rev. 2, Guidelines for TLS Implementations
Learn
P19: Database, Mail and DNS Hardening (offline: openvapt learn P19)
Source
internal/checks/network/data_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Dovecot Does Not Require TLS

NET-MAIL-004

Dovecot's ssl setting is yes or no instead of required, so IMAP and POP3 clients may use unencrypted sessions.

Why it matters. With ssl = yes, TLS is offered but a client may keep the whole session in the clear, and non-plaintext mechanisms still travel unprotected. ssl = required refuses any command before STARTTLS or implicit TLS, which makes disable_plaintext_auth (NET-DB-013) effective.

/etc/dovecot/conf.d/10-ssl.conf: Dovecot's ssl setting is yes or no instead of required, so IMAP and POP3 clients may use unencrypted sessions.

/etc/dovecot/conf.d/10-ssl.conf: ssl = yes
Fix
Set ssl = required and ssl_min_protocol = TLSv1.2 in conf.d/10-ssl.conf, then doveadm reload. Prefer implicit TLS ports 993 and 995 for clients. Caution: clients set to plaintext stop connecting, so confirm every mail client uses TLS first.
Verify
doveconf ssl ssl_min_protocol should print required and TLSv1.2.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-319, OWASP A02:2021, ASVS 9.2.2, NIST 800-53 SC-8, SC-13
References
Dovecot SSL/TLS Configuration
RFC 8996, Deprecating TLS 1.0 and TLS 1.1
Learn
P19: Database, Mail and DNS Hardening (offline: openvapt learn P19)
Source
internal/checks/network/data_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Management Panel or Monitoring Ports Network-Reachable

NET-SVC-004

Webmin, cPanel, WHM, RabbitMQ Management, Consul, the Docker API with TLS or the Prometheus node exporter listen on network-reachable addresses.

Why it matters. Management panels and exporters publish host metrics, service configuration and often a login form. They are a reconnaissance gift and a password guessing target, but they sit behind their own authentication or TLS, so the risk is lower than an open control plane.

sockets: Management panel or monitoring ports are network-reachable

tcp6 [::]:10000 Webmin, bound to all interfaces
tcp 0.0.0.0:15672 RabbitMQ Management, bound to all interfaces
Fix
Bind the panel or exporter to 127.0.0.1 or a management address, put it behind a reverse proxy with authentication, or restrict the port to monitoring hosts in the firewall.
Verify
ss -tulpn shows these ports on 127.0.0.1, ::1 or a management address only.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N
Category
Network Exposure
Effort
Low
Confidence
High
Standards
CWE-1188, CWE-1327, OWASP A05:2021, NIST 800-53 AC-17, CM-7, SC-7
References
Prometheus, Security model
IANA Service Name and Transport Protocol Port Number Registry
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
Source
internal/checks/network/services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Deprecated TLS 1.0 or 1.1 Accepted

NET-TLS-001

Checks whether local TLS services still accept TLS 1.0 or TLS 1.1.

Why it matters. TLS 1.0 and 1.1 were formally deprecated by RFC 8996 in 2021. They rely on outdated constructions (e.g. SHA-1 in the handshake) and fail PCI DSS and most compliance baselines.

shop.example.test on port 443: Deprecated TLS versions accepted

TLS 1.0 accepted
TLS 1.1 accepted
Fix
Apache: SSLProtocol -all +TLSv1.2 +TLSv1.3 . nginx: ssl_protocols TLSv1.2 TLSv1.3; . Postfix/Dovecot: set the minimum protocol to TLSv1.2. Reload the service afterwards.
Verify
openssl s_client -connect 127.0.0.1:443 -tls1_1 </dev/null should fail to connect.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
Low
Standards
CWE-326, CWE-327, OWASP A02:2021, ASVS 9.1.3, NIST 800-53 SC-8, SC-13
References
RFC 8996, Deprecating TLS 1.0 and TLS 1.1
NIST SP 800-52 Rev. 2, Guidelines for TLS Implementations
Mozilla Server Side TLS guidelines
Learn
P4: TLS, Certificates and HTTPS (offline: openvapt learn P4)
Source
internal/checks/network/tls.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

TLS Certificate Expired or Expiring Soon

NET-TLS-002

Checks the expiry date of the certificate each local TLS service presents.

Why it matters. An expired certificate breaks the site for visitors and trains users to click through warnings, which is exactly what an attacker needs for interception.

shop.example.test on port 443: Certificate expires in 8 days

notAfter 2026-10-25
Fix
Renew the certificate (certbot renew, or your provider's process) and make sure renewal is automated (systemctl list-timers | grep certbot).
Verify
echo | openssl s_client -connect 127.0.0.1:443 -servername <site> 2>/dev/null | openssl x509 -noout -enddate
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:L
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-298, OWASP A02:2021, ASVS 9.2.1, NIST 800-53 SC-12, SC-17
References
Let's Encrypt, certificate lifetimes and renewal
NIST SP 800-52 Rev. 2, Guidelines for TLS Implementations
Learn
P4: TLS, Certificates and HTTPS (offline: openvapt learn P4)
Source
internal/checks/network/tls.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Self-Signed or Mismatched TLS Certificate

NET-TLS-003

Checks whether each site presents a self-signed certificate, or one that does not cover its name.

Why it matters. Browsers reject these certificates, so visitors either leave or learn to ignore warnings, which removes protection against interception.

shop.example.test: Certificate is self-signed

subject shop.example.test
Fix
Issue a certificate from a public CA covering every site name, for example with certbot --apache or certbot --nginx -d example.com -d www.example.com.
Verify
openssl s_client -connect 127.0.0.1:443 -servername <site> </dev/null | openssl x509 -noout -subject -issuer -ext subjectAltName
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:L/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-295, CWE-297, OWASP A02:2021, A07:2021, ASVS 9.2.1, NIST 800-53 SC-17
References
RFC 6125, Representation and Verification of Domain-Based Application Service Identity
NIST SP 800-52 Rev. 2, Guidelines for TLS Implementations
Learn
P4: TLS, Certificates and HTTPS (offline: openvapt learn P4)
Source
internal/checks/network/tls.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Weak TLS 1.2 Cipher Suites Accepted

NET-TLS-004

A local TLS service accepts an RC4, 3DES, or CBC with SHA-1 cipher suite under TLS 1.2.

Why it matters. Obsolete cipher constructions lack modern authenticated encryption and are prohibited by current TLS hardening guidance.

shop.example.test on port 443: Weak TLS 1.2 cipher suite accepted

TLS_RSA_WITH_3DES_EDE_CBC_SHA
Fix
Allow only modern AEAD suites for TLS 1.2 and prefer TLS 1.3. Remove RC4, 3DES, NULL, EXPORT, anonymous, and CBC with SHA-1 suites. Caution: very old clients and devices that support only those suites stop connecting; check the access logs for them first.
Verify
Use an approved local TLS scanner and confirm each prohibited TLS 1.2 suite is rejected. Implicit TLS mail ports 465, 993, and 995 are included; STARTTLS is out of scope.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-326, CWE-327, OWASP A02:2021, ASVS 9.1.3, NIST 800-53 SC-8, SC-13
References
RFC 8996, Deprecating TLS 1.0 and TLS 1.1
NIST SP 800-52 Rev. 2, Guidelines for TLS Implementations
Mozilla Server Side TLS guidelines
Learn
P4: TLS, Certificates and HTTPS (offline: openvapt learn P4)
Source
internal/checks/network/tls_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

TLS Certificate Public Key Too Small

NET-TLS-005

A TLS leaf certificate uses RSA below 2048 bits or an elliptic curve below 256 bits.

Why it matters. Undersized public keys provide inadequate security strength and may permit certificate impersonation as cryptanalytic capability improves.

shop.example.test on port 443: Leaf certificate public key is too small

key RSA 1024 bits, signature SHA1-RSA
Fix
Replace the certificate and private key with RSA 2048 bits or stronger, or an approved EC key of at least 256 bits.
Verify
Inspect the renewed leaf certificate key size on ports 443, 465, 993, 995, 8443, and 10000. STARTTLS is out of scope.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
Category
Cryptography and TLS
Effort
Medium
Confidence
Low
Standards
CWE-326, OWASP A02:2021, NIST 800-53 SC-12, SC-13
References
NIST SP 800-131A Rev. 2, Transitioning the Use of Cryptographic Algorithms and Key Lengths
Learn
P4: TLS, Certificates and HTTPS (offline: openvapt learn P4)
Source
internal/checks/network/tls_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

SHA-1 Signed TLS Leaf Certificate

NET-TLS-006

A TLS leaf certificate is signed using SHA-1.

Why it matters. SHA-1 collision attacks invalidate its use for digital signatures and modern clients reject SHA-1 certificates.

shop.example.test on port 443: Leaf certificate uses a SHA-1 signature

key RSA 1024 bits, signature SHA1-RSA
Fix
Reissue the certificate with SHA-256 or stronger and deploy the complete updated chain.
Verify
Inspect the signature algorithm on each implicit TLS service. STARTTLS is out of scope.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
Category
Cryptography and TLS
Effort
Medium
Confidence
Low
Standards
CWE-327, OWASP A02:2021, NIST 800-53 SC-12, SC-13
References
NIST Transitioning Away from SHA-1
Learn
P4: TLS, Certificates and HTTPS (offline: openvapt learn P4)
Source
internal/checks/network/tls_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Apache Directory Indexes Enabled in Configuration

WEB-APA-003

An Options directive enables Indexes (or All), so folders without an index page list their files.

Why it matters. Directory listings publish uploads, backups and scripts that were never linked. Debian ships Indexes on in the default /var/www block, so a fresh install fails this until changed.

/etc/apache2/apache2.conf: An Options directive enables Indexes (or All), so folders without an index page list their files.

/etc/apache2/apache2.conf: Options Indexes FollowSymLinks
Fix
Change the block to Options -Indexes +FollowSymLinks (or remove Indexes). Where a listing is wanted, protect that Directory with Require.
Verify
apachectl -t -D DUMP_CONFIG 2>/dev/null | grep -n Options should show no Indexes except with a leading minus.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-548, OWASP A01:2021, A05:2021, ASVS 4.3.2, NIST 800-53 CM-7, AC-3
References
Apache HTTP Server, Options directive
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Apache Has No Slow Request Protection

WEB-APA-011

mod_reqtimeout does not appear to be loaded and no RequestReadTimeout is set, so a client that sends its request very slowly can hold a worker for the whole Timeout.

Why it matters. Apache keeps one worker busy for each open request. Without minimum read rates, a few clients sending headers a byte at a time (the Slowloris technique) can use up every worker and take the site offline. The module is enabled by default on most distributions, so its absence usually means it was removed.

/etc/apache2/apache2.conf: mod_reqtimeout does not appear to be loaded and no RequestReadTimeout is set, so a client that sends its request very slowly can hold a worker for the whole Timeout.

no reqtimeout_module and no RequestReadTimeout directive
Fix
Enable the module (Debian and Ubuntu: a2enmod reqtimeout; other systems: LoadModule reqtimeout_module modules/mod_reqtimeout.so) and keep or set RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500 , then reload.
Verify
apachectl -M 2>/dev/null | grep reqtimeout
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-770, OWASP A05:2021, NIST 800-53 SC-5, CM-6
References
Apache HTTP Server, mod_reqtimeout
Apache HTTP Server, Security Tips
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
P25: Availability Without Load Testing (offline: openvapt learn P25)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Application .env File Readable by All Users

WEB-APP-002

Checks the permission bits of framework .env files for world-read access.

Why it matters. .env files hold database passwords, API tokens and signing keys in plain text. A world-readable .env hands every account on the server, including other websites' PHP-FPM pools, the keys to this application.

/srv/shop-crm/.env: .env file is readable by all users

mode 0644 is readable by all users

/srv/shop-laravel/.env: .env file is readable by all users

mode 0644 is readable by all users

/var/www/shop/.env: .env file is readable by all users

mode 0644 is readable by all users
Fix
chmod 640 .env && chown <app-user>:<web-group> .env (or 600 when the application runs as its own user). Rotate the secrets if other people have had shell access.
Verify
stat -c '%a %U:%G %n' .env shows 640 or 600.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, CWE-312, OWASP A05:2021, A02:2021, ASVS 14.1.3, NIST 800-53 AC-3, SC-28
References
OWASP Secrets Management Cheat Sheet
OWASP ASVS 4.0.3, V14 Configuration
Learn
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/frameworks.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Rails Production Does Not Force HTTPS

WEB-APP-005

Checks config/environments/production.rb for config.force_ssl = true.

Why it matters. force_ssl redirects plain HTTP to HTTPS, marks cookies Secure and sends Strict-Transport-Security. Without it a session cookie can travel over HTTP once and be read on the network, even when the site also works over HTTPS.

/srv/shop-rails/config/environments/production.rb: Rails production does not force HTTPS

config.force_ssl is not true
Fix
Set config.force_ssl = true in config/environments/production.rb (and config.assume_ssl = true behind a TLS-terminating proxy), then restart the application.
Verify
grep -n force_ssl config/environments/production.rb shows true, and curl -I http://<site>/ returns a 301 to https.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N
Category
Web Application Security
Effort
Low
Confidence
High
Standards
CWE-319, CWE-614, OWASP A02:2021, A05:2021, ASVS 9.1.1, 3.4.1, NIST 800-53 SC-8, CM-6
References
Ruby on Rails Guides, Configuring Rails Applications
Ruby on Rails Guides, Securing Rails Applications
Learn
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/frameworks.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Git Repository Stored Inside a Web Root

WEB-APP-009

Looks on disk for a .git folder directly inside each web document root.

Why it matters. A .git folder in the document root is one web server rule away from being downloadable, which rebuilds the full source and its history, often with committed credentials. WEB-EXP-001 tests whether it is already reachable; this check finds it before a configuration change exposes it.

/var/www/shop: A .git repository is stored inside the web root

/var/www/shop/.git
Fix
Deploy from a build step that copies only the needed files (git archive, rsync --exclude .git, or a CI artefact), or point the document root at a public/ sub-folder as Laravel, Symfony and Rails expect. Remove the .git folder from the web root and rotate any secret ever committed.
Verify
ls -d <docroot>/.git prints nothing.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-527, CWE-538, OWASP A05:2021, ASVS 12.5.1, NIST 800-53 CM-7, SC-28
References
OWASP WSTG-CONF-04, Review Old Backup and Unreferenced Files
OWASP Secrets Management Cheat Sheet
Learn
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/frameworks.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Framework Writable Folders Open to All Users

WEB-APP-010

Checks Laravel and Symfony cache, log and storage folders for world-write permission.

Why it matters. chmod -R 777 storage is a common fix for permission errors. Laravel's bootstrap/cache and Symfony's var/cache hold compiled PHP that the framework includes on every request, so any local user who can write there runs code as the web server. Logs and sessions in storage are readable and forgeable too.

/srv/shop-laravel/.env: Framework cache or storage folders are world-writable

0777 /srv/shop-laravel/storage
0777 /srv/shop-laravel/bootstrap/cache
Fix
chmod -R o-w storage bootstrap/cache var and give the web server group write access instead: chgrp -R www-data storage bootstrap/cache && chmod -R g+w storage bootstrap/cache.
Verify
find storage bootstrap/cache var -perm -0002 -type d prints nothing.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:L
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, CWE-94, OWASP A05:2021, ASVS 14.1.3, NIST 800-53 AC-3, AC-6, CM-5
References
Laravel documentation, Deployment
Symfony documentation, Setting up or Fixing File Permissions
OWASP WSTG-CONF-09, Test File Permission
Learn
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/frameworks.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Cookies Missing Secure, HttpOnly or SameSite

WEB-CK-001

Checks the security flags on cookies the home page sets.

Why it matters. Without Secure, cookies leak over plain HTTP. Without HttpOnly, any XSS bug can steal sessions. Without SameSite, cross-site request forgery is easier.

shop.example.test: Cookies are missing security flags

PHPSESSID: missing Secure, HttpOnly, SameSite
Fix
PHP: session.cookie_secure=1, session.cookie_httponly=1, session.cookie_samesite=Lax in php.ini . Frameworks have equivalent settings (e.g. Laravel config/session.php). Use HttpOnly for every cookie JavaScript does not need to read.
Verify
curl -sI https://<site>/ | grep -i set-cookie
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:L/A:N
Category
Web Application Security
Effort
Medium
Confidence
High
Standards
CWE-614, CWE-1004, CWE-1275, OWASP A05:2021, A07:2021, ASVS 3.4.1, 3.4.2, 3.4.3, NIST 800-53 SC-8, SC-23
References
OWASP Session Management Cheat Sheet
RFC 6265, HTTP State Management Mechanism
Learn
P5: Web Security Headers and Cookies (offline: openvapt learn P5)
Source
internal/checks/web/transport.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

WordPress Shows Debug Output to Visitors

WEB-CMS-006

Checks wp-config.php for WP_DEBUG enabled without WP_DEBUG_DISPLAY set to false.

Why it matters. With WP_DEBUG on and display not turned off, PHP notices and errors are printed into pages, revealing server paths, plugin names and sometimes database details to anyone browsing the site.

/var/www/shop/wp-config.php: WordPress displays debug output

WP_DEBUG is true and WP_DEBUG_DISPLAY is not false
Fix
In production set define('WP_DEBUG', false);. If you need logs, use define('WP_DEBUG_LOG', '/path/outside/webroot/wp-debug.log'); together with define('WP_DEBUG_DISPLAY', false);.
Verify
grep -E "WP_DEBUG(_DISPLAY)?'" wp-config.php
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-209, CWE-489, OWASP A05:2021, ASVS 14.3.2, NIST 800-53 SI-11
References
WordPress Developer Resources, Debugging in WordPress
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
Source
internal/checks/web/cms_more.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

WordPress Automatic Updates Disabled

WEB-CMS-008

Checks whether wp-config.php turns off WordPress background updates, including security releases.

Why it matters. WordPress ships security fixes as automatic minor updates. Turning the updater off means the site stays vulnerable until someone remembers to update by hand, which is how most compromised WordPress sites fall behind.

/var/www/shop/wp-config.php: WordPress automatic updates are disabled

AUTOMATIC_UPDATER_DISABLED is true
Fix
Remove those lines, or set define('WP_AUTO_UPDATE_CORE', 'minor'); so at least security releases install automatically. Keep backups and enable plugin auto-updates where practical.
Verify
Dashboard, Updates shows that automatic updates for maintenance and security releases are on.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L
Category
Patch and Vulnerability Management
Effort
Low
Confidence
High
Standards
CWE-1104, OWASP A06:2021, ASVS 14.2.1, NIST 800-53 SI-2
References
WordPress Developer Resources, Configuring Automatic Background Updates
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
Source
internal/checks/web/cms_more.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Joomla Debug or Verbose Error Reporting Enabled

WEB-CMS-009

Checks Joomla configuration.php for debug mode or maximum/development error reporting.

Why it matters. Joomla's debug console and verbose error reporting print queries, file paths and configuration details into pages that visitors can see.

/var/www/shop/configuration.php: Joomla debug output is enabled

$debug is enabled
$error_reporting is maximum
Fix
In System, Global Configuration set Debug System to No and Error Reporting to None (or System Default), or set public $debug = false; and public $error_reporting = 'none'; in configuration.php.
Verify
grep -E 'debug|error_reporting' configuration.php
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-209, CWE-489, OWASP A05:2021, ASVS 14.3.2, NIST 800-53 SI-11
References
Joomla Documentation, Security Checklist: Site Administration
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
Source
internal/checks/web/cms_more.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Drupal Trusted Host Patterns Not Set

WEB-CMS-013

Checks Drupal settings.php for the trusted_host_patterns setting.

Why it matters. Without trusted_host_patterns Drupal builds absolute links, including password reset links, from whatever Host header the request carries. An attacker who sends a crafted Host header can poison caches and redirect reset links to a domain they control.

/var/www/shop/sites/default/settings.php: Drupal accepts any Host header

$settings['trusted_host_patterns'] is not set

/var/www/shop/sites/intranet/settings.php: Drupal accepts any Host header

$settings['trusted_host_patterns'] is not set
Fix
Add to settings.php: $settings['trusted_host_patterns'] = ['^www\.example\.com$', '^example\.com$']; then clear caches (drush cr). The status report page should no longer warn about trusted hosts.
Verify
drush status-report | grep -i 'trusted host'
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N
Category
Web Application Security
Effort
Low
Confidence
High
Standards
CWE-644, CWE-346, OWASP A05:2021, ASVS 14.4.1, NIST 800-53 CM-6, SI-10
References
Drupal.org, Trusted Host settings
OWASP WSTG-INPV-17, Testing for Host Header Injection
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/cms_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Magento Not in Production Mode

WEB-CMS-015

Checks app/etc/env.php for a MAGE_MODE other than production.

Why it matters. Developer and default modes show exceptions with stack traces and file paths to shoppers, disable static file signing and compile code on the fly. Adobe documents production as the only mode for a live store.

/var/www/shop/app/etc/env.php: MAGE_MODE is developer

Fix
bin/magento deploy:mode:set production (which also deploys static content and compiles DI), then clear caches. Keep developer mode for staging only.
Verify
bin/magento deploy:mode:show prints production.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-489, CWE-209, OWASP A05:2021, ASVS 14.3.2, NIST 800-53 CM-6, SI-11
References
Adobe Commerce documentation, Set the Magento mode
Adobe Commerce documentation, Security best practices
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/cms_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Ghost Configured With a Plain HTTP Site URL

WEB-CMS-016

Checks Ghost config.production.json for a url that starts with http://.

Why it matters. Ghost builds every link, including the admin login and member sign-in links, from the configured url. With http:// the admin session and members' tokens travel in the clear even when HTTPS is available, and browsers see mixed content.

/srv/shop-blog/config.production.json: Ghost url uses plain http://

Fix
ghost config url https://<your-domain> (or edit config.production.json), set up TLS with ghost setup ssl or your reverse proxy, then ghost restart.
Verify
ghost config get url prints an https:// address.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N
Category
Web Application Security
Effort
Low
Confidence
High
Standards
CWE-319, OWASP A02:2021, A05:2021, ASVS 9.1.1, NIST 800-53 SC-8, CM-6
References
Ghost documentation, Configuration (url)
OWASP Transport Layer Security Cheat Sheet
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/cms_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Cross-Origin Resource Sharing Allows Any Origin With Credentials

WEB-COR-001

Checks the home page's CORS headers for a wildcard origin combined with credentials, or an origin of null.

Why it matters. A permissive CORS policy can let any website read responses on behalf of a logged-in visitor, exposing personal data and tokens.

shop.example.test: Permissive CORS policy

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Fix
Return Access-Control-Allow-Origin only for an explicit allow-list of trusted origins, never '*' or 'null' together with credentials, and add Vary: Origin.
Verify
curl -sI https://<site>/ | grep -i access-control
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N
Category
Web Application Security
Effort
Low
Confidence
High
Standards
CWE-942, OWASP A05:2021, A01:2021, ASVS 14.5.3, NIST 800-53 AC-4, CM-6
References
OWASP WSTG-CLNT-07, Testing Cross Origin Resource Sharing
MDN Web Docs, Access-Control-Allow-Origin
Learn
P5: Web Security Headers and Cookies (offline: openvapt learn P5)
Source
internal/checks/web/docroot.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Archives or Certificates Inside a Web Root

WEB-DOC-003

Lists archives (*.tar.gz, *.tgz, *.tar, *.7z) and certificate files (*.pem, *.crt) inside each web document root for review, outside download folders.

Why it matters. A tarball inside a web root is often a site or database backup left after a migration, and a .pem file sometimes carries the private key next to the certificate. Both are downloadable by anyone who guesses the name. But download sites publish archives on purpose and public certificates are harmless, so this is a Medium review item, not a High finding; names that clearly mean backup, dump or key are rated High by WEB-DOC-001.

/var/www/shop: 2 archive or certificate file(s) inside the web root to review

/var/www/shop/shop-2026.tar.gz (archive; confirm it is a published download, not a site backup)
/var/www/shop/cert.pem (certificate or key material; confirm it holds no private key)
/var/www/shop/downloads/catalogue.tar.gz (in a download folder, expected)
Fix
Confirm each file is meant to be public. Move backups and anything holding a private key outside the document root, rotate any exposed key, and keep published downloads in a dedicated folder such as /downloads/.
Verify
Re-run this check; only files you have confirmed as intended downloads should remain, in a download folder.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-538, CWE-552, OWASP A05:2021, ASVS 12.5.1, NIST 800-53 SC-28, CM-6
References
OWASP WSTG-CONF-04, Review Old Backup and Unreferenced Files for Sensitive Information
OWASP Secrets Management Cheat Sheet
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/docroot.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

PHP Information Page Exposed

WEB-EXP-003

Checks for phpinfo() pages left on the site.

Why it matters. phpinfo() reveals PHP and module versions, file paths, environment variables and sometimes credentials, giving attackers a detailed map of the server.

shop.example.test: Exposed: /phpinfo.php (HTTP 200)

/phpinfo.php (HTTP 200)
Fix
Delete the file. Never leave diagnostic pages on a production server.
Verify
curl -s -o /dev/null -w '%{http_code}' https://<site>/phpinfo.php should print 404.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-497, OWASP A05:2021, ASVS 14.3.2, NIST 800-53 CM-7, SI-11
References
PHP manual, phpinfo()
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Directory Listing Enabled

WEB-EXP-005

Checks whether the web server lists folder contents when there is no index page.

Why it matters. Directory listings reveal every file in a folder, including backups, uploads and scripts never meant to be linked.

shop.example.test: Exposed: /uploads/ (HTTP 200)

/uploads/ (HTTP 200)
Fix
Apache: Options -Indexes . nginx: autoindex off; (the default). Add an empty index.html to folders that must stay browsable-free.
Verify
curl -s https://<site>/uploads/ | grep -i 'index of' should print nothing.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-548, OWASP A01:2021, A05:2021, ASVS 4.3.2, NIST 800-53 CM-7, AC-3
References
Apache HTTP Server, Options directive
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Web Server Status Page Exposed

WEB-EXP-006

Checks whether Apache server-status/server-info or nginx stub_status are reachable for each site.

Why it matters. Status pages show live requests (including URLs with tokens), client IPs, virtual hosts and modules.

shop.example.test: Exposed: /server-status (HTTP 200), no local-only restriction (Require local, Require ip 127.0.0.1 or allow 127.0.0.1 with deny all) found in the web server configuration; the scan requests from 127.0.0.1, so confirm from another machine

/server-status (HTTP 200)
no local-only restriction (Require local, Require ip 127.0.0.1 or allow 127.0.0.1 with deny all) found in the web server configuration; the scan requests from 127.0.0.1, so confirm from another machine
Fix
Restrict to administrators: <Location /server-status> Require local </Location> (Apache), or allow 127.0.0.1; deny all; (nginx). Remove the module if unused.
Verify
From another machine: curl -s -o /dev/null -w '%{http_code}' https://<site>/server-status should print 403 or 404.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-497, OWASP A05:2021, ASVS 14.3.2, NIST 800-53 CM-7, SI-11
References
Apache HTTP Server, mod_status
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Database Administration Tool Exposed

WEB-EXP-011

Checks whether phpMyAdmin or Adminer login pages are publicly reachable.

Why it matters. Database admin tools are among the most attacked paths on the internet: they invite password guessing and their own vulnerabilities give direct database access.

shop.example.test: Exposed: /phpmyadmin/ (HTTP 200)

/phpmyadmin/ (HTTP 200)
Fix
Remove the tool, or restrict it to administrators by IP allow-list, VPN or an extra authentication layer, and keep it updated.
Verify
From outside your network, the paths should return 403 or 404.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-1188, CWE-306, OWASP A05:2021, A07:2021, NIST 800-53 CM-7, AC-3
References
OWASP WSTG-CONF-05, Enumerate Infrastructure and Application Admin Interfaces
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Missing HTTP Strict Transport Security (HSTS)

WEB-HDR-001

Checks that HTTPS sites tell browsers to always use HTTPS, for at least six months.

Why it matters. Without HSTS, the first visit or any typed http:// link can be intercepted and downgraded to plain HTTP (SSL stripping) on public Wi-Fi.

shop.example.test: Strict-Transport-Security header is missing

Fix
Apache: Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" . nginx: add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; . Only add 'preload' once every subdomain supports HTTPS.
Verify
curl -sI https://<site>/ | grep -i strict-transport-security
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:L/A:N
Category
Web Application Security
Effort
Low
Confidence
High
Standards
CWE-319, CWE-523, OWASP A05:2021, ASVS 14.4.5, NIST 800-53 SC-8
References
RFC 6797, HTTP Strict Transport Security
OWASP HTTP Headers Cheat Sheet
MDN Web Docs, Strict-Transport-Security
Learn
P4: TLS, Certificates and HTTPS (offline: openvapt learn P4)
A8: Tracing Findings to Security Requirements (offline: openvapt learn A8)
Source
internal/checks/web/headers.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Missing Content Security Policy

WEB-HDR-002

Checks that each site sends a Content-Security-Policy header.

Why it matters. A CSP limits where scripts may load from, turning many cross-site scripting (XSS) bugs from account takeover into a blocked request.

shop.example.test: Content-Security-Policy header is missing

Fix
Start with a report-only policy to find what the site loads, then enforce, for example: Content-Security-Policy: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'
Verify
curl -sI https://<site>/ | grep -i content-security-policy
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
Category
Web Application Security
Effort
Medium
Confidence
High
Standards
CWE-1021, CWE-79, OWASP A03:2021, A05:2021, ASVS 14.4.3, NIST 800-53 SI-10
References
OWASP Content Security Policy Cheat Sheet
W3C Content Security Policy Level 3
Learn
P5: Web Security Headers and Cookies (offline: openvapt learn P5)
A8: Tracing Findings to Security Requirements (offline: openvapt learn A8)
Source
internal/checks/web/headers.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Site Can Be Framed (Clickjacking)

WEB-HDR-003

Checks that each site forbids being embedded in other sites' frames.

Why it matters. If a page can be framed, an attacker can overlay it invisibly and trick users into clicking buttons (clickjacking), such as 'delete' or 'transfer'.

shop.example.test: Neither X-Frame-Options nor CSP frame-ancestors is set

Fix
Send Content-Security-Policy: frame-ancestors 'self' (modern) and X-Frame-Options: SAMEORIGIN (older browsers).
Verify
curl -sI https://<site>/ | grep -Ei 'x-frame-options|frame-ancestors'
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N
Category
Web Application Security
Effort
Low
Confidence
High
Standards
CWE-1021, OWASP A04:2021, ASVS 14.4.7, NIST 800-53 SC-18
References
OWASP Clickjacking Defense Cheat Sheet
MDN Web Docs, X-Frame-Options
Learn
P5: Web Security Headers and Cookies (offline: openvapt learn P5)
A8: Tracing Findings to Security Requirements (offline: openvapt learn A8)
Source
internal/checks/web/headers.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

nginx Directory Listing Enabled in Configuration

WEB-NGX-002

An nginx server or location block sets autoindex on.

Why it matters. Directory listings publish every file in a folder, including uploads, backups and scripts that were never linked. The configuration view finds this even for folders the probe check did not request.

/etc/nginx/nginx.conf: An nginx server or location block sets autoindex on.

/etc/nginx/nginx.conf: autoindex on
Fix
Remove autoindex on; or set autoindex off; in that block. Where a listing is really needed, protect the location with auth_basic or an allow list.
Verify
nginx -T | grep -n autoindex should show only off or nothing.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-548, OWASP A01:2021, A05:2021, ASVS 4.3.2, NIST 800-53 CM-7, AC-3
References
nginx documentation, ngx_http_autoindex_module
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

nginx Serves Hidden Files and Folders

WEB-NGX-007

No location block denies paths that begin with a dot, so .git, .env, .svn and .htaccess files under the document root are served if present.

Why it matters. Dot files hold repository history, credentials and server rules. One deny rule for every path segment starting with a dot removes a whole class of leaks, including files deployed by mistake later.

/etc/nginx/nginx.conf: No location block denies paths that begin with a dot, so .git, .env, .svn and .htaccess files under the document root are served if present.

no  location ~ /\.  block found
Fix
Add to every server block: location ~ /\. { deny all; access_log off; log_not_found off; } and keep .well-known reachable with a more specific location ^~ /.well-known/ block before it.
Verify
curl -s -o /dev/null -w '%{http_code}' https://<site>/.git/HEAD should print 403 or 404.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-538, CWE-527, OWASP A05:2021, ASVS 12.5.1, 14.3.3, NIST 800-53 CM-7, SC-28
References
nginx documentation, ngx_http_core_module
OWASP WSTG-CONF-04, Review Old Backup and Unreferenced Files
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

PHP Displays Errors to Visitors

WEB-PHP-001

Checks whether PHP prints error messages into web pages.

Why it matters. Error messages reveal file paths, SQL queries and code structure, and can leak data. They help attackers turn a small bug into a working exploit.

php: display_errors = 1

Fix
In php.ini set display_errors = Off and log_errors = On , then restart PHP-FPM or the web server.
Verify
php -r "echo ini_get('display_errors');" and check the FPM pool's php.ini or php_admin_value settings.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-209, OWASP A05:2021, ASVS 14.3.2, NIST 800-53 SI-11, CM-6
References
PHP manual, php.ini directives
OWASP PHP Configuration Cheat Sheet
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/php.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

PHP Session Cookies Not Hardened

WEB-PHP-005

Checks PHP's session settings: HttpOnly and SameSite cookies and strict session id mode.

Why it matters. Session cookies are the keys to logged-in accounts. Without HttpOnly any XSS bug can steal them; without strict mode PHP accepts attacker-chosen session ids (session fixation).

php: PHP session cookies are not hardened

session.cookie_httponly = Off
session.use_strict_mode = 0
session.cookie_samesite is empty
Fix
In php.ini set session.cookie_httponly = 1 , session.use_strict_mode = 1 , session.cookie_samesite = Lax and, for HTTPS sites, session.cookie_secure = 1 , then restart PHP-FPM.
Verify
php -r "echo ini_get('session.cookie_httponly'), ini_get('session.use_strict_mode'), ini_get('session.cookie_samesite');"
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:L/A:N
Category
Web Application Security
Effort
Low
Confidence
High
Standards
CWE-1004, CWE-384, OWASP A07:2021, ASVS 3.4.2, 3.2.1, NIST 800-53 SC-23, CM-6
References
PHP manual, php.ini directives
PHP manual, Session security
Learn
P5: Web Security Headers and Cookies (offline: openvapt learn P5)
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/php.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Django Accepts Any Host Header

WEB-PY-002

Checks Django settings for ALLOWED_HOSTS = ['*'].

Why it matters. ALLOWED_HOSTS protects against Host header attacks. With a wildcard, an attacker can make Django build password-reset and other absolute links that point at the attacker's domain, and can poison shared caches.

/srv/shopadmin/shopadmin: Django accepts any Host header

/srv/shopadmin/shopadmin/settings.py: ALLOWED_HOSTS allows any host
Fix
List the real domain names: ALLOWED_HOSTS = ['example.com', 'www.example.com'], and restart the application.
Verify
python manage.py check --deploy
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N
Category
Web Application Security
Effort
Low
Confidence
High
Standards
CWE-346, OWASP A05:2021, NIST 800-53 CM-6, SI-10
References
Django documentation, Deployment checklist
Django settings reference, ALLOWED_HOSTS
Learn
P13: Application Servers: Tomcat, Node.js and Python (offline: openvapt learn P13)
Source
internal/checks/web/runtimes.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Python Development Server Used in a Service

WEB-PY-005

Checks whether a service runs a development web server such as manage.py runserver, flask run or python -m http.server.

Why it matters. Development servers are documented as unsuitable for production: they have not been security-audited, handle load and slow clients poorly and often run with debugging features. python -m http.server publishes a whole folder.

systemd units: Services run Python development servers

shop-admin.service: runs a development server (manage.py runserver)
shop-reports.service: runs a development server (flask run)
Fix
Serve the application with a production server (Gunicorn or uWSGI for WSGI, Uvicorn without --reload or Hypercorn for ASGI) bound to 127.0.0.1, behind nginx or Apache. Serve static files from the web server.
Verify
systemctl show -p ExecStart <unit> shows a production server.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:L
Category
Secure Configuration
Effort
Medium
Confidence
High
Standards
CWE-489, CWE-1188, OWASP A05:2021, ASVS 14.3.2, NIST 800-53 CM-7
References
Django documentation, django-admin runserver (not for production)
Flask documentation, Deploying to Production
Learn
P13: Application Servers: Tomcat, Node.js and Python (offline: openvapt learn P13)
Source
internal/checks/web/runtimes.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Site Available Over Plain HTTP Without Redirect

WEB-TLS-001

Checks that every site redirects http:// requests to https://.

Why it matters. Pages served over plain HTTP can be read and changed by anyone on the network path, including injected malware and stolen session cookies.

shop.example.test: Site content is served over plain HTTP

HTTP status 200
Fix
Apache: in the port 80 vhost add Redirect permanent / https://<site>/ . nginx: return 301 https://$host$request_uri; . Get a free certificate with certbot if HTTPS is not set up yet.
Verify
curl -sI http://<site>/ should show a 301 with Location: https://...
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:L/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-319, OWASP A02:2021, ASVS 9.1.1, NIST 800-53 SC-8
References
OWASP Transport Layer Security Cheat Sheet
Learn
P4: TLS, Certificates and HTTPS (offline: openvapt learn P4)
Source
internal/checks/web/transport.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Tomcat Shutdown Port Uses the Default Command

WEB-TOM-003

Checks whether Tomcat's shutdown port is enabled with the well-known default command SHUTDOWN.

Why it matters. Anyone who can connect to the shutdown port (8005 by default) and send the shutdown string stops Tomcat. With the default string, every local user and every compromised process on the machine can take the applications offline.

/etc/tomcat9: Tomcat shutdown port uses the default command

<Server port="8005" shutdown="SHUTDOWN">
Fix
Disable the port with <Server port="-1" ...> and stop Tomcat through systemd, or set shutdown to a long random string. Restart Tomcat.
Verify
grep '<Server' <conf>/server.xml shows port="-1".
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, OWASP A05:2021, NIST 800-53 CM-6, CM-7
References
Apache Tomcat 10.1, Security Considerations
Apache Tomcat 10.1 Configuration Reference, The Server Component
Learn
P13: Application Servers: Tomcat, Node.js and Python (offline: openvapt learn P13)
Source
internal/checks/web/tomcat.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

MEDIUM

Tomcat Example and Documentation Applications Deployed

WEB-TOM-005

Checks whether the examples or docs web applications that ship with Tomcat are deployed.

Why it matters. The sample applications are written to demonstrate features, not to be safe. Some (such as the session example) let visitors change server-side session data, and all of them reveal the exact Tomcat version.

/etc/tomcat9: Tomcat sample applications are deployed

/var/lib/tomcat9/webapps/examples is deployed
Fix
Delete the examples and docs folders from webapps (or apt remove tomcatN-examples tomcatN-docs) and restart Tomcat.
Verify
ls <webapps> lists only your own applications (and ROOT).
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-1188, OWASP A05:2021, NIST 800-53 CM-7
References
Apache Tomcat 10.1, Security Considerations
OWASP WSTG-CONF-02, Test Application Platform Configuration
Learn
P13: Application Servers: Tomcat, Node.js and Python (offline: openvapt learn P13)
Source
internal/checks/web/tomcat.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Audit Daemon Not Enabled at Boot

HOST-AUD-001

Checks that the audit daemon (auditd) is set to start at every boot, not only running now.

Why it matters. An audit daemon that was started by hand stops recording at the next reboot, leaving a gap exactly when an attacker who forced a restart would want one. HOST-LOG-002 reports whether auditd is running; this check reports whether it will come back.

auditd: auditd is disabled, so it will not record after the next reboot

Fix
systemctl enable auditd (on some distributions: systemctl enable --now auditd). Then confirm the rules in /etc/audit/rules.d load at boot with augenrules --check.
Verify
systemctl is-enabled auditd should print enabled.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-778, OWASP A09:2021, NIST 800-53 AU-2, AU-12
References
auditd(8), Linux man-pages
NIST SP 800-92, Guide to Computer Security Log Management
Learn
P21: Audit Logging and Monitoring Depth (offline: openvapt learn P21)
Source
internal/checks/host/audit_journal.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Identity Files Not Audited

HOST-AUD-002

Checks that changes to the account, group, password and sudo files are recorded by the audit system.

Why it matters. An attacker who adds an account, joins a privileged group or grants themselves sudo edits one of a handful of files. A watch rule on each makes that change an audit event with the user, process and time attached; without it the change leaves no trace beyond the file itself.

audit rules: Audit rules are missing

no watch on /etc/passwd
no watch on /etc/group
no watch on /etc/shadow
no watch on /etc/gshadow
no watch on /etc/sudoers
no watch on /etc/sudoers.d
Fix
Add to /etc/audit/rules.d/50-identity.rules: -w /etc/passwd -p wa -k identity and the same for /etc/group, /etc/shadow, /etc/gshadow, /etc/sudoers and /etc/sudoers.d/ , then run augenrules --load.
Verify
auditctl -l | grep -E 'passwd|shadow|sudoers'
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-778, OWASP A09:2021, NIST 800-53 AU-2, AU-12, AC-2(4)
References
auditctl(8), Linux man-pages
NIST SP 800-92, Guide to Computer Security Log Management
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P21: Audit Logging and Monitoring Depth (offline: openvapt learn P21)
Source
internal/checks/host/audit_journal.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Login and Logout Events Not Audited

HOST-AUD-003

Checks that the files recording logins, failed logins and sessions are watched by the audit system.

Why it matters. Login records are the first thing an investigator asks for and the first thing an intruder cleans. Watching lastlog, the failed-login store and the wtmp and btmp session files makes tampering itself an audit event.

audit rules: Audit rules are missing

no watch on /var/log/lastlog
no watch on the failed-login store (/var/run/faillock or /var/log/faillog)
no watch on /var/log/wtmp
no watch on /var/log/btmp
Fix
Add to /etc/audit/rules.d/50-login.rules: -w /var/log/lastlog -p wa -k logins , -w /var/run/faillock -p wa -k logins , -w /var/log/wtmp -p wa -k session , -w /var/log/btmp -p wa -k session , then augenrules --load.
Verify
auditctl -l | grep -E 'lastlog|faillock|wtmp|btmp'
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-778, OWASP A09:2021, NIST 800-53 AU-2, AU-12, AC-7
References
auditctl(8), Linux man-pages
NIST SP 800-92, Guide to Computer Security Log Management
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P21: Audit Logging and Monitoring Depth (offline: openvapt learn P21)
Source
internal/checks/host/audit_journal.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

System Time Changes Not Audited

HOST-AUD-004

Checks that the audit system records changes to the system clock and time zone.

Why it matters. Moving the clock is a classic way to confuse log timelines, forge timestamps or defeat certificate and token expiry. Auditing the time-setting system calls and /etc/localtime attributes every change to a user and process.

audit rules: Audit rules are missing

no rule for system call adjtimex
no rule for system call settimeofday
no rule for system call clock_settime
no watch on /etc/localtime
Fix
Add to /etc/audit/rules.d/50-time.rules: -a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -k time-change (and the same with arch=b32), plus -w /etc/localtime -p wa -k time-change , then augenrules --load.
Verify
auditctl -l | grep -E 'settimeofday|localtime'
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-778, OWASP A09:2021, NIST 800-53 AU-2, AU-8, AU-12
References
auditctl(8), Linux man-pages
NIST SP 800-92, Guide to Computer Security Log Management
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P21: Audit Logging and Monitoring Depth (offline: openvapt learn P21)
Source
internal/checks/host/audit_journal.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Kernel Module Loading Not Audited

HOST-AUD-005

Checks that loading and unloading kernel modules is recorded by the audit system.

Why it matters. A rootkit is usually a kernel module. Auditing init_module, finit_module and delete_module (or the kmod program) records the moment one is loaded, which is often the only evidence that survives.

audit rules: Audit rules are missing

no rule for init_module and delete_module, and no rule on the kmod program
Fix
Add to /etc/audit/rules.d/50-modules.rules: -a always,exit -F arch=b64 -S init_module,finit_module,delete_module -k modules (and arch=b32), or -a always,exit -F path=/usr/bin/kmod -F perm=x -F auid>=1000 -F auid!=unset -k modules , then augenrules --load.
Verify
auditctl -l | grep -E 'init_module|kmod'
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-778, OWASP A09:2021, NIST 800-53 AU-2, AU-12, CM-7
References
auditctl(8), Linux man-pages
NIST SP 800-92, Guide to Computer Security Log Management
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P21: Audit Logging and Monitoring Depth (offline: openvapt learn P21)
Source
internal/checks/host/audit_journal.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Privileged Command Use Not Audited

HOST-AUD-006

Checks that the audit system records when ordinary users run privileged (setuid or setgid) programs.

Why it matters. Programs such as sudo, su, passwd and mount run with elevated rights. Recording each execution by a real user (auid at or above the first normal user id) shows who used privilege and when, which is the core of a usable audit trail.

audit rules: Audit rules are missing

no execution rule with perm=x and an auid>= filter
Fix
Generate rules for every setuid and setgid program: find / -xdev \( -perm -4000 -o -perm -2000 \) -type f | awk '{print "-a always,exit -F path=" $1 " -F perm=x -F auid>=1000 -F auid!=unset -k privileged"}' > /etc/audit/rules.d/50-privileged.rules then augenrules --load.
Verify
auditctl -l | grep 'perm=x'
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-778, OWASP A09:2021, NIST 800-53 AU-2, AU-12, AC-6(9)
References
auditctl(8), Linux man-pages
NIST SP 800-92, Guide to Computer Security Log Management
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P21: Audit Logging and Monitoring Depth (offline: openvapt learn P21)
Source
internal/checks/host/audit_journal.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Audit Configuration Not Immutable

HOST-AUD-007

Checks that the audit rule set ends with -e 2, which locks the rules until the next reboot.

Why it matters. Without the immutable flag, anyone who gains root can delete the audit rules (auditctl -D) and work unobserved. With -e 2 the rules can only be changed by rebooting, which is itself a loud, logged event.

audit rules: Audit rules are missing

last rule is not -e 2 (found: -f 1)
Fix
Add -e 2 as the last line of the last file in /etc/audit/rules.d (for example 99-finalize.rules), then augenrules --load and reboot. Plan rule changes before enabling it: every later change needs a reboot.
Verify
auditctl -s | grep enabled should print enabled 2.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-778, OWASP A09:2021, NIST 800-53 AU-9, AU-12
References
auditctl(8), Linux man-pages
NIST SP 800-92, Guide to Computer Security Log Management
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P21: Audit Logging and Monitoring Depth (offline: openvapt learn P21)
Source
internal/checks/host/audit_journal.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Audit Log Files Readable by Others

HOST-AUD-008

Checks that the audit log directory and files can be read only by root.

Why it matters. Audit logs record which user ran which command with which arguments, including file names and sometimes secrets passed on a command line. They are also the record an intruder most wants to edit. Both reasons call for root-only access.

/var/log/audit: Audit logs are accessible beyond root

directory /var/log/audit mode 0755 uid 0 (need 0750 or stricter, owned by root)
/var/log/audit/audit.log mode 0644 uid 0 (need 0640 or stricter, owned by root)
Fix
chmod 0750 /var/log/audit && chmod 0600 /var/log/audit/* && chown -R root:root /var/log/audit , and set log_group = root in /etc/audit/auditd.conf so new files keep these modes.
Verify
stat -c '%a %U %n' /var/log/audit /var/log/audit/*
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-532, CWE-732, OWASP A09:2021, NIST 800-53 AU-9, AC-6
References
auditd.conf(5), Linux man-pages
NIST SP 800-92, Guide to Computer Security Log Management
Learn
P21: Audit Logging and Monitoring Depth (offline: openvapt learn P21)
Source
internal/checks/host/audit_journal.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Audit Daemon Ignores a Full Log Disk

HOST-AUD-009

Checks that auditd is told what to do when its log file is full or the disk runs low, rather than silently dropping events.

Why it matters. With max_log_file_action = ignore the log grows until the disk is full; with suspend auditing simply stops. An unset space_left_action means nobody is warned before that happens. Either way an attacker who fills the disk switches auditing off.

/etc/audit/auditd.conf: auditd will drop or stop auditing when the log disk fills

max_log_file_action = ignore
space_left_action = ignore
admin_space_left_action is not set
Fix
In /etc/audit/auditd.conf set max_log_file_action = keep_logs (or rotate with enough num_logs), space_left_action = email (or syslog or exec), and admin_space_left_action = halt or single as policy requires, then systemctl restart auditd. Caution: admin_space_left_action = halt or single stops the server or drops it to single-user mode when the audit disk fills; choose it only where losing audit records is worse than downtime, and give /var/log/audit room and monitoring first.
Verify
grep -E '^(max_log_file_action|space_left_action|admin_space_left_action)' /etc/audit/auditd.conf
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-778, OWASP A09:2021, NIST 800-53 AU-4, AU-5
References
auditd.conf(5), Linux man-pages
NIST SP 800-92, Guide to Computer Security Log Management
Learn
P21: Audit Logging and Monitoring Depth (offline: openvapt learn P21)
Source
internal/checks/host/audit_journal.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Journal Not Persistent or Not Compressed

HOST-AUD-010

Checks that systemd-journald is configured to keep the journal on disk and to compress it.

Why it matters. Storage=volatile keeps the journal only in memory, so a reboot (or a crash an attacker caused) erases the evidence. Compression keeps a persistent journal small enough to retain for weeks. HOST-LOG-001 looks for the journal directory; this check reads the configuration that decides what happens to it.

journald.conf: The journal is not kept persistently and compressed

Storage=volatile (/etc/systemd/journald.conf): the journal is lost at reboot
Compress=no (/etc/systemd/journald.conf)
Fix
In /etc/systemd/journald.conf set Storage=persistent and Compress=yes , create the directory with mkdir -p /var/log/journal && systemd-tmpfiles --create --prefix /var/log/journal , then systemctl restart systemd-journald.
Verify
journalctl --header | head and ls -d /var/log/journal
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-778, OWASP A09:2021, NIST 800-53 AU-4, AU-9, AU-11
References
journald.conf(5), systemd
NIST SP 800-92, Guide to Computer Security Log Management
Learn
P21: Audit Logging and Monitoring Depth (offline: openvapt learn P21)
Source
internal/checks/host/audit_journal.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Logs Not Forwarded to a Remote Collector

HOST-AUD-011

Checks that system logs are sent to another machine, so an intruder with root cannot erase the only copy.

Why it matters. Whoever gains root on a server can delete or edit its local logs. A copy that already left the machine, to a log server or a SIEM, is the record an investigation can trust. NIST SP 800-92 treats centralised log collection as a basic log management control.

syslog: No remote log destination is configured; the only copy of the logs is on this machine

Fix
rsyslog: create /etc/rsyslog.d/90-remote.conf with *.* action(type="omfwd" target="logs.example.internal" port="6514" protocol="tcp" StreamDriver="gtls" StreamDriverMode="1" StreamDriverAuthMode="x509/name") and restart rsyslog. Or configure systemd-journal-upload with URL= pointing at a journal-remote collector. Prefer TLS so logs are not readable in transit.
Verify
grep -rE '^[^#].*@|omfwd' /etc/rsyslog.conf /etc/rsyslog.d/ or grep '^URL=' /etc/systemd/journal-upload.conf
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Logging and Monitoring
Effort
Medium
Confidence
High
Standards
CWE-778, OWASP A09:2021, NIST 800-53 AU-9(2), AU-6, SI-4
References
NIST SP 800-92, Guide to Computer Security Log Management
rsyslog.conf(5), Debian trixie manual pages (forwarding actions)
journal-upload.conf(5), systemd
Learn
P21: Audit Logging and Monitoring Depth (offline: openvapt learn P21)
Source
internal/checks/host/audit_journal.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Kernel Module Loading Unrestricted

HOST-BOOT-005

Checks that the running kernel refuses unsigned modules or has module loading switched off entirely.

Why it matters. A root-level attacker who can load any module owns the kernel: rootkits hide processes and files from every tool on the box. Signature enforcement or kernel.modules_disabled = 1 after boot makes that persistence step fail.

kernel.modules_disabled: Any module can be loaded: modules_disabled = 0 and no signature enforcement or lockdown

Fix
Boot with module.sig_enforce=1 (or lockdown=integrity) on the kernel command line and sign any out-of-tree modules, or set kernel.modules_disabled = 1 from a late boot service once every needed module is loaded (it cannot be turned back on without a reboot).
Verify
sysctl kernel.modules_disabled; cat /sys/module/module/parameters/sig_enforce /sys/kernel/security/lockdown
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U/C:L/I:L/A:L
Category
Secure Configuration
Effort
Medium
Confidence
High
Standards
CWE-1188, NIST 800-53 SI-7, CM-7
References
Linux kernel documentation, Kernel module signing facility
Kernel Self Protection Project, Recommended Settings
Learn
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/boot.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Prelink Installed

HOST-BOOT-007

Checks that the prelink tool is absent, or disabled where the package is still installed.

Why it matters. Prelink rewrites binaries and libraries in place, which changes their hashes and defeats integrity monitoring and package verification, and it weakens address randomisation by fixing load addresses. Modern systems gain nothing from it.

prelink: Prelink is installed

/usr/sbin/prelink
/etc/prelink.conf
Fix
Undo and remove it: prelink -ua && apt purge prelink (or dnf remove prelink). Then re-initialise the integrity database (aide --init).
Verify
command -v prelink should print nothing.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U/C:N/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-344, NIST 800-53 SI-7, CM-7
References
prelink(8), Linux man-pages
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/boot.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Core Dumps Not Restricted

HOST-BOOT-008

Checks that process core dumps are turned off through PAM limits, and through systemd-coredump where the kernel hands dumps to it.

Why it matters. A core dump is a copy of a program's memory, including passwords, keys and session tokens it held. On a server nobody debugs, dumps are only a leak waiting in /var/lib/systemd/coredump or the working directory. HOST-KRN-004 covers setuid programs; this check covers every process.

core dumps: No hard core 0 limit and no systemd-coredump Storage=none

kernel.core_pattern = core
Fix
Add * hard core 0 to /etc/security/limits.conf (or a file in limits.d), set Storage=none and ProcessSizeMax=0 in the [Coredump] section of /etc/systemd/coredump.conf, and keep fs.suid_dumpable = 0.
Verify
grep -E '^\*\s+hard\s+core\s+0' /etc/security/limits.conf /etc/security/limits.d/*; grep -E '^(Storage|ProcessSizeMax)' /etc/systemd/coredump.conf; cat /proc/sys/kernel/core_pattern
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-528, NIST 800-53 SI-11, CM-6, AC-6
References
limits.conf(5), Linux-PAM
coredump.conf(5), systemd
Linux kernel documentation, /proc/sys/kernel
Learn
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/boot.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Docker Container Logs Have No Size Limit

HOST-CTR-005

Checks whether the Docker daemon's default log driver caps log file size and rotation.

Why it matters. With the default json-file driver and no max-size, a chatty or attacked container can fill the disk with its own logs and take the host and every other container down. Bounded, rotated logs also keep evidence manageable for investigations.

/etc/docker/daemon.json: Container logs are unbounded

daemon log-driver json-file (default) has no max-size
3f2a9c1d8e7b: json-file logging without max-size
Fix
Add to /etc/docker/daemon.json: "log-driver": "json-file", "log-opts": {"max-size": "10m", "max-file": "3"} (or use journald) and restart Docker; recreate containers that set their own LogConfig.
Verify
docker info --format '{{.LoggingDriver}}' ; grep -A3 log-opts /etc/docker/daemon.json
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-779, CWE-770, NIST 800-53 AU-4, SC-5, CM-6
References
Docker documentation, Configure logging drivers
NIST SP 800-190, Application Container Security Guide
CIS Docker Benchmark (referenced by recommendation number)
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
A5: Container Runtime Hardening Depth (offline: openvapt learn A5)
Source
internal/checks/host/containers_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Docker Userland Proxy Enabled

HOST-CTR-006

Checks whether the Docker daemon still uses the docker-proxy userland process for published ports.

Why it matters. The userland proxy is a root process per published port that exists only for an old loopback edge case. Hairpin NAT does the same job in the kernel with less code running as root and fewer processes to crash or exploit.

/etc/docker/daemon.json: userland-proxy is not false

Fix
Add "userland-proxy": false to /etc/docker/daemon.json and restart Docker; test that published ports still answer from the host itself.
Verify
ps -C docker-proxy should list nothing after containers are recreated.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:L
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, NIST 800-53 CM-7, CM-6
References
Docker documentation, dockerd daemon reference
CIS Docker Benchmark (referenced by recommendation number)
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
A5: Container Runtime Hardening Depth (offline: openvapt learn A5)
Source
internal/checks/host/containers_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Docker Default Ulimits Not Set

HOST-CTR-007

Checks whether the Docker daemon sets default ulimits (open files and processes) for containers.

Why it matters. Without default limits a container inherits the daemon's generous limits and can exhaust file descriptors or spawn processes until the host starves. Daemon-wide defaults protect every container that forgets to set its own.

/etc/docker/daemon.json: Default ulimits are not set

default-ulimits has no nofile
default-ulimits has no nproc
Fix
Add to /etc/docker/daemon.json: "default-ulimits": {"nofile": {"Name": "nofile", "Hard": 65536, "Soft": 32768}, "nproc": {"Name": "nproc", "Hard": 4096, "Soft": 2048}} and restart Docker; tune the numbers to your workloads.
Verify
docker info | grep -A3 -i ulimit or docker run --rm alpine sh -c 'ulimit -n; ulimit -u' (your own test container)
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-770, NIST 800-53 SC-6, CM-6
References
Docker documentation, dockerd daemon reference
CIS Docker Benchmark (referenced by recommendation number)
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
A5: Container Runtime Hardening Depth (offline: openvapt learn A5)
Source
internal/checks/host/containers_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Docker Content Trust Not Enabled

HOST-CTR-015

Checks whether DOCKER_CONTENT_TRUST=1 is set system-wide so that only signed images are pulled.

Why it matters. Without content trust, docker pull accepts whatever the registry or a tampering proxy returns for a tag. Signature verification makes a substituted image fail to pull instead of running as root on your host.

/etc/environment: DOCKER_CONTENT_TRUST is not set system-wide; unsigned images are accepted

Fix
Add DOCKER_CONTENT_TRUST=1 to /etc/environment (or a file in /etc/profile.d) and sign your own images with docker trust sign; images without signatures then need an explicit --disable-content-trust for a deliberate exception.
Verify
grep -r DOCKER_CONTENT_TRUST /etc/environment /etc/profile.d
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:L/A:N
Category
Secure Configuration
Effort
Medium
Confidence
High
Standards
CWE-494, CWE-347, NIST 800-53 SI-7, CM-14
References
Docker documentation, Content trust in Docker
CIS Docker Benchmark (referenced by recommendation number)
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
A5: Container Runtime Hardening Depth (offline: openvapt learn A5)
Source
internal/checks/host/containers_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Vulnerability Snapshot Outdated or Test Data

HOST-CVE-003

Checks installed packages against an offline vulnerability snapshot.

Why it matters. Known vulnerable package versions can expose a server to documented attacks.

vulnerability snapshot: Snapshot date 2021-01-01. An outdated snapshot misses newer vulnerabilities.

Fix
Install the vendor security update. For a source build, run 'make vulndb' to embed a snapshot generated from OSV and CISA KEV, then rebuild.
Verify
Re-run OpenVAPT after patching and confirm the finding is absent.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Patch and Vulnerability Management
Effort
Medium
Confidence
High
Standards
CWE-1104, OWASP A06:2021, NIST 800-53 SI-2, RA-5
References
OSV vulnerability database
NVD
CISA KEV
Learn
P10: Vulnerability Management: CVE, OSV and Known Exploited Vulnerabilities (offline: openvapt learn P10)
Source
internal/checks/host/cve.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Temporary Filesystems Allow Executables or Devices

HOST-FS-008

Checks that /tmp, /var/tmp and /dev/shm are mounted with nodev and nosuid.

Why it matters. World-writable temporary areas are where attackers drop tools. nosuid stops planted setuid programs working there, and nodev stops device files being created.

/tmp: /tmp is mounted without nodev, nosuid

options rw,relatime

/dev/shm: /dev/shm is mounted without nodev, nosuid

options rw
Fix
Mount the path as tmpfs or a separate filesystem with options nodev,nosuid (and noexec where software allows), for example via systemd tmp.mount or /etc/fstab, then remount.
Verify
findmnt -no OPTIONS /tmp /var/tmp /dev/shm
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Medium
Confidence
High
Standards
CWE-276, NIST 800-53 CM-6, CM-7
References
mount(8), Linux man-pages (nodev, nosuid, noexec)
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Default File Creation Mask Too Permissive

HOST-FS-009

Checks that the default umask makes new files unreadable to other users (027 or stricter).

Why it matters. With umask 022 every new file is readable by every local user, including configuration exports, reports and backups created by administrators.

/etc/login.defs: UMASK 022 lets other users read new files (recommended 027)

Fix
Set UMASK 027 in /etc/login.defs (and, if used, in /etc/profile or /etc/bash.bashrc).
Verify
grep '^UMASK' /etc/login.defs
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-276, NIST 800-53 AC-6, CM-6
References
login.defs(5), Linux man-pages
umask(2), Linux man-pages
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

/var/tmp Not a Separate Filesystem

HOST-FS-010

Checks that /var/tmp is its own mount (or a bind mount of /tmp) with nodev, nosuid and noexec.

Why it matters. /var/tmp is world-writable and survives reboots. On the root filesystem it can be filled to exhaust disk space, and it accepts planted device files and executables unless mounted with restricting options.

/var/tmp: /var/tmp is not a separate filesystem (it lives on the root filesystem)

Fix
Mount /var/tmp as a separate filesystem, or bind-mount it onto /tmp: /tmp /var/tmp none bind,nodev,nosuid,noexec 0 0 in /etc/fstab, then reboot or remount. Caution: /var/tmp is meant to survive reboots and some installers and databases run programs from it, so check what uses it before binding it to /tmp with noexec, and keep console access when editing /etc/fstab (a wrong line can stop the boot).
Verify
findmnt -no TARGET,OPTIONS /var/tmp
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:L
Category
Secure Configuration
Effort
Medium
Confidence
High
Standards
CWE-276, NIST 800-53 CM-6, CM-7, SC-5
References
mount(8), Linux man-pages (nodev, nosuid, noexec)
proc(5), Linux man-pages (/proc/[pid]/mounts)
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/files_mounts.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

/home Not a Separate Filesystem With nodev

HOST-FS-011

Checks that user home directories live on their own mount with nodev (and nosuid where practical).

Why it matters. Users control the contents of /home. A separate mount stops a user filling the root filesystem, and nodev stops device files being created in a home directory to reach raw disks or memory.

/home: /home is not a separate filesystem (it lives on the root filesystem)

Fix
Place /home on its own partition or logical volume and add nodev,nosuid to its options in /etc/fstab; remount with: mount -o remount /home . Caution: moving /home to a new volume needs a backup, a maintenance window and console access; a wrong /etc/fstab line can stop the boot.
Verify
findmnt -no TARGET,OPTIONS /home
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:L
Category
Secure Configuration
Effort
Medium
Confidence
High
Standards
CWE-276, NIST 800-53 CM-6, CM-7, SC-5
References
mount(8), Linux man-pages (nodev, nosuid, noexec)
proc(5), Linux man-pages (/proc/[pid]/mounts)
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/files_mounts.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Log Directories on the Root Filesystem

HOST-FS-012

Checks that /var/log (or /var) is a separate filesystem so runaway logging cannot fill the root disk.

Why it matters. Logs grow under attacker influence (failed logins, scanner noise). When they share the root filesystem, filling them stops the whole server, and when the disk is full new security events are lost.

/var/log: /var/log is not a separate filesystem (it lives on the root filesystem)

Fix
Place /var/log (and ideally /var/log/audit) on its own partition or logical volume, listed in /etc/fstab with nodev,nosuid,noexec. Caution: moving log directories needs a backup, a maintenance window and console access; stop the logging services while copying, and a wrong /etc/fstab line can stop the boot.
Verify
findmnt -no TARGET,OPTIONS /var/log /var
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:L
Category
Secure Configuration
Effort
Medium
Confidence
High
Standards
CWE-770, NIST 800-53 CM-6, CM-7, SC-5
References
mount(8), Linux man-pages (nodev, nosuid, noexec)
proc(5), Linux man-pages (/proc/[pid]/mounts)
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/files_mounts.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Temporary Filesystems Allow Executables

HOST-FS-013

Checks that /tmp, /var/tmp and /dev/shm, where they are separate mounts, carry the noexec option.

Why it matters. Attackers who gain a foothold download tools into a world-writable temporary directory and run them from there. noexec makes that step fail and forces noisier workarounds.

/tmp: /tmp allows executables

options rw,relatime

/dev/shm: /dev/shm allows executables

options rw
Fix
Add noexec to the mount options of each temporary filesystem (systemd tmp.mount drop-in or /etc/fstab) and remount. Some package managers need exec on /tmp during installs; set TMPDIR for them rather than removing noexec.
Verify
findmnt -no TARGET,OPTIONS /tmp /var/tmp /dev/shm
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Secure Configuration
Effort
Medium
Confidence
High
Standards
CWE-276, NIST 800-53 CM-6, CM-7
References
mount(8), Linux man-pages (nodev, nosuid, noexec)
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/files_mounts.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Files With No Known Owner or Group

HOST-FS-015

Looks for files whose owner or group id no longer appears in /etc/passwd or /etc/group.

Why it matters. When an account is deleted, its files keep the numeric id. The next account created with that id silently inherits them, which can hand a new user old keys, scripts or cron jobs.

filesystem: 1 file(s) have an unknown owner or group

uid=1003 gid=1003 /opt/legacy/app.bin (no such user or group)
Fix
Decide who should own each listed file and apply chown <user>:<group> <path>, or remove files that belonged to a deleted account after checking their contents.
Verify
find /etc /usr/local /opt /srv /var/www /home -xdev \( -nouser -o -nogroup \) should print nothing.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:N
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-282, NIST 800-53 AC-2, AC-6, CM-6
References
NIST SP 800-123, Guide to General Server Security
passwd(5), Linux man-pages
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/files_mounts.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Kernel Symbol Map or Initial RAM Disk Readable by Others

HOST-FS-018

Checks that /boot/System.map-* and the initial RAM disk images are not readable by every user.

Why it matters. System.map lists every kernel symbol address, which defeats kptr_restrict and helps kernel exploits. An initial RAM disk can embed network credentials, disk-unlock key files or custom scripts that should not be world-readable.

/boot: 1 boot file(s) are readable by others

0644 /boot/System.map-4.15.0-20-generic
Fix
chmod 600 /boot/System.map-* /boot/initrd* /boot/initramfs* and, on Debian family systems, set UMASK=0077 in /etc/initramfs-tools/initramfs.conf so new images are created private.
Verify
stat -c '%a %n' /boot/System.map-* /boot/initrd*
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-497, CWE-732, NIST 800-53 AC-3, AC-6
References
Linux kernel documentation, /proc/sys/kernel
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/files_mounts.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Cron and At Not Restricted to Allowed Users

HOST-FS-019

Checks that cron.allow and at.allow exist, are private to root, and that the deny lists are not relied upon instead.

Why it matters. By default every local account may schedule jobs. A deny list only names known accounts; an allow list says exactly who may schedule, which is what least privilege asks for and what makes persistence by a compromised service account harder.

/etc/cron.allow: /etc/cron.allow does not exist; only /etc/cron.deny limits who may schedule cron jobs

/etc/at.allow: /etc/at.allow does not exist; only /etc/at.deny limits who may schedule at jobs

Fix
Create the allow lists: touch /etc/cron.allow /etc/at.allow && chmod 600 /etc/cron.allow /etc/at.allow && chown root:root /etc/cron.allow /etc/at.allow then add one user name per line for the accounts that need scheduling, and remove /etc/cron.deny and /etc/at.deny. Caution: once cron.allow exists, crontabs of users not listed stop running, so list every service and user account that has a crontab (ls /var/spool/cron/crontabs or /var/spool/cron) before creating it.
Verify
stat -c '%a %U %n' /etc/cron.allow /etc/at.allow; ls /etc/cron.deny /etc/at.deny 2>&1
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-862, NIST 800-53 AC-6, CM-7
References
crontab(1), Linux man-pages (cron.allow and cron.deny)
at(1), Linux man-pages (at.allow and at.deny)
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/files_mounts.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Cron Configuration Readable by Other Users

HOST-FS-020

Checks that /etc/crontab is mode 600 and the cron.d, cron.hourly, cron.daily, cron.weekly and cron.monthly directories are mode 700, all owned by root.

Why it matters. Readable cron configuration tells a local attacker exactly which scripts root runs and when, which is the reconnaissance step before replacing one of them. HOST-FS-005 stops writing; this check stops reading.

cron: 1 cron path(s) are readable by group or others

0666 uid=0 /etc/crontab
Fix
chown root:root /etc/crontab /etc/cron.* && chmod 600 /etc/crontab && chmod 700 /etc/cron.d /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly
Verify
stat -c '%a %U %n' /etc/crontab /etc/cron.*
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, NIST 800-53 AC-3, AC-6
References
crontab(5), Linux man-pages
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/files_mounts.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Shell Profile Sets a Permissive File Creation Mask

HOST-FS-021

Checks that system-wide shell start-up files do not set a umask that leaves new files readable by every user.

Why it matters. A umask line in /etc/profile or /etc/bash.bashrc overrides the login.defs default for every interactive shell. Many distributions still ship umask 022 there, which makes every file an administrator creates readable by all local accounts.

/etc/profile: 1 shell file(s) set a umask that lets other users read new files

/etc/profile: umask 022
Fix
Change every umask 022 line in the listed files to umask 027, or remove the line so the login.defs value applies. Users start a new login shell to pick it up.
Verify
grep -rn '^[[:space:]]*umask' /etc/profile /etc/bash.bashrc /etc/bashrc /etc/profile.d/ 2>/dev/null
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-276, NIST 800-53 AC-6, CM-6
References
umask(2), Linux man-pages
login.defs(5), Linux man-pages
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/files_mounts.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

No Brute-Force Protection Service

HOST-IDS-001

Checks that a log-based intrusion prevention service (fail2ban, sshguard or CrowdSec) is running.

Why it matters. Internet-facing services receive constant guessing. Automatically blocking sources that fail repeatedly reduces noise and risk, and turns logs into active defence.

ids: No brute-force protection service is active

Fix
Install and enable one, for example: apt install fail2ban && systemctl enable --now fail2ban , with an sshd jail enabled.
Verify
systemctl is-active fail2ban
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-307, OWASP A07:2021, NIST 800-53 SI-4, AC-7
References
fail2ban project
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P16: Logging, Auditing and Time (offline: openvapt learn P16)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Kernel Pointers Exposed to Unprivileged Users

HOST-KRN-002

Checks that kernel memory addresses are hidden from normal users.

Why it matters. Leaked kernel addresses defeat kernel ASLR and are the first step of most local kernel exploits.

kernel.kptr_restrict: kernel.kptr_restrict = 0 (hardened value: 1)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.kptr_restrict = 1 then apply with: sysctl --system
Verify
sysctl kernel.kptr_restrict should print 1.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-497, NIST 800-53 CM-6, SI-16
References
Linux kernel documentation, /proc/sys/kernel
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Kernel Log Readable by Unprivileged Users

HOST-KRN-003

Checks that only privileged users can read the kernel log (dmesg).

Why it matters. The kernel log can reveal addresses, hardware and driver details useful for local exploitation.

kernel.dmesg_restrict: kernel.dmesg_restrict = 0 (hardened value: 1)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.dmesg_restrict = 1 then apply with: sysctl --system
Verify
sysctl kernel.dmesg_restrict should print 1.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-497, NIST 800-53 AC-6, CM-6
References
Linux kernel documentation, /proc/sys/kernel
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Setuid Programs May Dump Core

HOST-KRN-004

Checks that privileged programs do not write core dumps.

Why it matters. A core dump of a setuid program can contain password hashes or keys and may be readable by the user who crashed it.

fs.suid_dumpable: fs.suid_dumpable = 2 (hardened value: 0)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: fs.suid_dumpable = 0 then apply with: sysctl --system
Verify
sysctl fs.suid_dumpable should print 0.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-528, NIST 800-53 AC-6, CM-6
References
Linux kernel documentation, /proc/sys/fs
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

IP Forwarding Enabled

HOST-KRN-005

Checks that the server does not route packets between networks.

Why it matters. A server that forwards packets can be used to pivot between networks. Only routers, VPN gateways and container hosts need this.

net.ipv4.ip_forward: net.ipv4.ip_forward = 1; container runtime detected (/var/run/docker.sock); forwarding is required by the runtime, but forwarded traffic is accepted by default. Set the FORWARD policy to DROP or add DOCKER-USER rules (see NET-FW-005)

container runtime detected (/var/run/docker.sock); forwarding is required by the runtime
iptables FORWARD policy ACCEPT
Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.ip_forward = 0 then apply with: sysctl --system
Verify
sysctl net.ipv4.ip_forward should print 0.
CVSS v3.1
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, NIST 800-53 SC-7, CM-6
References
Linux kernel documentation, IP sysctl
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

ICMP Redirects Accepted

HOST-KRN-006

Checks that the kernel ignores ICMP redirect messages.

Why it matters. Forged ICMP redirects let an attacker on the local network reroute the server's traffic through themselves.

net.ipv4.conf.all.accept_redirects: net.ipv4.conf.all.accept_redirects = 1 (hardened value: 0)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.conf.all.accept_redirects = 0 then apply with: sysctl --system
Verify
sysctl net.ipv4.conf.all.accept_redirects should print 0.
CVSS v3.1
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-940, NIST 800-53 SC-7, CM-6
References
Linux kernel documentation, IP sysctl
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Source-Routed Packets Accepted

HOST-KRN-007

Checks that the kernel drops packets that dictate their own route.

Why it matters. Source routing lets an attacker bypass network filtering and spoof trusted addresses.

net.ipv4.conf.all.accept_source_route: net.ipv4.conf.all.accept_source_route = 1 (hardened value: 0)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.conf.all.accept_source_route = 0 then apply with: sysctl --system
Verify
sysctl net.ipv4.conf.all.accept_source_route should print 0.
CVSS v3.1
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-940, NIST 800-53 SC-7, CM-6
References
Linux kernel documentation, IP sysctl
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

TCP SYN Cookies Disabled

HOST-KRN-008

Checks that SYN cookies protect the server from SYN flood attacks.

Why it matters. Without SYN cookies a simple flood of half-open connections can make every service unreachable.

net.ipv4.tcp_syncookies: net.ipv4.tcp_syncookies = 0 (hardened value: 1)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.tcp_syncookies = 1 then apply with: sysctl --system
Verify
sysctl net.ipv4.tcp_syncookies should print 1.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-770, NIST 800-53 SC-5, CM-6
References
Linux kernel documentation, IP sysctl
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Process Tracing Not Restricted

HOST-KRN-010

Checks that processes cannot attach a debugger to other processes of the same user.

Why it matters. Unrestricted ptrace lets any compromised process read the memory of others, for example to steal SSH agent keys or browser sessions.

kernel.yama.ptrace_scope: kernel.yama.ptrace_scope = 0 (hardened value: 1)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.yama.ptrace_scope = 1 then apply with: sysctl --system
Verify
sysctl kernel.yama.ptrace_scope should print 1.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-749, NIST 800-53 AC-6, CM-6
References
Linux kernel documentation, Yama LSM
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Symlink Protection Disabled

HOST-KRN-011

Checks that the kernel blocks following symlinks owned by other users in world-writable sticky directories.

Why it matters. Without it, classic /tmp symlink races let local users trick root-run programs into overwriting files.

fs.protected_symlinks: fs.protected_symlinks = 0 (hardened value: 1)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: fs.protected_symlinks = 1 then apply with: sysctl --system
Verify
sysctl fs.protected_symlinks should print 1.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-59, NIST 800-53 AC-6, CM-6
References
Linux kernel documentation, /proc/sys/fs
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Hardlink Protection Disabled

HOST-KRN-012

Checks that users cannot create hard links to files they do not own.

Why it matters. Hard links to privileged files enable time-of-check races and keep vulnerable setuid binaries alive after updates.

fs.protected_hardlinks: fs.protected_hardlinks = 0 (hardened value: 1)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: fs.protected_hardlinks = 1 then apply with: sysctl --system
Verify
sysctl fs.protected_hardlinks should print 1.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-59, NIST 800-53 AC-6, CM-6
References
Linux kernel documentation, /proc/sys/fs
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Reverse Path Filtering Disabled

HOST-KRN-013

Checks that the kernel drops packets whose source address could not be routed back through the receiving interface.

Why it matters. Reverse path filtering blocks many spoofed-source packets used in attacks and amplification.

net.ipv4.conf.all.rp_filter: net.ipv4.conf.all.rp_filter = 0 (hardened value: 1)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.conf.all.rp_filter = 1 then apply with: sysctl --system
Verify
sysctl net.ipv4.conf.all.rp_filter should print 1.
CVSS v3.1
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-940, NIST 800-53 SC-7, CM-6
References
Linux kernel documentation, IP sysctl
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Martian Packets Not Logged

HOST-KRN-014

Checks that packets with impossible source addresses are logged.

Why it matters. Logging martian packets helps detect spoofing and misrouting attempts.

net.ipv4.conf.all.log_martians: net.ipv4.conf.all.log_martians = 0 (hardened value: 1)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.conf.all.log_martians = 1 then apply with: sysctl --system
Verify
sysctl net.ipv4.conf.all.log_martians should print 1.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-778, NIST 800-53 SC-7, CM-6
References
Linux kernel documentation, IP sysctl
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Server Sends ICMP Redirects

HOST-KRN-015

Checks that the server does not send ICMP redirects, which only routers should do.

Why it matters. A non-router sending redirects can be abused to influence other hosts' routing on the local network.

net.ipv4.conf.all.send_redirects: 1 of 1 setting(s) differ from the hardened value 0

net/ipv4/conf/all/send_redirects = 1
Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.conf.all.send_redirects = 0 then apply with: sysctl --system
Verify
sysctl net.ipv4.conf.all.send_redirects should print 0.
CVSS v3.1
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, NIST 800-53 SC-7, CM-6
References
Linux kernel documentation, IP sysctl
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Broadcast ICMP Echo Answered

HOST-KRN-016

Checks that the server ignores ping requests sent to broadcast addresses.

Why it matters. Answering broadcast pings makes the server a participant in Smurf-style amplification attacks.

net.ipv4.icmp_echo_ignore_broadcasts: net.ipv4.icmp_echo_ignore_broadcasts = 0 (hardened value: 1)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.icmp_echo_ignore_broadcasts = 1 then apply with: sysctl --system
Verify
sysctl net.ipv4.icmp_echo_ignore_broadcasts should print 1.
CVSS v3.1
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-406, NIST 800-53 SC-5, CM-6
References
Linux kernel documentation, IP sysctl
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

IPv6 ICMP Redirects Accepted

HOST-KRN-017

Checks that the kernel ignores IPv6 ICMP redirect messages.

Why it matters. Forged IPv6 redirects let an attacker on the local network reroute traffic through themselves.

net.ipv6.conf.all.accept_redirects: 1 of 1 setting(s) differ from the hardened value 0

net/ipv6/conf/all/accept_redirects = 1
Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv6.conf.all.accept_redirects = 0 then apply with: sysctl --system
Verify
sysctl net.ipv6.conf.all.accept_redirects should print 0.
CVSS v3.1
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-940, NIST 800-53 SC-7, CM-6
References
Linux kernel documentation, IP sysctl
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Performance Events Open to Unprivileged Users

HOST-KRN-018

Checks that unprivileged users cannot use kernel performance events to observe the system.

Why it matters. Unrestricted perf events expose kernel and other processes' activity and have been used in local exploits.

kernel.perf_event_paranoid: kernel.perf_event_paranoid = 1 (hardened value: 2)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.perf_event_paranoid = 2 then apply with: sysctl --system
Verify
sysctl kernel.perf_event_paranoid should print 2.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-749, NIST 800-53 CM-6, SI-16
References
Linux kernel documentation, /proc/sys/kernel
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Magic SysRq Key Enabled

HOST-KRN-019

Checks that the magic SysRq key combination is disabled or limited to keyboard synchronisation.

Why it matters. With SysRq enabled, anyone at a console or with access to /proc/sysrq-trigger can reboot the machine, kill every process or dump memory without logging in.

kernel.sysrq: kernel.sysrq = 1 (hardened value: 0)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.sysrq = 0 then apply with: sysctl --system
Verify
sysctl kernel.sysrq should print 0.
CVSS v3.1
CVSS:3.1/AV:P/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-749, NIST 800-53 AC-6, CM-6
References
Linux kernel documentation, Linux Magic System Request Key Hacks
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

FIFO Protection in Shared Directories Disabled

HOST-KRN-020

Checks that the kernel refuses to open FIFOs in world-writable sticky directories that another user owns.

Why it matters. A FIFO planted in /tmp can make a privileged program block or write into an attacker-controlled pipe, a classic step in local attacks.

fs.protected_fifos: fs.protected_fifos = 0 (hardened value: 1)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: fs.protected_fifos = 1 then apply with: sysctl --system
Verify
sysctl fs.protected_fifos should print 1.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-59, NIST 800-53 AC-6, CM-6
References
Linux kernel documentation, /proc/sys/fs
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Regular File Protection in Shared Directories Disabled

HOST-KRN-021

Checks that the kernel refuses to open, with O_CREAT, regular files in world-writable sticky directories that another user owns.

Why it matters. Without it, a user can pre-create a file that a root-run script later writes to in /tmp, redirecting privileged output into a file they control.

fs.protected_regular: fs.protected_regular = 0 (hardened value: 1)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: fs.protected_regular = 1 then apply with: sysctl --system
Verify
sysctl fs.protected_regular should print 1.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-59, NIST 800-53 AC-6, CM-6
References
Linux kernel documentation, /proc/sys/fs
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Unprivileged User Namespaces Allowed

HOST-KRN-022

Checks that normal users cannot create user namespaces, unless the server runs containers that need them.

Why it matters. User namespaces give an unprivileged process a fake root inside a namespace, which exposes kernel code paths that were written for root only; many local kernel exploits start by unsharing a user namespace.

kernel.unprivileged_userns_clone: kernel.unprivileged_userns_clone = 1 (hardened value: 0)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing kernel.unprivileged_userns_clone = 0 (Debian family) or user.max_user_namespaces = 0 (other kernels), then apply with: sysctl --system. Rootless Docker, Podman, Flatpak and some browsers need user namespaces, so test first.
Verify
sysctl kernel.unprivileged_userns_clone user.max_user_namespaces
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-749, NIST 800-53 CM-6, CM-7
References
user_namespaces(7), Linux man-pages
Kernel Self Protection Project, Recommended Settings
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/kernel_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

IPv6 Source-Routed Packets Accepted

HOST-KRN-023

Checks that the kernel drops IPv6 packets that dictate their own route.

Why it matters. IPv6 routing headers can be used to bypass filters and spoof trusted addresses, as source routing could in IPv4.

net.ipv6.conf.all.accept_source_route: 1 of 1 setting(s) differ from the hardened value 0

net/ipv6/conf/all/accept_source_route = 1
Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv6.conf.all.accept_source_route = 0 then apply with: sysctl --system
Verify
sysctl net.ipv6.conf.all.accept_source_route should print 0.
CVSS v3.1
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-940, NIST 800-53 SC-7, CM-6
References
Linux kernel documentation, IP sysctl
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Secure ICMP Redirects Accepted

HOST-KRN-024

Checks that the kernel also ignores ICMP redirects that come from its configured gateways.

Why it matters. An attacker who spoofs the gateway address can still reroute traffic unless secure redirects are off as well; a server has no reason to accept redirects at all.

net.ipv4.conf.all.secure_redirects: 1 of 1 setting(s) differ from the hardened value 0

net/ipv4/conf/all/secure_redirects = 1
Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.conf.all.secure_redirects = 0 then apply with: sysctl --system
Verify
sysctl net.ipv4.conf.all.secure_redirects should print 0.
CVSS v3.1
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-940, NIST 800-53 SC-7, CM-6
References
Linux kernel documentation, IP sysctl
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

IPv6 Router Advertisements Accepted

HOST-KRN-025

Checks that the server does not reconfigure its IPv6 addresses and routes from router advertisements.

Why it matters. A rogue router advertisement on the local network can add a default route through an attacker's machine or assign addresses that bypass firewall rules; servers use static addressing.

net.ipv6.conf.all.accept_ra: 1 of 1 setting(s) differ from the hardened value 0

net/ipv6/conf/all/accept_ra = 1
Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv6.conf.all.accept_ra = 0 then apply with: sysctl --system. Caution: on a host that gets its IPv6 address or default route from router advertisements (SLAAC, most cloud dual-stack VMs), accept_ra = 0 removes the IPv6 default route and cuts IPv6 connectivity. Use it only with static IPv6 addressing; otherwise keep accept_ra = 1 and rely on RA Guard on the switch or a host firewall rule for RA sources.
Verify
sysctl net.ipv6.conf.all.accept_ra should print 0.
CVSS v3.1
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-940, NIST 800-53 SC-7, CM-6
References
Linux kernel documentation, IP sysctl
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Bogus ICMP Error Responses Logged

HOST-KRN-026

Checks that the kernel silently ignores malformed ICMP error responses instead of logging each one.

Why it matters. Logging every bogus ICMP error lets a remote sender fill the kernel log and disk at will, hiding real events among noise.

net.ipv4.icmp_ignore_bogus_error_responses: net.ipv4.icmp_ignore_bogus_error_responses = 0 (hardened value: 1)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.ipv4.icmp_ignore_bogus_error_responses = 1 then apply with: sysctl --system
Verify
sysctl net.ipv4.icmp_ignore_bogus_error_responses should print 1.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-779, NIST 800-53 SC-7, CM-6
References
Linux kernel documentation, IP sysctl
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Kexec Kernel Replacement Allowed

HOST-KRN-027

Checks that a running kernel cannot be replaced at run time with kexec.

Why it matters. kexec lets root boot a different kernel without going through the firmware, which bypasses Secure Boot and module signing and is used to load unsigned kernels after a compromise.

kernel.kexec_load_disabled: kernel.kexec_load_disabled = 0 (hardened value: 1)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.kexec_load_disabled = 1 then apply with: sysctl --system. Caution: kexec_load_disabled = 1 also stops kdump from loading its crash kernel (kdump.service on the RHEL family, kdump-tools on Debian and Ubuntu), so crash dumps are lost. Keep it 0 where kdump is used, or accept that trade-off deliberately. The setting cannot be turned back off without a reboot.
Verify
sysctl kernel.kexec_load_disabled should print 1.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U/C:N/I:L/A:L
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-749, NIST 800-53 AC-6, CM-6
References
Kernel Self Protection Project, Recommended Settings
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Unprivileged userfaultfd Allowed

HOST-KRN-028

Checks that only privileged processes can use userfaultfd.

Why it matters. userfaultfd lets a process pause the kernel at a chosen moment, which has turned many kernel race conditions into reliable local exploits.

vm.unprivileged_userfaultfd: vm.unprivileged_userfaultfd = 1 (hardened value: 0)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: vm.unprivileged_userfaultfd = 0 then apply with: sysctl --system. Caution: unprivileged live migration tools (for example QEMU post-copy migration or CRIU run as a normal user) need userfaultfd; test those first.
Verify
sysctl vm.unprivileged_userfaultfd should print 0.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-749, NIST 800-53 AC-6, CM-6
References
Linux kernel documentation, /proc/sys/vm
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

TTY Line Discipline Autoloading Enabled

HOST-KRN-029

Checks that unprivileged users cannot make the kernel load terminal line discipline modules.

Why it matters. Automatically loaded line disciplines have carried several exploitable kernel bugs; disabling autoload shrinks the kernel attack surface reachable from a normal shell.

dev.tty.ldisc_autoload: dev.tty.ldisc_autoload = 1 (hardened value: 0)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: dev.tty.ldisc_autoload = 0 then apply with: sysctl --system
Verify
sysctl dev.tty.ldisc_autoload should print 0.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, NIST 800-53 AC-6, CM-6
References
Kernel Self Protection Project, Recommended Settings
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

BPF JIT Hardening Off

HOST-KRN-030

Checks that the BPF just-in-time compiler blinds constants in generated code for every user.

Why it matters. Without hardening, attacker-chosen constants in BPF programs land in executable kernel memory, a known technique for building kernel exploit payloads.

net.core.bpf_jit_harden: net.core.bpf_jit_harden = 0 (hardened value: 2)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: net.core.bpf_jit_harden = 2 then apply with: sysctl --system
Verify
sysctl net.core.bpf_jit_harden should print 2.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, NIST 800-53 SC-7, CM-6
References
Kernel Self Protection Project, Recommended Settings
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

io_uring Open to Unprivileged Users

HOST-KRN-031

Checks that io_uring is disabled, or limited to privileged processes, on kernels that offer the setting.

Why it matters. io_uring has produced a long run of local privilege-escalation bugs; several large operators disable it for untrusted workloads.

kernel.io_uring_disabled: kernel.io_uring_disabled = 0 (hardened value: 2)

Fix
Create /etc/sysctl.d/60-openvapt-hardening.conf containing: kernel.io_uring_disabled = 2 then apply with: sysctl --system. Caution: applications that use io_uring for fast I/O (some databases, proxies and runtimes) fall back or fail to start when it is disabled; test them first, or use 1 to allow only a chosen group.
Verify
sysctl kernel.io_uring_disabled should print 2.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-749, NIST 800-53 AC-6, CM-6
References
Kernel Self Protection Project, Recommended Settings
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P17: Kernel, Filesystem and Boot Hardening (offline: openvapt learn P17)
Source
internal/checks/host/kernel.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

System Logging Not Persistent

HOST-LOG-001

Checks that system logs survive a reboot (rsyslog/syslog-ng running, or a persistent journal).

Why it matters. Without persistent logs there is no evidence after an incident: no record of logins, sudo use, or service errors.

logging: No syslog daemon active and the journal is not persistent

Fix
Either install and enable rsyslog, or make the journal persistent: mkdir -p /var/log/journal && systemd-tmpfiles --create --prefix /var/log/journal && systemctl restart systemd-journald
Verify
ls -d /var/log/journal or systemctl is-active rsyslog
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-778, OWASP A09:2021, NIST 800-53 AU-2, AU-9, AU-11
References
NIST SP 800-92, Guide to Computer Security Log Management
journald.conf(5)
Learn
P16: Logging, Auditing and Time (offline: openvapt learn P16)
A4: Building Your Own Check (offline: openvapt learn A4)
Source
internal/checks/host/logging_time.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Security Audit Daemon Not Running

HOST-LOG-002

Checks whether the Linux audit daemon (auditd) is running.

Why it matters. auditd records security-relevant events (changes to /etc/passwd, privilege use, file deletions) that ordinary logs miss, which incident responders rely on.

auditd: auditd is not active

Fix
Install the audit package (apt install auditd, or dnf install audit), enable it (systemctl enable --now auditd) and load a rule set appropriate to your policy.
Verify
systemctl is-active auditd should print 'active'.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Logging and Monitoring
Effort
Medium
Confidence
High
Standards
CWE-778, OWASP A09:2021, NIST 800-53 AU-2, AU-12
References
auditd(8), Linux man-pages
Learn
P16: Logging, Auditing and Time (offline: openvapt learn P16)
Source
internal/checks/host/logging_time.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Security Logs Readable by All Users

HOST-LOG-003

Checks that authentication and system logs are not world-readable.

Why it matters. Authentication logs contain user names, source addresses and sometimes passwords typed into the user name field. Only administrators should read them.

/var/log/auth.log: 1 file(s) are readable or writable by others

0644 /var/log/auth.log
Fix
chmod o-rwx /var/log/auth.log /var/log/secure /var/log/syslog /var/log/messages and set the matching create mode in /etc/logrotate.d.
Verify
stat -c '%a %n' /var/log/auth.log /var/log/secure
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-532, NIST 800-53 AC-3, AC-6
References
NIST SP 800-92, Guide to Computer Security Log Management
Learn
P16: Logging, Auditing and Time (offline: openvapt learn P16)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Log Rotation Not Configured

HOST-LOG-004

Checks that logrotate (or journald size limits) keeps logs from filling the disk.

Why it matters. Unrotated logs eventually fill the disk and stop services, and an attacker can deliberately flood logs to cause that or to hide activity.

logs: No log rotation or journal size limit configured

Fix
Install logrotate (apt install logrotate / dnf install logrotate) and keep its daily timer enabled, or set SystemMaxUse= in journald.conf.
Verify
ls /etc/logrotate.conf ; systemctl is-active logrotate.timer
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-770, NIST 800-53 AU-4, AU-11
References
logrotate(8), Linux man-pages
Learn
P16: Logging, Auditing and Time (offline: openvapt learn P16)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

No Mandatory Access Control Enforced

HOST-MAC-001

Checks that AppArmor or SELinux is enabled and enforcing.

Why it matters. Mandatory access control confines services even when they run as root, so a compromised web server or database cannot freely read or change the rest of the system.

mac: Neither SELinux (enforcing) nor AppArmor is active

Fix
Ubuntu/Debian: keep AppArmor enabled (systemctl enable --now apparmor) and its profiles in enforce mode. RHEL family: set SELINUX=enforcing in /etc/selinux/config and relabel. Test applications in permissive or complain mode first.
Verify
getenforce or aa-status
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
High
Confidence
High
Standards
CWE-250, NIST 800-53 AC-3(3), AC-6
References
Linux kernel documentation, Linux Security Module development and LSMs
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Password Quality Module Not Enforced

HOST-PAM-001

Checks that new passwords pass through pam_pwquality with its dictionary check on, so dictionary words and user-name variants are rejected.

Why it matters. NIST SP 800-63B-4 asks verifiers to reject passwords found in dictionaries and blocklists rather than to impose composition rules. pam_pwquality does that work on Linux, but only when the password stack actually calls it and its dictcheck and usercheck options are not switched off. A minlen in pwquality.conf (HOST-PWD-003) does nothing if the module is never invoked.

pam: Password quality checks are not enforced

no pam_pwquality line in /etc/pam.d/common-password
dictcheck = 0 (/etc/security/pwquality.conf.d/10-lab.conf)
Fix
Install libpam-pwquality (Debian/Ubuntu) or libpwquality (RHEL family). Make sure the password stack has password requisite pam_pwquality.so retry=3 before pam_unix (pam-auth-update or authselect enable-feature with-pwquality), and in /etc/security/pwquality.conf keep dictcheck = 1 and usercheck = 1 . Pair it with a breached-password blocklist where possible. Keep a root session open and test a login and a password change in a second session before closing it: a wrong PAM line can lock every user out.
Verify
grep pam_pwquality /etc/pam.d/common-password /etc/pam.d/system-auth 2>/dev/null; grep -rE '^(dictcheck|usercheck|enforcing)' /etc/security/pwquality.conf /etc/security/pwquality.conf.d/
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-521, OWASP A07:2021, NIST 800-53 IA-5(1)
References
pwquality.conf(5), libpwquality, Debian trixie manual pages
NIST SP 800-63B-4, Digital Identity Guidelines: Authentication and Authenticator Management
Learn
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/pam_login.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Account Lockout Releases Too Quickly

HOST-PAM-002

Checks that a locked account stays locked for at least 15 minutes (or until an administrator unlocks it).

Why it matters. This check and HOST-PWD-004 split one control so a single root cause is never counted twice: HOST-PWD-004 covers whether lockout exists and its deny threshold (how many failures lock the account); this check covers only unlock_time (how long the lock lasts). How long the lock lasts decides whether it slows an attacker: pam_faillock's default unlock_time of 600 seconds lets guessing resume every ten minutes. Fifteen minutes or more, or 0 (manual unlock), makes online guessing impractical.

/etc/pam.d/common-auth: unlock_time=60 seconds (need 900 or more, or 0 for manual unlock)

Fix
In /etc/security/faillock.conf set unlock_time = 900 (or 0 to require an administrator to run faillock --reset), keeping deny between 3 and 10. Keep a root session open and test in a second session before closing the first: a wrong PAM line can lock every user out, and unlock_time = 0 means locked accounts, administrators included, wait for faillock --reset.
Verify
grep -E 'unlock_time' /etc/security/faillock.conf /etc/pam.d/common-auth /etc/pam.d/system-auth 2>/dev/null
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-307, OWASP A07:2021, NIST 800-53 AC-7
References
pam_faillock(8), Linux-PAM
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/pam_login.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

su Not Restricted to an Administrative Group

HOST-PAM-003

Checks that only members of a named group (wheel or sudo) may use su to become another user.

Why it matters. Without pam_wheel, every local account, including a compromised web service user, can run su and start guessing the root password. Restricting su to an administrative group removes that path and leaves sudo, which logs each command, as the way to gain privilege.

/etc/pam.d/su: No active pam_wheel line: any user may attempt su

Fix
In /etc/pam.d/su uncomment or add auth required pam_wheel.so use_uid group=sudo (group=wheel on the RHEL family), and make sure the group contains only administrators. Caution: add every administrator who uses su to that group first and test from a second session, or they lose su access.
Verify
grep -E '^auth\s+required\s+pam_wheel.so' /etc/pam.d/su
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-250, CWE-862, NIST 800-53 AC-6(2), AC-3
References
pam_wheel(8), Linux-PAM
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/pam_login.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Password History Not Enforced

HOST-PAM-004

Checks that PAM remembers at least the last 5 passwords so a changed password cannot be changed straight back.

Why it matters. When a password must be changed after a suspected compromise, the point is lost if the user can set the old one again. pam_pwhistory (or pam_unix remember=) keeps recent hashes and refuses reuse. Five is a common minimum.

/etc/pam.d/common-password: No remember= setting: old passwords can be reused at once

Fix
Add password required pam_pwhistory.so remember=5 use_authtok before pam_unix in the password stack (pam-auth-update on Debian/Ubuntu, authselect enable-feature with-pwhistory on the RHEL family), or set remember = 5 in /etc/security/pwhistory.conf. Keep a root session open and test a password change in a second session before closing it: a wrong PAM line can block password changes or logins.
Verify
grep -E 'remember' /etc/pam.d/common-password /etc/pam.d/system-auth /etc/security/pwhistory.conf 2>/dev/null
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-262, OWASP A07:2021, NIST 800-53 IA-5(1)
References
pam_pwhistory(8), Linux-PAM
pam_unix(8), Linux-PAM
NIST SP 800-63B-4, Digital Identity Guidelines: Authentication and Authenticator Management
Learn
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/pam_login.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Minimum Password Age Not Set

HOST-PAM-005

Checks that a password cannot be changed again on the same day it was set.

Why it matters. Password history (HOST-PAM-004) only works if users cannot cycle through several changes in a minute to get back to a favourite password. PASS_MIN_DAYS 1 closes that loop with no real cost to users.

/etc/login.defs: PASS_MIN_DAYS 0 (1 or more)

Fix
Set PASS_MIN_DAYS 1 in /etc/login.defs, and for existing accounts chage --mindays 1 <user> .
Verify
grep '^PASS_MIN_DAYS' /etc/login.defs
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-262, OWASP A07:2021, NIST 800-53 IA-5(1)
References
login.defs(5), Linux man-pages
NIST SP 800-63B-4, Digital Identity Guidelines: Authentication and Authenticator Management
Learn
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/pam_login.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Inactive Accounts Never Locked

HOST-PAM-007

Checks that new accounts are set to lock automatically after a password has been expired and unused for at most 30 days.

Why it matters. Accounts of people who left, or test accounts nobody remembers, stay usable for years unless something disables them. The INACTIVE default in /etc/default/useradd makes new accounts lock themselves a fixed number of days after their password expires.

/etc/default/useradd: INACTIVE=-1 (need 0 to 30)

Fix
useradd -D -f 30 (writes INACTIVE=30 to /etc/default/useradd), and for existing accounts chage --inactive 30 <user> . Caution: this locks accounts whose password has expired for 30 days, so exempt break-glass and rarely used administrator accounts or keep their passwords current.
Verify
useradd -D | grep INACTIVE
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-262, NIST 800-53 AC-2(3)
References
useradd(8), Linux man-pages (default INACTIVE value)
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/pam_login.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

No Shell Idle Timeout

HOST-PAM-009

Checks that interactive shells log out after at most 15 minutes without input (TMOUT).

Why it matters. A root shell left open on an unattended terminal, or a forgotten SSH session on a shared workstation, is free privilege for whoever sits down next. TMOUT makes bash and ksh close an idle session automatically; readonly stops users from switching it off.

TMOUT: No TMOUT is set in the shell start-up files

Fix
Create /etc/profile.d/99-tmout.sh with TMOUT=900 ; readonly TMOUT ; export TMOUT (mode 644, owned by root). Sessions that must stay open should use a multiplexer such as tmux with its own lock, not a longer TMOUT. Caution: a readonly TMOUT ends idle interactive shells, including foreground jobs left waiting in them; run long jobs under nohup, systemd-run or a multiplexer.
Verify
grep -rE '^\s*(readonly |export )?TMOUT=' /etc/profile /etc/profile.d/ /etc/bash.bashrc /etc/bashrc 2>/dev/null
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-613, OWASP A07:2021, NIST 800-53 AC-11, AC-12
References
Bash Reference Manual, Bash Variables (TMOUT)
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/pam_login.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Many Old Kernels Retained

HOST-PKG-004

Checks that no more than three kernel versions are installed.

Why it matters. Every installed kernel stays bootable from the boot menu, with every vulnerability it had. Old kernels also fill /boot until updates fail to install, which is a quiet way to stop receiving kernel patches. Keeping the running kernel plus one or two fallbacks is enough.

kernels: 5 kernel versions installed (recommended at most 3)

4.15.0-100-generic
4.15.0-112-generic
4.15.0-120-generic
4.15.0-140-generic
4.15.0-150-generic
Fix
Debian/Ubuntu: apt-get autoremove --purge removes kernels outside the keep list. RHEL family: set installonly_limit=3 in /etc/dnf/dnf.conf and run dnf remove --oldinstallonly . Never remove the running kernel (uname -r).
Verify
dpkg -l 'linux-image-*' | grep '^ii' or rpm -q kernel kernel-core
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U/C:L/I:L/A:N
Category
Patch and Vulnerability Management
Effort
Low
Confidence
High
Standards
CWE-1104, OWASP A06:2021, NIST 800-53 SI-2, CM-7
References
NIST SP 800-40 Rev. 4, Guide to Enterprise Patch Management Planning
apt-get(8), Debian trixie manual pages (autoremove)
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/pkg_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Package Lists Not Refreshed Automatically

HOST-PKG-006

Checks that the package manager downloads fresh repository metadata on a schedule, so pending updates can be seen at all.

Why it matters. apt and dnf only know about updates listed in the metadata they last downloaded. Without a timer that refreshes it, HOST-PKG-001 and the administrator's own apt list --upgradable both report a clean system that is weeks behind. The refresh is read-only and separate from installing anything.

apt: Package lists are not refreshed automatically (no APT::Periodic::Update-Package-Lists and apt-daily.timer not enabled)

Fix
Debian/Ubuntu: create /etc/apt/apt.conf.d/20auto-upgrades with APT::Periodic::Update-Package-Lists "1"; (dpkg-reconfigure unattended-upgrades writes it) and systemctl enable apt-daily.timer . RHEL family: systemctl enable --now dnf-makecache.timer .
Verify
systemctl is-enabled apt-daily.timer or systemctl is-enabled dnf-makecache.timer
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Patch and Vulnerability Management
Effort
Low
Confidence
High
Standards
CWE-1104, OWASP A06:2021, NIST 800-53 SI-2, RA-5
References
Debian, UnattendedUpgrades (APT::Periodic settings)
NIST SP 800-40 Rev. 4, Guide to Enterprise Patch Management Planning
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/pkg_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Short Minimum Password Length

HOST-PWD-003

Checks that the password quality policy requires at least 15 characters.

Why it matters. Length is the single most effective property against guessing. NIST SP 800-63B-4 (2025) requires at least 15 characters for a password used as the only authentication factor, and recommends allowing long passphrases.

/etc/security/pwquality.conf: minlen = 8 (NIST SP 800-63B-4 requires 15 or more for single-factor passwords)

Fix
Install libpam-pwquality (Debian/Ubuntu) or libpwquality (RHEL family) and set minlen = 15 (or more) in /etc/security/pwquality.conf.
Verify
grep -r '^minlen' /etc/security/pwquality.conf /etc/security/pwquality.conf.d/
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-521, OWASP A07:2021, NIST 800-53 IA-5(1)
References
pwquality.conf(5), libpwquality, Debian trixie manual pages
NIST SP 800-63B-4, Digital Identity Guidelines: Authentication and Authenticator Management
Learn
P7: Identity, Passwords and Privilege (offline: openvapt learn P7)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/passwords.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

SSH X11 Forwarding Enabled

HOST-SSH-005

Checks whether SSH forwards graphical X11 sessions.

Why it matters. Servers rarely need X11. Forwarding it exposes the connecting user's display to anyone with root on the server, and widens the attack surface of sshd.

sshd: X11 forwarding is enabled

x11forwarding yes
Fix
Set X11Forwarding no in /etc/ssh/sshd_config and reload sshd.
Verify
sshd -T | grep -i x11forwarding should print 'no'.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:L/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, NIST 800-53 CM-7
References
OpenBSD, sshd_config(5) manual page
Learn
P2: SSH Security (offline: openvapt learn P2)
Source
internal/checks/host/ssh_misc.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

SSH Allows Many Authentication Attempts

HOST-SSH-006

Checks whether MaxAuthTries is above 4.

Why it matters. Each connection may try this many passwords or keys. A low limit slows guessing and makes attacks show up in the logs sooner.

sshd: MaxAuthTries is 10 (recommended 4 or lower)

Fix
Set MaxAuthTries 4 (or lower) in /etc/ssh/sshd_config and reload sshd. Consider fail2ban or sshguard for rate limiting.
Verify
sshd -T | grep -i maxauthtries should print 4 or lower.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-307, NIST 800-53 AC-7
References
OpenBSD, sshd_config(5) manual page
Learn
P2: SSH Security (offline: openvapt learn P2)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/ssh_misc.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

SSH Authentication Controls Too Permissive

HOST-SSH-008

Checks effective SSH authentication method and login grace settings.

Why it matters. Long login windows and unconstrained single-factor authentication give online guessing and stolen credentials more opportunity.

sshd: SSH authentication restrictions are too permissive

logingracetime 120
password or keyboard-interactive login enabled without a second factor (authenticationmethods (not set, default applies))
Fix
Set LoginGraceTime 60 or lower and choose AuthenticationMethods appropriate to the server, such as publickey, then restrict access with AllowUsers or AllowGroups where practical.
Verify
Use sshd -T -C for each allowed user and source context and inspect logingracetime, authenticationmethods, allowusers and allowgroups.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-307, CWE-308, NIST 800-53 AC-7, IA-2
References
OpenBSD, sshd_config(5) manual page
Learn
P2: SSH Security (offline: openvapt learn P2)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/ssh_forwarding.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

SSH Logging Level Too Low

HOST-SSH-012

Checks that sshd logs at INFO or VERBOSE level.

Why it matters. QUIET, FATAL or ERROR levels drop login records, so failed and successful logins cannot be investigated. VERBOSE also records the key fingerprint used.

sshd: LogLevel quiet drops login records

Fix
Set LogLevel VERBOSE (or INFO) in /etc/ssh/sshd_config and reload sshd.
Verify
sshd -T | grep -i loglevel
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-778, OWASP A09:2021, NIST 800-53 AU-2, AU-3
References
OpenBSD, sshd_config(5) manual page
Learn
P2: SSH Security (offline: openvapt learn P2)
P16: Logging, Auditing and Time (offline: openvapt learn P16)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

SSH Authorized Keys Without Restrictions or Protection

HOST-SSH-013

Checks root's authorized_keys for keys without from= or command= options, and every authorized_keys file for permissive modes.

Why it matters. A key in root's authorized_keys is a root password that never expires. Restricting it with from= (allowed source addresses) or command= (one fixed command) limits what a stolen key can do. An authorized_keys file that others can write lets them add their own key; one that others can read tells them which keys to steal.

authorized_keys: SSH authorized keys lack restrictions or protection

0644 /root/.ssh/authorized_keys is readable by others
/root/.ssh/authorized_keys: 1 root key(s) without from= or command= restrictions
Fix
Prefix each root key with options, for example from="203.0.113.0/24",no-port-forwarding,no-agent-forwarding or command="/usr/local/bin/backup",restrict ; chmod 600 ~/.ssh/authorized_keys and 700 ~/.ssh for every account. Prefer sudo from a personal account over direct root keys.
Verify
cut -c1-40 /root/.ssh/authorized_keys ; stat -c '%a %n' /root/.ssh/authorized_keys /home/*/.ssh/authorized_keys
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:L/I:L/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-732, CWE-250, NIST 800-53 IA-5, AC-6, AC-17
References
sshd(8), AUTHORIZED_KEYS FILE FORMAT, OpenBSD manual pages
NIST IR 7966, Security of Interactive and Automated Access Management Using Secure Shell (SSH)
Learn
P2: SSH Security (offline: openvapt learn P2)
P20: Secrets, Cron and Account Hygiene (offline: openvapt learn P20)
Source
internal/checks/host/hygiene.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Sudo Commands Not Logged to a Dedicated File

HOST-SUDO-001

Checks that sudo uses a pseudo-terminal and keeps its own log file.

Why it matters. Defaults use_pty stops background processes from a sudo session lingering after it ends. A dedicated logfile keeps an easily reviewed record of privileged commands.

/etc/sudoers: Missing: Defaults use_pty, Defaults logfile=

Fix
With visudo add: Defaults use_pty and Defaults logfile="/var/log/sudo.log"
Verify
grep -rE 'use_pty|logfile' /etc/sudoers /etc/sudoers.d
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-778, OWASP A09:2021, NIST 800-53 AU-2, AU-12
References
sudoers(5) manual
Learn
P7: Identity, Passwords and Privilege (offline: openvapt learn P7)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
P16: Logging, Auditing and Time (offline: openvapt learn P16)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Unnecessary Legacy Services Running

HOST-SVC-001

Checks for desktop and legacy network services that servers rarely need.

Why it matters. Each running service adds attack surface. Zeroconf discovery, printing, RPC portmapping and inetd-style super-servers are common, long-forgotten exposures.

services: Unnecessary services are active

avahi-daemon
rpcbind
Fix
systemctl disable --now <service> for each listed service you do not need, or remove its package. Caution: check first that nothing depends on it (systemctl list-dependencies --reverse <service>) and keep console access when disabling network or remote-access services.
Verify
systemctl is-active avahi-daemon cups rpcbind xinetd
CVSS v3.1
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, NIST 800-53 CM-7
References
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Avahi or CUPS Installed or Enabled

HOST-SVC-007

Checks whether zero-configuration discovery (Avahi) or the printing system (CUPS) is installed or enabled.

Why it matters. Avahi announces the machine and its services to the local network, and CUPS listens for print jobs and runs a web interface. Both are desktop features with a history of vulnerabilities and no purpose on a server. If this machine is one of the desktops and print servers that legitimately run it, record the reason in the suppression file so the finding stays visible but accepted.

services: 3 legacy service component(s) present

package avahi-daemon is installed
package cups is installed
unit avahi-daemon.service is enabled at boot
Fix
apt purge avahi-daemon cups cups-daemon or dnf remove avahi cups , and systemctl disable --now avahi-daemon.socket avahi-daemon.service cups.socket cups.service . Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.
Verify
dpkg -l avahi-daemon cups cups-daemon 2>/dev/null | grep '^ii' ; systemctl is-enabled avahi-daemon.service avahi-daemon.socket cups.service cups.socket cups-browsed.service 2>/dev/null
CVSS v3.1
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, NIST 800-53 CM-7, CM-7(1)
References
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/legacy_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

NFS Server or rpcbind Installed or Enabled

HOST-SVC-008

Checks whether the NFS server or the RPC port mapper (rpcbind) is installed or enabled.

Why it matters. NFS exports whole directory trees with trust based on client IP address and numeric user ids, and rpcbind tells any caller which RPC services are running. Unless this machine is a file server, both are attack surface with no benefit. The rpcbind package is often pulled in as a dependency and left running. If this machine is one of the file servers that legitimately run it, record the reason in the suppression file so the finding stays visible but accepted.

services: 2 legacy service component(s) present

package nfs-kernel-server is installed
package rpcbind is installed
Fix
apt purge nfs-kernel-server rpcbind or dnf remove nfs-utils rpcbind where NFS is not served, and systemctl disable --now nfs-server rpcbind.socket rpcbind.service . Where NFS is required, export read-only with root_squash to named hosts and firewall port 2049 and 111. Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.
Verify
dpkg -l nfs-kernel-server rpcbind 2>/dev/null | grep '^ii' ; systemctl is-enabled nfs-server.service rpcbind.service rpcbind.socket nfs-kernel-server.service 2>/dev/null
CVSS v3.1
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, CWE-306, NIST 800-53 CM-7, CM-7(1)
References
NFS security, Linux kernel documentation (exports and rpcbind)
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/legacy_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

DHCP or DNS Server Installed or Enabled

HOST-SVC-009

Checks whether a DHCP server or an authoritative or recursive DNS server (BIND) is installed or enabled on a machine that is not a network server.

Why it matters. A rogue DHCP server hands out addresses and gateways to the whole network segment, and BIND is a large, privileged network service with a long vulnerability history. Both belong on dedicated infrastructure hosts. On a web or application server they are either forgotten or an attacker's foothold. If this machine is one of the dedicated network infrastructure hosts that legitimately run it, record the reason in the suppression file so the finding stays visible but accepted.

services: 1 legacy service component(s) present

package isc-dhcp-server is installed
Fix
apt purge isc-dhcp-server bind9 or dnf remove dhcp-server bind , and systemctl disable --now isc-dhcp-server named . If this machine is meant to be a DNS or DHCP server, record that in the suppression file and review NET-SVC findings for its configuration. Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.
Verify
dpkg -l isc-dhcp-server dhcp-server kea-dhcp4-server kea-dhcp6-server bind9 bind bind9-dnsutils-server 2>/dev/null | grep '^ii' ; systemctl is-enabled isc-dhcp-server.service dhcpd.service kea-dhcp4-server.service named.service bind9.service 2>/dev/null
CVSS v3.1
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, NIST 800-53 CM-7, CM-7(1)
References
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/legacy_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Samba File Server Installed or Enabled

HOST-SVC-010

Checks whether the Samba SMB file server is installed or set to start at boot.

Why it matters. SMB file sharing exposes files, printers and authentication to the network and has been the target of worms and several critical remote code execution flaws. It is needed only on file servers for Windows-style clients. If this machine is one of the file servers that legitimately run it, record the reason in the suppression file so the finding stays visible but accepted.

services: 1 legacy service component(s) present

package samba is installed
Fix
apt purge samba or dnf remove samba , and systemctl disable --now smbd nmbd (smb nmb on the RHEL family). Where it is required, disable SMB1, require signing and restrict shares to named users. Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.
Verify
dpkg -l samba 2>/dev/null | grep '^ii' ; systemctl is-enabled smbd.service nmbd.service smb.service nmb.service samba.service 2>/dev/null
CVSS v3.1
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, NIST 800-53 CM-7, CM-7(1)
References
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/legacy_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

SNMP Agent or Squid Proxy Installed or Enabled

HOST-SVC-011

Checks whether an SNMP agent or the Squid caching proxy is installed or enabled.

Why it matters. SNMP v1 and v2c authenticate with a community string sent in clear text (public and private are the usual defaults) and reveal routing tables, interfaces, processes and installed software. Squid turns the machine into a relay for other traffic and is often left open. Both need a deliberate configuration to be anything but a liability. If this machine is one of the monitored hosts using SNMPv3 and dedicated proxy servers that legitimately run it, record the reason in the suppression file so the finding stays visible but accepted.

services: 1 legacy service component(s) present

package snmpd is installed
Fix
apt purge snmpd squid or dnf remove net-snmp squid , and systemctl disable --now snmpd squid . If monitoring needs SNMP, use version 3 with authPriv and bind the agent to the management network. Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.
Verify
dpkg -l snmpd net-snmp squid squid-openssl 2>/dev/null | grep '^ii' ; systemctl is-enabled snmpd.service squid.service 2>/dev/null
CVSS v3.1
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, CWE-319, NIST 800-53 CM-7, CM-7(1)
References
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/legacy_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

inetd Super-Server Installed or Enabled

HOST-SVC-012

Checks whether xinetd or another inetd super-server is installed or enabled.

Why it matters. inetd-style super-servers exist to launch small network services (echo, chargen, telnet, tftp) on demand from a shared configuration. On a systemd machine every service they would start has a native unit; the super-server adds a second, rarely reviewed, place where network services are switched on.

services: 2 legacy service component(s) present

package xinetd is installed
unit xinetd.service is enabled at boot
Fix
apt purge xinetd openbsd-inetd or dnf remove xinetd , and systemctl disable --now xinetd . Review /etc/inetd.conf and /etc/xinetd.d first so nothing needed disappears. Before removing a package, check that no application on this machine or the network still uses the service, and keep console access when the service is remote-access related.
Verify
dpkg -l xinetd openbsd-inetd inetutils-inetd 2>/dev/null | grep '^ii' ; systemctl is-enabled xinetd.service inetd.service openbsd-inetd.service inetutils-inetd.service 2>/dev/null
CVSS v3.1
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, NIST 800-53 CM-7, CM-7(1)
References
NIST SP 800-123, Guide to General Server Security
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/legacy_services.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Custom Services Lack Sandboxing

HOST-SYSD-002

Checks whether custom long-running services use systemd's basic sandboxing options.

Why it matters. systemd can confine a service with a few lines: block privilege gain through setuid programs, mount the operating system read-only, give it a private /tmp and hide home directories. These limit what an attacker can do after exploiting the service, at almost no cost.

systemd units: 4 custom service(s) lack basic sandboxing

shop-admin.service is missing: NoNewPrivileges=yes, ProtectSystem=strict, PrivateTmp=yes, ProtectHome=yes
shop-api.service is missing: NoNewPrivileges=yes, ProtectSystem=strict, PrivateTmp=yes, ProtectHome=yes
shop-reports.service is missing: NoNewPrivileges=yes, ProtectSystem=strict, PrivateTmp=yes, ProtectHome=yes
shop-worker.service is missing: NoNewPrivileges=yes, ProtectSystem=strict, PrivateTmp=yes, ProtectHome=yes
Fix
Add the missing lines with systemctl edit <unit> (a drop-in), for example NoNewPrivileges=yes, ProtectSystem=strict, ReadWritePaths=/var/lib/<app>, PrivateTmp=yes, ProtectHome=yes. Restart the service and test it; add ReadWritePaths= for every folder the app must write. systemd-analyze security <unit> suggests further options.
Verify
systemd-analyze security <unit> shows a lower exposure score, and the service still works.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:L/I:L/A:N
Category
Secure Configuration
Effort
Medium
Confidence
High
Standards
CWE-250, CWE-653, NIST 800-53 CM-6, SC-39, AC-6
References
systemd.exec(5), execution environment configuration
systemd-analyze(1), security verb
Learn
P11: Service Hardening With systemd (offline: openvapt learn P11)
Source
internal/checks/host/systemd.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Time Synchronisation Not Active

HOST-TIME-001

Checks that the clock is kept in sync (chrony, ntpd or systemd-timesyncd).

Why it matters. Accurate time is needed to correlate logs during an investigation, and TLS certificates and one-time-password codes fail when the clock drifts.

time: No time synchronisation service is active

Fix
Enable one time service, for example: systemctl enable --now systemd-timesyncd (or install chrony).
Verify
timedatectl should show 'System clock synchronized: yes'.
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-778, NIST 800-53 AU-8
References
NIST SP 800-53 Rev. 5, Security and Privacy Controls
Learn
P16: Logging, Auditing and Time (offline: openvapt learn P16)
Source
internal/checks/host/logging_time.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Automatic Security Updates Not Configured

HOST-UPD-001

Checks that security updates are installed automatically.

Why it matters. Many compromises use vulnerabilities fixed days or weeks earlier. Automatic security updates close that window without relying on someone remembering.

updates: No automatic security update mechanism is enabled

Fix
Debian/Ubuntu: apt install unattended-upgrades && dpkg-reconfigure -plow unattended-upgrades . RHEL family: dnf install dnf-automatic, set apply_updates = yes and upgrade_type = security, then systemctl enable --now dnf-automatic.timer .
Verify
Re-run this check.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Patch and Vulnerability Management
Effort
Low
Confidence
High
Standards
CWE-1104, OWASP A06:2021, NIST 800-53 SI-2(2)
References
Debian, UnattendedUpgrades
NIST SP 800-40 Rev. 4
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
Source
internal/checks/host/hardening.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

System Accounts With Login Shells

HOST-USR-005

Checks that service accounts (UID below UID_MIN, usually 1000, other than root) cannot log in interactively.

Why it matters. Service accounts should never need a shell. A login shell gives an attacker who compromises the service, or guesses its password, an interactive foothold.

/etc/passwd: System accounts have login shells

daemon (/bin/bash)
Fix
usermod -s /usr/sbin/nologin <account> for each listed account (use /sbin/nologin on RHEL family).
Verify
awk -F: '$3>0 && $3<1000 {print $1, $7}' /etc/passwd
CVSS v3.1
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-250, NIST 800-53 AC-2, CM-7
References
nologin(8), Linux man-pages
Learn
P7: Identity, Passwords and Privilege (offline: openvapt learn P7)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/passwords.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Home Directories Accessible to Other Users

HOST-USR-010

Checks that the home directory of each interactive account denies read, write and execute to others.

Why it matters. Home directories hold shell history, SSH keys, application configuration and downloads. With others allowed in, any account on the machine can read another user's history and keys or, with write access, plant a .bashrc that runs when that user logs in.

/home: Home directories are accessible to other users

0755 /home/deploy (deploy) is accessible to others
Fix
chmod 750 /home/<user> for each listed account (700 if group access is not needed), and set HOME_MODE 0750 in /etc/login.defs or DIR_MODE=0750 in /etc/adduser.conf so new accounts start that way.
Verify
stat -c '%a %n' /home/* shows 750 or 700.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Category
Access Control
Effort
Low
Confidence
High
Standards
CWE-732, CWE-276, NIST 800-53 AC-3, AC-6
References
NIST SP 800-123, Guide to General Server Security
login.defs(5), Linux man-pages
Learn
P7: Identity, Passwords and Privilege (offline: openvapt learn P7)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
P20: Secrets, Cron and Account Hygiene (offline: openvapt learn P20)
Source
internal/checks/host/hygiene.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

MySQL Error Log Not Configured

NET-DB-017

log_error is not set, so server errors, failed logins and startup warnings go to the console or syslog without a dedicated, retained file.

Why it matters. The error log is the first place to see authentication failures, crashes and plugin warnings. A named file with rotation makes those events available to incident response and to the audit checks that read it.

/etc/mysql/mysql.conf.d/mysqld.cnf: log_error is not set, so server errors, failed logins and startup warnings go to the console or syslog without a dedicated, retained file.

log_error is not set in the option files
Fix
Add log_error = /var/log/mysql/error.log under [mysqld], make the folder writable by the mysql user, and add a logrotate rule.
Verify
SHOW VARIABLES LIKE 'log_error'; should print the file path.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-778, OWASP A09:2021, ASVS 7.1.1, NIST 800-53 AU-2, AU-12
References
MySQL 8.4 Reference Manual, The Error Log
MySQL 8.4 Reference Manual, Server System Variables
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
P19: Database, Mail and DNS Hardening (offline: openvapt learn P19)
Source
internal/checks/network/data_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

MySQL Resolves Client Host Names

NET-DB-018

skip-name-resolve is not set, so grants that name hosts depend on DNS answers and every connection waits on a reverse lookup.

Why it matters. Host-based grants that trust names can be satisfied by whoever controls DNS or the resolver path. With skip-name-resolve the server matches IP addresses only, which is both faster and not spoofable through DNS. Grants that use host names must be rewritten first.

/etc/mysql/mysql.conf.d/mysqld.cnf: skip-name-resolve is not set, so grants that name hosts depend on DNS answers and every connection waits on a reverse lookup.

skip-name-resolve is not set; the default is OFF
Fix
Rewrite grants that use host names to IP addresses or '%', then add skip-name-resolve under [mysqld] and restart in a maintenance window.
Verify
SHOW VARIABLES LIKE 'skip_name_resolve'; should print ON.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N
Category
Data Services
Effort
Low
Confidence
High
Standards
CWE-350, CWE-290, OWASP A05:2021, ASVS 14.1.3, NIST 800-53 CM-6, IA-3
References
MySQL 8.4 Reference Manual, skip_name_resolve
MySQL 8.4 Reference Manual, Security Guidelines
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
P19: Database, Mail and DNS Hardening (offline: openvapt learn P19)
Source
internal/checks/network/data_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

PostgreSQL Connection Logging Off

NET-DB-021

log_connections and log_disconnections are off, so successful logins leave no record.

Why it matters. Failed logins are logged by default, but successful ones are not. Knowing which role connected from where and for how long is the base evidence for spotting credential misuse and for any later investigation.

/etc/postgresql/16/main/postgresql.conf: log_connections and log_disconnections are off, so successful logins leave no record.

log_connections is not set; the default is off
Fix
Set log_connections = on and log_disconnections = on in postgresql.conf and reload. On PostgreSQL 18 and newer, log_connections accepts a list such as receipt,authentication,authorization .
Verify
SHOW log_connections; should print on (or a non-empty list).
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N
Category
Logging and Monitoring
Effort
Low
Confidence
High
Standards
CWE-778, OWASP A09:2021, ASVS 7.1.3, NIST 800-53 AU-2, AU-12, AC-2(4)
References
PostgreSQL, Error Reporting and Logging
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P8: Data Services: Databases, File Shares, DNS and Mail (offline: openvapt learn P8)
P19: Database, Mail and DNS Hardening (offline: openvapt learn P19)
Source
internal/checks/network/data_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

BIND Version String Disclosed

NET-DNS-001

named.conf has no version statement in options, so a CHAOS class query for version.bind returns the exact BIND release.

Why it matters. The version string lets an attacker match advisories to the server without any guessing. Replacing it costs nothing and does not break resolution.

/etc/bind/named.conf.options: named.conf has no version statement in options, so a CHAOS class query for version.bind returns the exact BIND release.

no version statement in options
Fix
Add version "not disclosed"; inside the options block and run named-checkconf, then rndc reconfig.
Verify
dig @127.0.0.1 version.bind txt chaos +short should print the chosen string.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-497, OWASP A05:2021, NIST 800-53 CM-6, SI-11
References
BIND 9 Administrator Reference Manual, version statement
BIND 9 Administrator Reference Manual, options
Learn
P19: Database, Mail and DNS Hardening (offline: openvapt learn P19)
Source
internal/checks/network/data_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Firewall Rules Open Ports With No Service

NET-FW-004

Checks for firewall allow rules whose port has no listening service on this machine.

Why it matters. Stale rules are holes waiting for a service. Anything later started on that port, by an administrator, a package or an attacker, becomes reachable without anyone deciding it should be. Rule sets also become impossible to review when they no longer match reality.

firewall: 1 allow rule(s) open ports with no service

port 8443/tcp allowed by iptables but nothing listens on it: -A INPUT -p tcp -m tcp --dport 8443 -j ACCEPT
Fix
Remove rules for services that no longer exist (ufw status numbered, then ufw delete <n>), or note why a rule must stay. Review the firewall whenever a service is retired.
Verify
Re-run this check; every allowed port should have a listening service.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Network Exposure
Effort
Low
Confidence
High
Standards
CWE-1188, NIST 800-53 SC-7, CM-7, CM-3
References
NIST SP 800-41 Rev. 1, Guidelines on Firewalls and Firewall Policy
Learn
P3: Network Exposure and Firewalls (offline: openvapt learn P3)
P12: Firewall Policy Versus What Is Listening (offline: openvapt learn P12)
Source
internal/checks/network/firewall_exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Postfix VRFY Command Enabled

NET-MAIL-003

disable_vrfy_command is not yes, so anyone who connects can ask the server whether a mailbox exists.

Why it matters. VRFY lets a sender enumerate valid addresses one by one, which feeds spam lists and targeted phishing. Legitimate mail flow never needs it.

/etc/postfix/main.cf: disable_vrfy_command is not yes, so anyone who connects can ask the server whether a mailbox exists.

disable_vrfy_command is not set; the default is no
Fix
Add disable_vrfy_command = yes to main.cf and postfix reload.
Verify
postconf disable_vrfy_command should print yes; an authorised VRFY postmaster over a local SMTP session should return 502.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-204, OWASP A05:2021, NIST 800-53 CM-7, SI-11
References
Postfix, disable_vrfy_command
RFC 5321, Simple Mail Transfer Protocol, section 7.3
Learn
P19: Database, Mail and DNS Hardening (offline: openvapt learn P19)
Source
internal/checks/network/data_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Apache Reveals Version in Header and Footer

WEB-APA-001

ServerTokens is not Prod or ServerSignature is On, so responses and error pages show the Apache version and modules.

Why it matters. The Server header and the signature line on error pages tell an attacker the exact release and loaded modules. Hiding them removes a free hint; patching remains the real fix.

/etc/apache2/apache2.conf: ServerTokens is not Prod or ServerSignature is On, so responses and error pages show the Apache version and modules.

/etc/apache2/conf-enabled/security.conf: ServerTokens OS
/etc/apache2/conf-enabled/security.conf: ServerSignature On
Fix
Set ServerTokens Prod and ServerSignature Off in apache2.conf or conf-enabled/security.conf (Debian) or httpd.conf (RHEL), then apachectl configtest and reload.
Verify
curl -sI https://<site>/ | grep -i '^server:' should print Server: Apache with nothing after it.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-497, OWASP A05:2021, ASVS 14.3.3, NIST 800-53 CM-6, SI-11
References
Apache HTTP Server, ServerTokens directive
OWASP WSTG-INFO-02, Fingerprint Web Server
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Apache TRACE Method Enabled

WEB-APA-002

TraceEnable is not set to Off, so the HTTP TRACE method echoes requests back to the client.

Why it matters. TRACE reflects request headers, including cookies and authorisation, which older cross-site tracing attacks used to read them from the browser. No production site needs it.

/etc/apache2/apache2.conf: TraceEnable is not set to Off, so the HTTP TRACE method echoes requests back to the client.

/etc/apache2/conf-enabled/security.conf: TraceEnable On
Fix
Add TraceEnable Off to the server configuration and reload.
Verify
curl -s -o /dev/null -w '%{http_code}' -X TRACE https://<site>/ should print 405.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, CWE-749, OWASP A05:2021, ASVS 14.5.1, NIST 800-53 CM-7
References
Apache HTTP Server, TraceEnable directive
OWASP WSTG-CONF-06, Test HTTP Methods
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Apache AllowOverride All Permits .htaccess Control

WEB-APA-004

A Directory block sets AllowOverride All, so any .htaccess file under it can change handlers, options and access rules.

Why it matters. With AllowOverride All, whoever can write a file into the document root (an upload bug, a compromised CMS) can turn images into executable scripts or lift access controls. Limiting overrides keeps those decisions in root-owned configuration.

/etc/apache2/apache2.conf: A Directory block sets AllowOverride All, so any .htaccess file under it can change handlers, options and access rules.

/etc/apache2/apache2.conf: AllowOverride All
Fix
Set AllowOverride None and move needed rules into the vhost, or allow only what the application needs, for example AllowOverride FileInfo Indexes Limit for WordPress permalinks.
Verify
grep -rn AllowOverride /etc/apache2 /etc/httpd 2>/dev/null should show no All.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-15, CWE-1188, OWASP A05:2021, ASVS 14.1.1, NIST 800-53 CM-6, CM-7
References
Apache HTTP Server, AllowOverride directive
Apache HTTP Server, Security Tips
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Apache OCSP Stapling Not Enabled

WEB-APA-007

A TLS-enabled Apache does not set SSLUseStapling on.

Why it matters. Without stapling, every browser asks the certificate authority whether the certificate is revoked, which slows the handshake and reveals the visited site to the CA. Stapling lets the server attach a fresh signed status itself.

/etc/apache2/apache2.conf: A TLS-enabled Apache does not set SSLUseStapling on.

SSLUseStapling is not set; the default is off
Fix
Add SSLUseStapling On inside the vhost and SSLStaplingCache "shmcb:logs/ssl_stapling(32768)" outside it, as the Mozilla generator produces.
Verify
openssl s_client -connect 127.0.0.1:443 -servername <site> -status should print OCSP Response Status: successful.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-299, OWASP A02:2021, ASVS 9.2.4, NIST 800-53 SC-8, SC-17
References
Apache HTTP Server, SSLUseStapling directive
Mozilla SSL Configuration Generator
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Apache ETag Reveals Inode Numbers

WEB-APA-009

FileETag includes INode (or All), so ETag headers leak filesystem inode numbers of served files.

Why it matters. Inode numbers help distinguish servers behind a load balancer and have been used to infer file identity across hosts (CVE-2003-1418). The Apache 2.4 default of MTime Size does not include them.

/etc/apache2/apache2.conf: FileETag includes INode (or All), so ETag headers leak filesystem inode numbers of served files.

/etc/apache2/apache2.conf: FileETag INode MTime Size
Fix
Set FileETag MTime Size or FileETag None and reload.
Verify
curl -sI https://<site>/robots.txt | grep -i etag should show a two-part value, not three.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-497, OWASP A05:2021, ASVS 14.3.3, NIST 800-53 SI-11, CM-6
References
Apache HTTP Server, FileETag directive
CVE-2003-1418, Apache inode disclosure in ETag
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Apache Serves Repository and Environment Files

WEB-APA-010

No DirectoryMatch, FilesMatch or RedirectMatch rule denies .git, .svn, .hg or .env paths, so they are served if present under a document root.

Why it matters. Repository folders rebuild the source code and its history; .env files hold database passwords and application keys. Debian's default only protects .ht* files. One rule for every dot path removes the whole class, including files deployed by mistake later. The rating is Low because this is a missing safety net, not an exposure: when such a file is actually present under a document root, WEB-APP-009 and WEB-DOC-001 report it at their own higher severity, and when none is present the check passes and only notes the missing rule.

/etc/apache2/apache2.conf: No DirectoryMatch, FilesMatch or RedirectMatch rule denies .git, .svn, .hg or .env paths, so they are served if present under a document root.

no DirectoryMatch, FilesMatch or RedirectMatch rule covers .git, .svn or .env, and these exist under a document root:
/var/www/shop/.git
/var/www/shop/.env
Fix
Add to the server configuration: <DirectoryMatch "/\.(git|svn|hg)"> Require all denied </DirectoryMatch> and <FilesMatch "^\.(env|git|svn)"> Require all denied </FilesMatch> , then reload.
Verify
curl -s -o /dev/null -w '%{http_code}' https://<site>/.git/HEAD should print 403 or 404.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-538, CWE-527, OWASP A05:2021, ASVS 12.5.1, 14.3.3, NIST 800-53 CM-7, SC-28
References
Apache HTTP Server, DirectoryMatch directive
OWASP WSTG-CONF-04, Review Old Backup and Unreferenced Files
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Flask Debug Mode Enabled in Application Code

WEB-APP-007

Looks for app.run(debug=True) or app.debug = True in Flask entry files. A heuristic; the service check WEB-PY-004 covers the environment switches.

Why it matters. Debug mode in code follows the application wherever it is deployed. If the file is ever run directly instead of through a WSGI server, the Werkzeug debugger and its code console come up for every visitor.

/srv/shop-reports/app.py: Flask debug mode is enabled in code

app.run(debug=True)
Fix
Remove debug=True from app.run() and read it from the environment for local work only (app.run(debug=os.environ.get('FLASK_DEBUG') == '1')); serve production with Gunicorn or uWSGI, which never call app.run().
Verify
grep -n 'debug' app.py shows no hard-coded True.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
Medium
Standards
CWE-489, CWE-215, OWASP A05:2021, ASVS 14.3.2, NIST 800-53 CM-6, CM-7
References
Flask documentation, Debug mode
Flask documentation, Deploying to Production
Learn
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/frameworks.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

WordPress Version Disclosed

WEB-CMS-001

Checks whether WordPress sites reveal their exact version in the page or in readme.html.

Why it matters. The version number lets automated tools pick matching exploits for outdated cores and plugins.

shop.example.test: WordPress version is disclosed

generator tag: WordPress 5.2.1
/readme.html is public and states WordPress 5.2.1
Fix
Keep WordPress updated (automatic minor updates on). Remove the generator tag (remove_action('wp_head','wp_generator')) and delete readme.html after each update, or block it at the web server.
Verify
curl -s https://<site>/ | grep -i 'name="generator"'
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-497, OWASP A05:2021, A06:2021, ASVS 14.3.3, NIST 800-53 CM-7, SI-11
References
WordPress Developer Resources, Hardening WordPress
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
Source
internal/checks/web/cms.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

WordPress XML-RPC Interface Enabled

WEB-CMS-002

Checks whether xmlrpc.php answers on WordPress sites.

Why it matters. XML-RPC allows many password guesses in one request (system.multicall) and is abused for pingback amplification. Few sites still need it.

shop.example.test: xmlrpc.php is enabled

Fix
Block it at the web server (<Files xmlrpc.php> Require all denied </Files>) or disable it with a security plugin, unless Jetpack or the mobile app needs it.
Verify
curl -s https://<site>/xmlrpc.php should return 403 or 404.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
Category
Web Application Security
Effort
Low
Confidence
High
Standards
CWE-307, OWASP A07:2021, ASVS 2.2.1, NIST 800-53 AC-7, CM-7
References
WordPress Developer Resources, Brute Force Attacks (XML-RPC)
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
Source
internal/checks/web/cms.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

WordPress User Accounts Enumerable

WEB-CMS-003

Checks whether the WordPress REST API lists user accounts to anonymous visitors.

Why it matters. A list of login names halves the work of password guessing and phishing against administrators.

shop.example.test: Exposed: /wp-json/wp/v2/users (HTTP 200)

/wp-json/wp/v2/users (HTTP 200)
Fix
Restrict the users endpoint to authenticated requests with a security plugin or a small rest_endpoints filter, and use login names that differ from public display names.
Verify
curl -s https://<site>/wp-json/wp/v2/users should return 401, 403 or 404.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-204, OWASP A07:2021, NIST 800-53 CM-6, SI-11
References
WordPress Developer Resources, REST API Users endpoint
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
Source
internal/checks/web/exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

WordPress Dashboard File Editor Enabled

WEB-CMS-007

Checks whether wp-config.php leaves the built-in theme and plugin file editor enabled.

Why it matters. The editor lets any administrator account change PHP files from the browser. A stolen or phished admin session then becomes code execution on the server in one step.

/var/www/shop/wp-config.php: WordPress file editor is enabled

DISALLOW_FILE_EDIT is not set to true
Fix
Add define('DISALLOW_FILE_EDIT', true); to wp-config.php above the line that says to stop editing.
Verify
The Theme File Editor and Plugin File Editor menus disappear from the dashboard.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:L/I:L/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-94, CWE-1188, OWASP A05:2021, NIST 800-53 CM-7, AC-6
References
WordPress Developer Resources, Hardening WordPress
WordPress Developer Resources, Editing wp-config.php
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
Source
internal/checks/web/cms_more.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Joomla Version Disclosed

WEB-CMS-010

Checks whether a Joomla site serves its version manifest at /administrator/manifests/files/joomla.xml.

Why it matters. The manifest gives the exact Joomla version, which lets automated tools pick exploits for known vulnerabilities, such as the unauthenticated information disclosure CVE-2023-23752.

shop.example.test: Joomla version manifest is public

version 3.9.0
Fix
Block the folder at the web server (Apache: <Directory "/path/administrator/manifests"> Require all denied </Directory>; nginx: location ^~ /administrator/manifests/ { deny all; }) and keep Joomla updated.
Verify
curl -s -o /dev/null -w '%{http_code}' https://<site>/administrator/manifests/files/joomla.xml prints 403 or 404.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-497, OWASP A05:2021, A06:2021, ASVS 14.3.3, NIST 800-53 SI-11
References
Joomla Documentation, Security Checklist
NVD, CVE-2023-23752
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
Source
internal/checks/web/cms_more.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Drupal Version Disclosed by Changelog

WEB-CMS-011

Checks whether a Drupal site serves CHANGELOG.txt, which names the exact Drupal version.

Why it matters. The changelog tells attackers precisely which Drupal security advisories apply, as was used at scale for Drupalgeddon 2 (CVE-2018-7600).

shop.example.test: Drupal changelog is public

/core/CHANGELOG.txt: Drupal 8.5.0, 2018-03-07
Fix
Delete the changelog files after each update, or deny *.txt files in the Drupal root and core folders at the web server, and keep Drupal updated.
Verify
curl -s -o /dev/null -w '%{http_code}' https://<site>/core/CHANGELOG.txt prints 403 or 404.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-497, OWASP A05:2021, A06:2021, ASVS 14.3.3, NIST 800-53 SI-11
References
Drupal.org, Security advisories
NVD, CVE-2018-7600
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
Source
internal/checks/web/cms_more.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

WordPress Author Archive Reveals Login Names

WEB-CMS-018

Checks whether /?author=1 redirects to an author archive, which exposes the first account's login name in the address.

Why it matters. The author archive address contains the user's slug, which by default equals the login name. Together with the REST API listing (WEB-CMS-003) this gives attackers the administrator's user name for password guessing without touching the login form.

shop.example.test: /?author=1 redirects to the author archive

Location: .../author/<login-name>/
Fix
Return 404 for author queries by id (a small redirect rule or a security plugin's user enumeration protection), and give administrators a nickname and display name that differ from the login name.
Verify
curl -sI https://<site>/?author=1 | grep -i location prints nothing or a 404 page.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-204, OWASP A07:2021, NIST 800-53 CM-6, SI-11
References
WordPress Developer Resources, Brute Force Attacks
WordPress Developer Resources, Hardening WordPress
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/cms_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Dependency Manifests Exposed

WEB-EXP-009

Checks whether package manifests and lock files are downloadable.

Why it matters. Lock files list exact library versions, giving attackers a ready list to match against public vulnerabilities, and often reveal internal package names.

shop.example.test: Exposed: /composer.lock (HTTP 200)

/composer.lock (HTTP 200)
Fix
Keep manifests outside the public web root (for example serve only a public/ subfolder), or deny them at the web server.
Verify
curl -s -o /dev/null -w '%{http_code}' https://<site>/composer.lock should print 403 or 404.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-538, OWASP A05:2021, A06:2021, ASVS 12.5.1, NIST 800-53 CM-7
References
OWASP WSTG-CONF-04, Review Old Backup and Unreferenced Files for Sensitive Information
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Default Web Server Page Served

WEB-EXP-010

Checks whether a site shows the web server's default installation page.

Why it matters. Default pages reveal the server software and suggest an unmaintained or forgotten virtual host, which attackers prioritise.

shop.example.test: Exposed: / (HTTP 200)

/ (HTTP 200)
Fix
Remove the default site or replace its index page, and disable unused virtual hosts.
Verify
Open the site in a browser; the default page should not appear.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-1188, CWE-497, OWASP A05:2021, NIST 800-53 CM-7
References
OWASP WSTG-INFO-02, Fingerprint Web Server
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/exposure.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Missing X-Content-Type-Options

WEB-HDR-004

Checks that browsers are told not to guess (sniff) content types.

Why it matters. Without nosniff, a browser may execute an uploaded text or image file as script or HTML, enabling XSS through file uploads.

shop.example.test: X-Content-Type-Options is missing or not 'nosniff'


Fix
Send X-Content-Type-Options: nosniff on every response (Apache: Header always set X-Content-Type-Options nosniff; nginx: add_header X-Content-Type-Options nosniff always;).
Verify
curl -sI https://<site>/ | grep -i x-content-type-options
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:N/A:N
Category
Web Application Security
Effort
Low
Confidence
High
Standards
CWE-430, OWASP A05:2021, ASVS 14.4.4, NIST 800-53 CM-6
References
OWASP Secure Headers Project
MDN Web Docs, X-Content-Type-Options
Learn
P5: Web Security Headers and Cookies (offline: openvapt learn P5)
A8: Tracing Findings to Security Requirements (offline: openvapt learn A8)
Source
internal/checks/web/headers.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Missing Referrer-Policy

WEB-HDR-005

Checks that each site limits what URL information is leaked to other sites in the Referer header.

Why it matters. Full URLs can contain session tokens, password-reset links or personal data, which would otherwise be sent to every third-party resource and outbound link.

shop.example.test: Referrer-Policy is missing or not ''


Fix
Send Referrer-Policy: strict-origin-when-cross-origin (or no-referrer). Never use unsafe-url.
Verify
curl -sI https://<site>/ | grep -i referrer-policy
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:N/A:N
Category
Web Application Security
Effort
Low
Confidence
High
Standards
CWE-201, OWASP A05:2021, ASVS 14.4.6, NIST 800-53 CM-6
References
OWASP Secure Headers Project
MDN Web Docs, Referrer-Policy
Learn
P5: Web Security Headers and Cookies (offline: openvapt learn P5)
A8: Tracing Findings to Security Requirements (offline: openvapt learn A8)
Source
internal/checks/web/headers.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Missing Permissions-Policy

WEB-HDR-006

Checks that each site restricts powerful browser features (camera, microphone, geolocation) it does not use.

Why it matters. Restricting features limits what injected or third-party scripts can do in your visitors' browsers.

shop.example.test: Permissions-Policy is missing or not ''


Fix
Send, for example, Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=() adjusted to the features the site really uses.
Verify
curl -sI https://<site>/ | grep -i permissions-policy
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:N/A:N
Category
Web Application Security
Effort
Low
Confidence
High
Standards
CWE-1188, OWASP A05:2021, NIST 800-53 CM-6, CM-7
References
OWASP Secure Headers Project
MDN Web Docs, Permissions-Policy
Learn
P5: Web Security Headers and Cookies (offline: openvapt learn P5)
A8: Tracing Findings to Security Requirements (offline: openvapt learn A8)
Source
internal/checks/web/headers.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Server Software Version Disclosed

WEB-HDR-007

Checks whether response headers reveal exact web server, PHP or framework versions.

Why it matters. Exact versions let attackers match the site against public exploit lists in seconds. Hiding them does not fix vulnerabilities but removes free reconnaissance.

shop.example.test: Software versions are disclosed in headers

Server: Apache/2.4.29 (Ubuntu)
X-Powered-By: PHP/7.2.24
Fix
Apache: ServerTokens Prod and ServerSignature Off . nginx: server_tokens off; . PHP: expose_php = Off in php.ini . Remove X-Powered-By in the application or proxy.
Verify
curl -sI https://<site>/ | grep -Ei '^(server|x-powered-by)'
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-497, OWASP A05:2021, ASVS 14.3.3, NIST 800-53 CM-7, SI-11
References
OWASP HTTP Headers Cheat Sheet
Apache HTTP Server, ServerTokens directive
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
A8: Tracing Findings to Security Requirements (offline: openvapt learn A8)
Source
internal/checks/web/headers.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

nginx Version Shown in Server Header

WEB-NGX-001

nginx does not set server_tokens off, so responses and error pages carry the exact nginx version.

Why it matters. The version string lets an attacker pick advisories that match the server instead of guessing. Hiding it is not a fix for old software, but there is no reason to publish it.

/etc/nginx/nginx.conf: nginx does not set server_tokens off, so responses and error pages carry the exact nginx version.

/etc/nginx/conf.d/tokens.conf: server_tokens on
Fix
In the http block of nginx.conf add server_tokens off; then run nginx -t and reload.
Verify
curl -sI https://<site>/ | grep -i '^server:' should print Server: nginx with no version.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-497, OWASP A05:2021, ASVS 14.3.3, NIST 800-53 CM-6, SI-11
References
nginx documentation, ngx_http_core_module
OWASP WSTG-INFO-02, Fingerprint Web Server
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

nginx OCSP Stapling Off or Session Tickets On

WEB-NGX-005

A TLS-enabled nginx does not enable ssl_stapling, or leaves ssl_session_tickets on.

Why it matters. Without stapling, every browser asks the certificate authority whether the certificate is revoked, which slows the handshake and leaks the visited site to the CA. Session tickets encrypted with a long-lived key weaken forward secrecy when the key is never rotated; the Mozilla profiles turn them off.

/etc/nginx/nginx.conf: A TLS-enabled nginx does not enable ssl_stapling, or leaves ssl_session_tickets on.

ssl_stapling is not set; the default is off
ssl_session_tickets is not set; the default is on
Fix
Add ssl_stapling on; ssl_stapling_verify on; ssl_session_tickets off; and a resolver directive, as the Mozilla generator produces.
Verify
openssl s_client -connect 127.0.0.1:443 -servername <site> -status should print OCSP Response Status: successful.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Cryptography and TLS
Effort
Low
Confidence
High
Standards
CWE-299, CWE-326, OWASP A02:2021, ASVS 9.2.4, NIST 800-53 SC-8, SC-17
References
Mozilla SSL Configuration Generator
nginx documentation, ngx_http_ssl_module
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

Node.js Service Not Running in Production Mode

WEB-NODE-003

Checks whether Node.js services set NODE_ENV=production.

Why it matters. Express and many other frameworks treat a missing NODE_ENV as development: error pages then include stack traces with file paths, and caching and other production safeguards are off.

systemd units: Node.js services are not in production mode

shop-api.service: NODE_ENV=development
Fix
Add Environment=NODE_ENV=production to the [Service] section (systemctl edit <unit>), run systemctl daemon-reload and restart the service.
Verify
systemctl show -p Environment <unit> includes NODE_ENV=production.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-489, CWE-209, OWASP A05:2021, ASVS 14.3.2, NIST 800-53 CM-6
References
Express documentation, Production best practices: performance and reliability
OWASP Node.js Security Cheat Sheet
Learn
P13: Application Servers: Tomcat, Node.js and Python (offline: openvapt learn P13)
Source
internal/checks/web/runtimes.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

LOW

PHP Version Exposed in Headers

WEB-PHP-002

Checks whether PHP adds an X-Powered-By header with its version.

Why it matters. The header advertises the exact PHP version to every visitor and scanner.

php: expose_php = 1

Fix
In php.ini set expose_php = Off and restart PHP.
Verify
php -r "echo ini_get('expose_php');" and check the FPM pool's php.ini or php_admin_value settings.
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
Category
Information Exposure
Effort
Low
Confidence
High
Standards
CWE-497, OWASP A05:2021, ASVS 14.3.3, NIST 800-53 CM-7, SI-11
References
PHP manual, php.ini directives
OWASP PHP Configuration Cheat Sheet
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
Source
internal/checks/web/php.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

INFO

Docker Not Running in Rootless Mode

HOST-CTR-009

Reports whether the Docker daemon runs as root or in rootless mode. Informational.

Why it matters. In rootless mode the daemon and every container run inside a user namespace as an ordinary account, so a container breakout lands in that account rather than in root. It is not possible for every workload (some networking and storage features differ), so this is information for a design decision, not a failure.

docker: Docker runs as the root daemon only; rootless mode is not in use

Fix
Where the workloads allow it, install rootless Docker (dockerd-rootless-setuptool.sh install) for the service account and disable the system daemon; otherwise keep userns-remap (HOST-CTR-002) as the fallback.
Verify
docker info --format '{{.SecurityOptions}}' lists name=rootless.
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:N
Category
Secure Configuration
Effort
High
Confidence
High
Standards
CWE-250, NIST 800-53 AC-6, SC-39
References
Docker documentation, Rootless mode
NIST SP 800-190, Application Container Security Guide
Learn
P9: Containers and Kubernetes (offline: openvapt learn P9)
A5: Container Runtime Hardening Depth (offline: openvapt learn A5)
Source
internal/checks/host/containers_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

INFO

Password Expiry Warning Too Short

HOST-PAM-006

Reports whether users are warned at least 7 days before a password expires.

Why it matters. Where passwords do expire, a short or missing warning means users are locked out without notice and support staff reset passwords under pressure, which is when weak temporary passwords and social engineering succeed. This is informational: with no expiry (HOST-PWD-005) the warning never fires.

/etc/login.defs: PASS_WARN_AGE 3 (7 or more)

Fix
Set PASS_WARN_AGE 7 in /etc/login.defs, and for existing accounts chage --warndays 7 <user> .
Verify
grep '^PASS_WARN_AGE' /etc/login.defs
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-262, OWASP A07:2021, NIST 800-53 IA-5(1)
References
login.defs(5), Linux man-pages
NIST SP 800-63B-4, Digital Identity Guidelines: Authentication and Authenticator Management
Learn
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/pam_login.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

INFO

Third-Party Package Repositories Present

HOST-PKG-003

Lists package repositories that are not run by the distribution vendor, so each one can be justified.

Why it matters. Every repository can install software as root at the next update, so each one is a supplier you trust completely. Personal package archives, vendor repositories and forgotten test repositories are a common way for unpatched or abandoned software to stay on a server. This is informational: a third-party repository is a decision to review, not a defect by itself.

package repositories: 1 third-party repository host(s) configured

ppa.launchpadcontent.net (/etc/apt/sources.list.d/lab-ppa.list)
Fix
For each listed repository, record who runs it and why it is needed; remove the ones nobody can justify (delete the file under /etc/apt/sources.list.d or /etc/yum.repos.d and apt-get update or dnf clean all). Keep the rest pinned to the packages they are for (apt preferences, dnf includepkgs).
Verify
ls /etc/apt/sources.list.d/ /etc/yum.repos.d/ 2>/dev/null
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:N
Category
Patch and Vulnerability Management
Effort
Medium
Confidence
High
Standards
CWE-1357, OWASP A08:2021, NIST 800-53 CM-8, SR-3, SR-4
References
sources.list(5), Debian manual pages
NIST SP 800-40 Rev. 4, Guide to Enterprise Patch Management Planning
NIST SP 800-161 Rev. 1, Cybersecurity Supply Chain Risk Management Practices
Learn
P1: Linux Server Hardening (offline: openvapt learn P1)
P22: Authentication Policy and Package Hygiene (offline: openvapt learn P22)
Source
internal/checks/host/pkg_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

INFO

Forced Periodic Password Rotation Configured

HOST-PWD-005

Reports whether new accounts are forced to change passwords on a short fixed schedule.

Why it matters. NIST SP 800-63B-4 (section 3.1.1.2) says verifiers should not require periodic password changes, and should force a change only on evidence of compromise. Frequent forced rotation pushes users toward predictable variations. CIS Controls v8 safeguard 5.2 asks for unique passwords with a minimum length (8 characters where multi-factor authentication is used, 14 where it is not) and does not ask for periodic changes. This finding is informational: a short PASS_MAX_DAYS is not a vulnerability, but it is worth reviewing against current guidance.

/etc/login.defs: PASS_MAX_DAYS 90 forces a password change every 90 days; NIST SP 800-63B-4 advises against periodic rotation

Fix
Prefer long passphrases, a breached-password blocklist and multi-factor authentication over forced rotation. If policy allows, set PASS_MAX_DAYS 365 or 99999 in /etc/login.defs and change passwords when compromise is suspected.
Verify
grep '^PASS_MAX_DAYS' /etc/login.defs
CVSS v3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:N
Category
Identity and Authentication
Effort
Low
Confidence
High
Standards
CWE-262, NIST 800-53 IA-5(1)
References
login.defs(5), Linux man-pages
NIST SP 800-63B-4, Digital Identity Guidelines: Authentication and Authenticator Management
CIS Critical Security Controls v8, Control 5 (Account Management)
Learn
P7: Identity, Passwords and Privilege (offline: openvapt learn P7)
P15: Access Control: Accounts, Sudo and Logins (offline: openvapt learn P15)
Source
internal/checks/host/passwords.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

INFO

Apache Has No Request Filtering Module

WEB-APA-008

Neither mod_security (ModSecurity) nor mod_evasive is loaded, so Apache has no request filtering or flood control in front of the application.

Why it matters. A web application firewall or flood limiter is a defence-in-depth layer, not a requirement, and a misconfigured one breaks sites. The result is informational so you can decide with the application owner.

/etc/apache2/apache2.conf: Neither mod_security (ModSecurity) nor mod_evasive is loaded, so Apache has no request filtering or flood control in front of the application.

no security2_module or evasive20_module is loaded
Fix
Consider ModSecurity with the OWASP Core Rule Set in detection-only mode first, or mod_evasive for simple rate limiting, and tune before blocking.
Verify
apachectl -M 2>/dev/null | grep -E 'security2|evasive'
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-1188, OWASP A05:2021, ASVS 11.1.4, NIST 800-53 SC-5, SI-10
References
OWASP ModSecurity Core Rule Set
Apache HTTP Server, Security Tips
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
P25: Availability Without Load Testing (offline: openvapt learn P25)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

INFO

Dependency Lock Files Older Than a Year

WEB-APP-008

Reports composer.lock, package-lock.json, yarn.lock, Gemfile.lock and poetry.lock files not modified for 365 days or more (dependency freshness). Informational.

Why it matters. A lock file pins exact library versions. One untouched for a year means the application has had no dependency updates in that time, so every library vulnerability published since is still present. The check cannot tell whether a specific vulnerability applies; the known-vulnerability checks and composer audit or npm audit do that.

/srv/shop-laravel/composer.lock: Lock file last changed 800 days ago

/var/www/shop/admin/Gemfile.lock: Lock file last changed 800 days ago

/var/www/shop/package-lock.json: Lock file last changed 800 days ago

Fix
Run composer update / npm update / bundle update / poetry update in a test environment, run the audit command of each ecosystem (composer audit, npm audit, bundle audit, pip-audit) and deploy. Schedule dependency updates at least quarterly.
Verify
stat -c '%y %n' composer.lock package-lock.json shows a recent date.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N
Category
Patch and Vulnerability Management
Effort
Medium
Confidence
High
Standards
CWE-1104, CWE-1395, OWASP A06:2021, ASVS 14.2.1, NIST 800-53 SI-2, SA-22
References
OWASP Vulnerable Dependency Management Cheat Sheet
OWASP Top 10 2021, A06 Vulnerable and Outdated Components
Learn
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/frameworks.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

INFO

WordPress Cron Reachable by Visitors

WEB-CMS-017

Reports whether /wp-cron.php answers to anonymous requests on WordPress sites. Informational.

Why it matters. WP-Cron runs scheduled tasks when visitors load pages, and wp-cron.php can be requested directly. On busy or targeted sites that lets anyone make the server do work on demand, and it is a frequent target for resource exhaustion; a system cron job is the documented production setup.

shop.example.test: wp-cron.php answers anonymous requests

Fix
Add define('DISABLE_WP_CRON', true); to wp-config.php, run */5 * * * * www-data php /var/www/<site>/wp-cron.php from the system cron (or curl the URL from cron), and deny direct requests to wp-cron.php at the web server.
Verify
curl -s -o /dev/null -w '%{http_code}' https://<site>/wp-cron.php prints 403 or 404.
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-770, OWASP A05:2021, NIST 800-53 CM-7, SC-5
References
WordPress Developer Resources, Hooking WP-Cron Into the System Task Scheduler
WordPress Developer Resources, Hardening WordPress
Learn
P6: Information Exposure and Misconfiguration (offline: openvapt learn P6)
P14: CMS Hardening in Depth: WordPress, Joomla and Drupal (offline: openvapt learn P14)
A6: Application Framework and CMS Configuration (offline: openvapt learn A6)
Source
internal/checks/web/cms_depth.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

INFO

nginx Request Limits Not Configured

WEB-NGX-006

nginx sets no client_max_body_size, limit_req_zone or limit_conn_zone, so request size and rate rely on defaults alone.

Why it matters. Explicit limits bound what one client can upload or how fast it can call login and search pages. They are an availability and brute-force control, informational here because the right values depend on the application.

/etc/nginx/nginx.conf: nginx sets no client_max_body_size, limit_req_zone or limit_conn_zone, so request size and rate rely on defaults alone.

no client_max_body_size, limit_req_zone or limit_conn_zone directive
Fix
Set client_max_body_size to what the application needs (the default is 1m) and add limit_req_zone for login and API locations with a sensible rate. See the nginx limit_req and limit_conn module documentation.
Verify
nginx -T | grep -nE 'client_max_body_size|limit_(req|conn)_zone'
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N
Category
Secure Configuration
Effort
Low
Confidence
High
Standards
CWE-770, CWE-307, OWASP A05:2021, A07:2021, ASVS 11.1.4, NIST 800-53 SC-5, AC-7
References
nginx documentation, ngx_http_limit_req_module
nginx documentation, ngx_http_core_module
Learn
P18: Web Server Hardening: nginx and Apache (offline: openvapt learn P18)
P25: Availability Without Load Testing (offline: openvapt learn P25)
Source
internal/checks/web/serverconf.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

INFO

No security.txt Contact File

WEB-SEC-001

Checks whether each site publishes /.well-known/security.txt (RFC 9116).

Why it matters. security.txt tells researchers how to report a vulnerability. Without it, reports may go unheard or be disclosed publicly instead.

shop.example.test: No /.well-known/security.txt with a Contact field

Fix
Publish /.well-known/security.txt with at least Contact: and Expires: fields (see securitytxt.org).
Verify
curl -s https://<site>/.well-known/security.txt
CVSS v3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N
Category
Web Application Security
Effort
Low
Confidence
High
Standards
CWE-1188, NIST 800-53 RA-5(11)
References
RFC 9116, A File Format to Aid in Security Vulnerability Disclosure
Learn
P5: Web Security Headers and Cookies (offline: openvapt learn P5)
Source
internal/checks/web/docroot.go

If you believe this is a false positive, report it with the False Positive form, or accept it with an expiry date in a suppression file.

Coverage Gaps

Incomplete, Error and Skipped checks did not establish that the affected area is secure. Review the reason and rerun with the required access or corrected configuration.

IDStatusAffected Area and Reason
NET-TLS-001Incompleteshop.example.test on port 10000: Modern TLS handshake failed, so legacy protocol rejection could not be verified
NET-TLS-005Incompleteshop.example.test on port 10000: TLS certificate could not be read
NET-TLS-006Incompleteshop.example.test on port 10000: TLS certificate could not be read

All Checks

IDTitleCategoryEffortSeverityStatus
HOST-CTR-001Docker API Exposed Over TCP Without TLSNetwork ExposureLowCriticalFail
HOST-CVE-002Known Exploited Vulnerabilities PresentPatch and Vulnerability ManagementMediumCriticalFail
HOST-K8S-001Kubelet Allows Anonymous or Unauthorised AccessIdentity and AuthenticationMediumCriticalFail
HOST-SSH-003SSH Permits Empty PasswordsIdentity and AuthenticationLowCriticalFail
NET-DB-002Redis Authentication and Network BindingData ServicesLowCriticalFail
NET-DB-003MongoDB Authorization and Network BindingData ServicesLowCriticalFail
NET-DB-004PostgreSQL Trust and Broad Client AccessData ServicesLowCriticalFail
NET-DB-007Elasticsearch Security and Network BindingData ServicesLowCriticalFail
NET-SVC-002Control Plane or Remote Desktop Ports Network-ReachableNetwork ExposureMediumCriticalFail
WEB-EXP-002Environment or Secrets File ExposedInformation ExposureMediumCriticalFail
WEB-NODE-002Node.js Debugger (Inspector) Enabled in a ServiceSecure ConfigurationLowCriticalFail
WEB-PY-004Python Interactive Debugger Enabled in a ServiceSecure ConfigurationLowCriticalFail
WEB-TOM-002Tomcat Administrative Users With Default or Weak PasswordsIdentity and AuthenticationLowCriticalFail
WEB-TOM-004Tomcat AJP Connector Unprotected (Ghostcat)Web Application SecurityLowCriticalFail
HOST-CRON-001Cron Jobs Run Programs Other Users Can ModifyAccess ControlLowHighFail
HOST-CRON-002World-Writable Directory in Cron's PATHAccess ControlLowHighFail
HOST-CTR-003Privileged or Host-Namespace ContainersSecure ConfigurationMediumHighFail
HOST-CTR-004Containers Mount the Docker Socket or Host RootAccess ControlMediumHighFail
HOST-CTR-008Docker Socket Accessible to Non-AdministratorsAccess ControlLowHighFail
HOST-CTR-011Seccomp or AppArmor Disabled for ContainersSecure ConfigurationMediumHighFail
HOST-CTR-014containerd Remote API or Podman Unconfined DefaultsSecure ConfigurationMediumHighFail
HOST-CVE-001Installed OS Packages With Known VulnerabilitiesPatch and Vulnerability ManagementMediumHighFail
HOST-DKR-001Users With Root-Equivalent Docker AccessIdentity and AuthenticationMediumHighFail
HOST-FS-001Sensitive Account Files Have Unsafe PermissionsAccess ControlLowHighFail
HOST-FS-002Temporary Directory Missing the Sticky BitAccess ControlLowHighFail
HOST-FS-003World-Writable Files in System ConfigurationAccess ControlMediumHighFail
HOST-FS-004Unexpected SUID or SGID ProgramsAccess ControlMediumHighFail
HOST-FS-005Cron Files Writable by Non-Root UsersAccess ControlLowHighFail
HOST-FS-007Private TLS Keys Readable by OthersCryptography and TLSLowHighFail
HOST-FS-022Account Database Files or Their Backups Not Owned and Locked by RootAccess ControlLowHighFail
HOST-K8S-002Kubernetes Data Directory Accessible to OthersAccess ControlLowHighFail
HOST-K8S-003Kubernetes Credential Files Readable by OthersIdentity and AuthenticationLowHighFail
HOST-OS-001Operating System Past End of Security SupportPatch and Vulnerability ManagementHighHighFail
HOST-PKG-001Security Updates Waiting to Be InstalledPatch and Vulnerability ManagementMediumHighFail
HOST-PKG-002Repository Signature Checks DisabledPatch and Vulnerability ManagementLowHighFail
HOST-SEC-001Secrets in World-Readable FilesInformation ExposureMediumHighFail
HOST-SSH-001SSH Allows Direct Root LoginIdentity and AuthenticationLowHighFail
HOST-SSH-009SSH Host Private Keys Readable by OthersCryptography and TLSLowHighFail
HOST-SSH-010SSH Server Configuration Writable by Non-Root UsersAccess ControlLowHighFail
HOST-SYSD-003Service Unit Files Writable by Non-Root UsersAccess ControlLowHighFail
HOST-SYSD-004Service Programs in Writable LocationsAccess ControlLowHighFail
HOST-USR-001Extra Accounts With Root Privileges (UID 0)Identity and AuthenticationMediumHighFail
HOST-USR-002Accounts Without a PasswordIdentity and AuthenticationLowHighFail
HOST-USR-003Sudo Rules Without Password (NOPASSWD)Identity and AuthenticationLowHighFail
HOST-USR-007Insecure Trust Files in Home DirectoriesIdentity and AuthenticationLowHighFail
NET-AI-001AI Model Server or Dashboard Reachable From the NetworkNetwork ExposureLowHighFail
NET-AI-002Jupyter Configuration Weakens AuthenticationIdentity and AuthenticationLowHighFail
NET-APP-001Debugger or Application Control Ports ExposedNetwork ExposureLowHighFail
NET-DB-001Database or Cache Service Exposed to the NetworkData ServicesLowHighFail
NET-DB-005MySQL or MariaDB Unsafe Network OptionsData ServicesLowHighFail
NET-DB-006Memcached UDP or Broad Listen AddressData ServicesLowHighFail
NET-DB-008Unsafe NFS Export OptionsData ServicesLowHighFail
NET-DB-009Unsafe Samba Guest or SMB1 ConfigurationData ServicesLowHighFail
NET-DB-010BIND Open RecursionData ServicesLowHighFail
NET-DB-011BIND Zone Transfers Allowed to AnyData ServicesLowHighFail
NET-DB-012Postfix Open Relay ControlsData ServicesLowHighFail
NET-FW-002IPv6 Listeners Without IPv6 FirewallNetwork ExposureMediumHighFail
NET-FW-003Firewall Allows Sensitive Services From AnywhereNetwork ExposureLowHighFail
NET-SVC-001Cleartext Legacy Services ListeningNetwork ExposureMediumHighFail
NET-SVC-003Network Time Service Amplification RiskNetwork ExposureLowHighFail
WEB-APA-005Apache Allows TLS 1.0 or 1.1Cryptography and TLSLowHighFail
WEB-APA-006Apache Cipher Suite Includes Weak SuitesCryptography and TLSLowHighFail
WEB-APP-001Laravel Debug Mode On or Application Key MissingInformation ExposureLowHighFail
WEB-APP-003Symfony Running in the Development EnvironmentInformation ExposureLowHighFail
WEB-APP-004Rails Master Key or Secrets File ExposedAccess ControlLowHighFail
WEB-APP-006Spring Boot Actuator Endpoints Fully ExposedInformation ExposureLowHighFail
WEB-CMS-004CMS Configuration Readable by All UsersAccess ControlLowHighFail
WEB-CMS-005CMS Configuration Writable by Other UsersAccess ControlLowHighFail
WEB-CMS-012Drupal Core Past End of LifePatch and Vulnerability ManagementHighHighFail
WEB-CMS-014Joomla Core Past End of LifePatch and Vulnerability ManagementHighHighFail
WEB-CMS-019Drupal update.php Open Without AuthenticationSecure ConfigurationLowHighFail
WEB-CVE-001Vulnerable Web Application LibrariesPatch and Vulnerability ManagementMediumHighFail
WEB-DOC-001Secrets or Backups Stored Inside a Web RootInformation ExposureLowHighFail
WEB-DOC-002Web Root Files Writable by Other UsersAccess ControlLowHighFail
WEB-EXP-001Git Repository Exposed on the WebsiteInformation ExposureLowHighFail
WEB-EXP-004Backup or Database Dump Files DownloadableInformation ExposureLowHighFail
WEB-EXP-007Other Version Control Metadata ExposedInformation ExposureLowHighFail
WEB-EXP-008Log Files Downloadable From the WebsiteInformation ExposureLowHighFail
WEB-EXP-012Framework Debug Pages ExposedInformation ExposureLowHighFail
WEB-NGX-003nginx Allows TLS 1.0 or 1.1Cryptography and TLSLowHighFail
WEB-NGX-004nginx Cipher List Includes Weak SuitesCryptography and TLSLowHighFail
WEB-NODE-001Node.js Version Past End of LifePatch and Vulnerability ManagementHighHighFail
WEB-PHP-003PHP Allows Remote File InclusionSecure ConfigurationLowHighFail
WEB-PHP-004PHP Version Past End of Security SupportPatch and Vulnerability ManagementHighHighFail
WEB-PY-001Django Debug Mode EnabledInformation ExposureLowHighFail
WEB-PY-003Django Uses the Generated Development Secret KeyCryptography and TLSLowHighFail
WEB-TOM-001Tomcat Manager Reachable Without Address RestrictionWeb Application SecurityLowHighFail
HOST-BOOT-001Boot Loader Has No PasswordAccess ControlMediumMediumFail
HOST-BOOT-002UEFI Secure Boot DisabledSecure ConfigurationHighMediumFail
HOST-BOOT-003Uncommon Filesystem Modules Not DisabledSecure ConfigurationLowMediumFail
HOST-BOOT-004USB Storage Driver Not DisabledSecure ConfigurationLowMediumFail
HOST-BOOT-006No File Integrity MonitoringLogging and MonitoringMediumMediumFail
HOST-CTR-002Docker Daemon Not HardenedSecure ConfigurationMediumMediumFail
HOST-CTR-010Docker Daemon Allows Insecure Registries or Debug FeaturesSecure ConfigurationLowMediumFail
HOST-CTR-012Containers Run Without Memory or Process LimitsSecure ConfigurationMediumMediumFail
HOST-CTR-013Containers Run as Root With a Writable Root FilesystemSecure ConfigurationMediumMediumFail
HOST-FS-006Boot Loader Configuration ExposedAccess ControlLowMediumFail
HOST-FS-014World-Writable Files Outside Temporary DirectoriesAccess ControlLowMediumFail
HOST-FS-016SUID or SGID Programs Outside the Known BaselineAccess ControlMediumMediumFail
HOST-FS-017World-Writable Directories Without the Sticky BitAccess ControlLowMediumFail
HOST-KRN-001Address Space Layout Randomisation Not Fully EnabledSecure ConfigurationLowMediumFail
HOST-KRN-009Unprivileged eBPF AllowedSecure ConfigurationLowMediumFail
HOST-PAM-008Root PATH Contains Unsafe EntriesIdentity and AuthenticationLowMediumFail
HOST-PKG-005Running Kernel Older Than Installed KernelPatch and Vulnerability ManagementMediumMediumFail
HOST-PWD-001Weak Password Hashing Algorithm ConfiguredIdentity and AuthenticationLowMediumFail
HOST-PWD-002Accounts With Obsolete Password HashesIdentity and AuthenticationLowMediumFail
HOST-PWD-004No Account Lockout After Failed LoginsIdentity and AuthenticationMediumMediumFail
HOST-SSH-002SSH Password Authentication EnabledIdentity and AuthenticationLowMediumFail
HOST-SSH-004SSH Offers Weak CryptographyCryptography and TLSLowMediumFail
HOST-SSH-007SSH Forwarding Features EnabledSecure ConfigurationLowMediumFail
HOST-SSH-011SSH Legacy Trust Options EnabledIdentity and AuthenticationLowMediumFail
HOST-SVC-002Telnet Server Installed or EnabledSecure ConfigurationLowMediumFail
HOST-SVC-003rsh, rlogin, rexec or finger Server Installed or EnabledSecure ConfigurationLowMediumFail
HOST-SVC-004TFTP Server Installed or EnabledSecure ConfigurationLowMediumFail
HOST-SVC-005FTP Server Installed or EnabledSecure ConfigurationLowMediumFail
HOST-SVC-006NIS Server or Client Installed or EnabledSecure ConfigurationLowMediumFail
HOST-SYSD-001Custom Services Run as RootIdentity and AuthenticationMediumMediumFail
HOST-SYSD-005Secrets Written Into Service Unit FilesInformation ExposureLowMediumFail
HOST-UPD-002Reboot Required to Apply UpdatesPatch and Vulnerability ManagementMediumMediumFail
HOST-USR-004Duplicate User IDsIdentity and AuthenticationMediumMediumFail
HOST-USR-006Legacy NIS Entries in Account FilesIdentity and AuthenticationLowMediumFail
HOST-USR-008Duplicate Group IDs or Account NamesIdentity and AuthenticationMediumMediumFail
HOST-USR-009Password and Shadow Files Out of StepIdentity and AuthenticationLowMediumFail
NET-APP-002Application Server Ports Reachable Without a Reverse ProxyNetwork ExposureLowMediumFail
NET-DB-013Mail Cleartext Authentication AllowedCryptography and TLSLowMediumFail
NET-DB-014MySQL Symbolic Links Allowed for TablesData ServicesLowMediumFail
NET-DB-015MySQL secure_file_priv Not RestrictedData ServicesLowMediumFail
NET-DB-016MySQL Does Not Require Encrypted Client ConnectionsCryptography and TLSLowMediumFail
NET-DB-019PostgreSQL Uses md5 or password AuthenticationIdentity and AuthenticationLowMediumFail
NET-DB-020PostgreSQL SSL Not EnabledCryptography and TLSLowMediumFail
NET-DB-022PostgreSQL Password Encryption Not SCRAMIdentity and AuthenticationLowMediumFail
NET-DB-023Redis Dangerous Commands Not RestrictedData ServicesLowMediumFail
NET-DNS-002BIND DNSSEC Validation DisabledData ServicesLowMediumFail
NET-FW-001No Active Host FirewallNetwork ExposureMediumMediumFail
NET-FW-005Container Ports Bypass the Host FirewallNetwork ExposureMediumMediumFail
NET-MAIL-001Postfix SMTP TLS Not Offered or Has No CertificateCryptography and TLSLowMediumFail
NET-MAIL-002Postfix Allows TLS 1.0 or 1.1Cryptography and TLSLowMediumFail
NET-MAIL-004Dovecot Does Not Require TLSCryptography and TLSLowMediumFail
NET-SVC-004Management Panel or Monitoring Ports Network-ReachableNetwork ExposureLowMediumFail
NET-TLS-001Deprecated TLS 1.0 or 1.1 AcceptedCryptography and TLSLowMediumFail
NET-TLS-002TLS Certificate Expired or Expiring SoonCryptography and TLSLowMediumFail
NET-TLS-003Self-Signed or Mismatched TLS CertificateCryptography and TLSLowMediumFail
NET-TLS-004Weak TLS 1.2 Cipher Suites AcceptedCryptography and TLSLowMediumFail
NET-TLS-005TLS Certificate Public Key Too SmallCryptography and TLSMediumMediumFail
NET-TLS-006SHA-1 Signed TLS Leaf CertificateCryptography and TLSMediumMediumFail
WEB-APA-003Apache Directory Indexes Enabled in ConfigurationInformation ExposureLowMediumFail
WEB-APA-011Apache Has No Slow Request ProtectionSecure ConfigurationLowMediumFail
WEB-APP-002Application .env File Readable by All UsersAccess ControlLowMediumFail
WEB-APP-005Rails Production Does Not Force HTTPSWeb Application SecurityLowMediumFail
WEB-APP-009Git Repository Stored Inside a Web RootInformation ExposureLowMediumFail
WEB-APP-010Framework Writable Folders Open to All UsersAccess ControlLowMediumFail
WEB-CK-001Cookies Missing Secure, HttpOnly or SameSiteWeb Application SecurityMediumMediumFail
WEB-CMS-006WordPress Shows Debug Output to VisitorsInformation ExposureLowMediumFail
WEB-CMS-008WordPress Automatic Updates DisabledPatch and Vulnerability ManagementLowMediumFail
WEB-CMS-009Joomla Debug or Verbose Error Reporting EnabledInformation ExposureLowMediumFail
WEB-CMS-013Drupal Trusted Host Patterns Not SetWeb Application SecurityLowMediumFail
WEB-CMS-015Magento Not in Production ModeInformation ExposureLowMediumFail
WEB-CMS-016Ghost Configured With a Plain HTTP Site URLWeb Application SecurityLowMediumFail
WEB-COR-001Cross-Origin Resource Sharing Allows Any Origin With CredentialsWeb Application SecurityLowMediumFail
WEB-DOC-003Archives or Certificates Inside a Web RootInformation ExposureLowMediumFail
WEB-EXP-003PHP Information Page ExposedInformation ExposureLowMediumFail
WEB-EXP-005Directory Listing EnabledInformation ExposureLowMediumFail
WEB-EXP-006Web Server Status Page ExposedInformation ExposureLowMediumFail
WEB-EXP-011Database Administration Tool ExposedInformation ExposureLowMediumFail
WEB-HDR-001Missing HTTP Strict Transport Security (HSTS)Web Application SecurityLowMediumFail
WEB-HDR-002Missing Content Security PolicyWeb Application SecurityMediumMediumFail
WEB-HDR-003Site Can Be Framed (Clickjacking)Web Application SecurityLowMediumFail
WEB-NGX-002nginx Directory Listing Enabled in ConfigurationInformation ExposureLowMediumFail
WEB-NGX-007nginx Serves Hidden Files and FoldersInformation ExposureLowMediumFail
WEB-PHP-001PHP Displays Errors to VisitorsSecure ConfigurationLowMediumFail
WEB-PHP-005PHP Session Cookies Not HardenedWeb Application SecurityLowMediumFail
WEB-PY-002Django Accepts Any Host HeaderWeb Application SecurityLowMediumFail
WEB-PY-005Python Development Server Used in a ServiceSecure ConfigurationMediumMediumFail
WEB-TLS-001Site Available Over Plain HTTP Without RedirectCryptography and TLSLowMediumFail
WEB-TOM-003Tomcat Shutdown Port Uses the Default CommandSecure ConfigurationLowMediumFail
WEB-TOM-005Tomcat Example and Documentation Applications DeployedInformation ExposureLowMediumFail
HOST-AUD-001Audit Daemon Not Enabled at BootLogging and MonitoringLowLowFail
HOST-AUD-002Identity Files Not AuditedLogging and MonitoringLowLowFail
HOST-AUD-003Login and Logout Events Not AuditedLogging and MonitoringLowLowFail
HOST-AUD-004System Time Changes Not AuditedLogging and MonitoringLowLowFail
HOST-AUD-005Kernel Module Loading Not AuditedLogging and MonitoringLowLowFail
HOST-AUD-006Privileged Command Use Not AuditedLogging and MonitoringLowLowFail
HOST-AUD-007Audit Configuration Not ImmutableLogging and MonitoringLowLowFail
HOST-AUD-008Audit Log Files Readable by OthersLogging and MonitoringLowLowFail
HOST-AUD-009Audit Daemon Ignores a Full Log DiskLogging and MonitoringLowLowFail
HOST-AUD-010Journal Not Persistent or Not CompressedLogging and MonitoringLowLowFail
HOST-AUD-011Logs Not Forwarded to a Remote CollectorLogging and MonitoringMediumLowFail
HOST-BOOT-005Kernel Module Loading UnrestrictedSecure ConfigurationMediumLowFail
HOST-BOOT-007Prelink InstalledSecure ConfigurationLowLowFail
HOST-BOOT-008Core Dumps Not RestrictedInformation ExposureLowLowFail
HOST-CTR-005Docker Container Logs Have No Size LimitLogging and MonitoringLowLowFail
HOST-CTR-006Docker Userland Proxy EnabledSecure ConfigurationLowLowFail
HOST-CTR-007Docker Default Ulimits Not SetSecure ConfigurationLowLowFail
HOST-CTR-015Docker Content Trust Not EnabledSecure ConfigurationMediumLowFail
HOST-CVE-003Vulnerability Snapshot Outdated or Test DataPatch and Vulnerability ManagementMediumLowFail
HOST-FS-008Temporary Filesystems Allow Executables or DevicesSecure ConfigurationMediumLowFail
HOST-FS-009Default File Creation Mask Too PermissiveAccess ControlLowLowFail
HOST-FS-010/var/tmp Not a Separate FilesystemSecure ConfigurationMediumLowFail
HOST-FS-011/home Not a Separate Filesystem With nodevSecure ConfigurationMediumLowFail
HOST-FS-012Log Directories on the Root FilesystemSecure ConfigurationMediumLowFail
HOST-FS-013Temporary Filesystems Allow ExecutablesSecure ConfigurationMediumLowFail
HOST-FS-015Files With No Known Owner or GroupAccess ControlLowLowFail
HOST-FS-018Kernel Symbol Map or Initial RAM Disk Readable by OthersInformation ExposureLowLowFail
HOST-FS-019Cron and At Not Restricted to Allowed UsersAccess ControlLowLowFail
HOST-FS-020Cron Configuration Readable by Other UsersAccess ControlLowLowFail
HOST-FS-021Shell Profile Sets a Permissive File Creation MaskAccess ControlLowLowFail
HOST-IDS-001No Brute-Force Protection ServiceLogging and MonitoringLowLowFail
HOST-KRN-002Kernel Pointers Exposed to Unprivileged UsersSecure ConfigurationLowLowFail
HOST-KRN-003Kernel Log Readable by Unprivileged UsersSecure ConfigurationLowLowFail
HOST-KRN-004Setuid Programs May Dump CoreSecure ConfigurationLowLowFail
HOST-KRN-005IP Forwarding EnabledSecure ConfigurationLowLowFail
HOST-KRN-006ICMP Redirects AcceptedSecure ConfigurationLowLowFail
HOST-KRN-007Source-Routed Packets AcceptedSecure ConfigurationLowLowFail
HOST-KRN-008TCP SYN Cookies DisabledSecure ConfigurationLowLowFail
HOST-KRN-010Process Tracing Not RestrictedSecure ConfigurationLowLowFail
HOST-KRN-011Symlink Protection DisabledSecure ConfigurationLowLowFail
HOST-KRN-012Hardlink Protection DisabledSecure ConfigurationLowLowFail
HOST-KRN-013Reverse Path Filtering DisabledSecure ConfigurationLowLowFail
HOST-KRN-014Martian Packets Not LoggedSecure ConfigurationLowLowFail
HOST-KRN-015Server Sends ICMP RedirectsSecure ConfigurationLowLowFail
HOST-KRN-016Broadcast ICMP Echo AnsweredSecure ConfigurationLowLowFail
HOST-KRN-017IPv6 ICMP Redirects AcceptedSecure ConfigurationLowLowFail
HOST-KRN-018Performance Events Open to Unprivileged UsersSecure ConfigurationLowLowFail
HOST-KRN-019Magic SysRq Key EnabledSecure ConfigurationLowLowFail
HOST-KRN-020FIFO Protection in Shared Directories DisabledSecure ConfigurationLowLowFail
HOST-KRN-021Regular File Protection in Shared Directories DisabledSecure ConfigurationLowLowFail
HOST-KRN-022Unprivileged User Namespaces AllowedSecure ConfigurationLowLowFail
HOST-KRN-023IPv6 Source-Routed Packets AcceptedSecure ConfigurationLowLowFail
HOST-KRN-024Secure ICMP Redirects AcceptedSecure ConfigurationLowLowFail
HOST-KRN-025IPv6 Router Advertisements AcceptedSecure ConfigurationLowLowFail
HOST-KRN-026Bogus ICMP Error Responses LoggedSecure ConfigurationLowLowFail
HOST-KRN-027Kexec Kernel Replacement AllowedSecure ConfigurationLowLowFail
HOST-KRN-028Unprivileged userfaultfd AllowedSecure ConfigurationLowLowFail
HOST-KRN-029TTY Line Discipline Autoloading EnabledSecure ConfigurationLowLowFail
HOST-KRN-030BPF JIT Hardening OffSecure ConfigurationLowLowFail
HOST-KRN-031io_uring Open to Unprivileged UsersSecure ConfigurationLowLowFail
HOST-LOG-001System Logging Not PersistentLogging and MonitoringLowLowFail
HOST-LOG-002Security Audit Daemon Not RunningLogging and MonitoringMediumLowFail
HOST-LOG-003Security Logs Readable by All UsersLogging and MonitoringLowLowFail
HOST-LOG-004Log Rotation Not ConfiguredLogging and MonitoringLowLowFail
HOST-MAC-001No Mandatory Access Control EnforcedSecure ConfigurationHighLowFail
HOST-PAM-001Password Quality Module Not EnforcedIdentity and AuthenticationLowLowFail
HOST-PAM-002Account Lockout Releases Too QuicklyIdentity and AuthenticationLowLowFail
HOST-PAM-003su Not Restricted to an Administrative GroupIdentity and AuthenticationLowLowFail
HOST-PAM-004Password History Not EnforcedIdentity and AuthenticationLowLowFail
HOST-PAM-005Minimum Password Age Not SetIdentity and AuthenticationLowLowFail
HOST-PAM-007Inactive Accounts Never LockedIdentity and AuthenticationLowLowFail
HOST-PAM-009No Shell Idle TimeoutIdentity and AuthenticationLowLowFail
HOST-PKG-004Many Old Kernels RetainedPatch and Vulnerability ManagementLowLowFail
HOST-PKG-006Package Lists Not Refreshed AutomaticallyPatch and Vulnerability ManagementLowLowFail
HOST-PWD-003Short Minimum Password LengthIdentity and AuthenticationLowLowFail
HOST-SSH-005SSH X11 Forwarding EnabledSecure ConfigurationLowLowFail
HOST-SSH-006SSH Allows Many Authentication AttemptsIdentity and AuthenticationLowLowFail
HOST-SSH-008SSH Authentication Controls Too PermissiveIdentity and AuthenticationLowLowFail
HOST-SSH-012SSH Logging Level Too LowLogging and MonitoringLowLowFail
HOST-SSH-013SSH Authorized Keys Without Restrictions or ProtectionIdentity and AuthenticationLowLowFail
HOST-SUDO-001Sudo Commands Not Logged to a Dedicated FileLogging and MonitoringLowLowFail
HOST-SVC-001Unnecessary Legacy Services RunningSecure ConfigurationLowLowFail
HOST-SVC-007Avahi or CUPS Installed or EnabledSecure ConfigurationLowLowFail
HOST-SVC-008NFS Server or rpcbind Installed or EnabledSecure ConfigurationLowLowFail
HOST-SVC-009DHCP or DNS Server Installed or EnabledSecure ConfigurationLowLowFail
HOST-SVC-010Samba File Server Installed or EnabledSecure ConfigurationLowLowFail
HOST-SVC-011SNMP Agent or Squid Proxy Installed or EnabledSecure ConfigurationLowLowFail
HOST-SVC-012inetd Super-Server Installed or EnabledSecure ConfigurationLowLowFail
HOST-SYSD-002Custom Services Lack SandboxingSecure ConfigurationMediumLowFail
HOST-TIME-001Time Synchronisation Not ActiveLogging and MonitoringLowLowFail
HOST-UPD-001Automatic Security Updates Not ConfiguredPatch and Vulnerability ManagementLowLowFail
HOST-USR-005System Accounts With Login ShellsIdentity and AuthenticationLowLowFail
HOST-USR-010Home Directories Accessible to Other UsersAccess ControlLowLowFail
NET-DB-017MySQL Error Log Not ConfiguredLogging and MonitoringLowLowFail
NET-DB-018MySQL Resolves Client Host NamesData ServicesLowLowFail
NET-DB-021PostgreSQL Connection Logging OffLogging and MonitoringLowLowFail
NET-DNS-001BIND Version String DisclosedInformation ExposureLowLowFail
NET-FW-004Firewall Rules Open Ports With No ServiceNetwork ExposureLowLowFail
NET-MAIL-003Postfix VRFY Command EnabledInformation ExposureLowLowFail
WEB-APA-001Apache Reveals Version in Header and FooterInformation ExposureLowLowFail
WEB-APA-002Apache TRACE Method EnabledSecure ConfigurationLowLowFail
WEB-APA-004Apache AllowOverride All Permits .htaccess ControlSecure ConfigurationLowLowFail
WEB-APA-007Apache OCSP Stapling Not EnabledCryptography and TLSLowLowFail
WEB-APA-009Apache ETag Reveals Inode NumbersInformation ExposureLowLowFail
WEB-APA-010Apache Serves Repository and Environment FilesInformation ExposureLowLowFail
WEB-APP-007Flask Debug Mode Enabled in Application CodeSecure ConfigurationLowLowFail
WEB-CMS-001WordPress Version DisclosedInformation ExposureLowLowFail
WEB-CMS-002WordPress XML-RPC Interface EnabledWeb Application SecurityLowLowFail
WEB-CMS-003WordPress User Accounts EnumerableInformation ExposureLowLowFail
WEB-CMS-007WordPress Dashboard File Editor EnabledSecure ConfigurationLowLowFail
WEB-CMS-010Joomla Version DisclosedInformation ExposureLowLowFail
WEB-CMS-011Drupal Version Disclosed by ChangelogInformation ExposureLowLowFail
WEB-CMS-018WordPress Author Archive Reveals Login NamesInformation ExposureLowLowFail
WEB-EXP-009Dependency Manifests ExposedInformation ExposureLowLowFail
WEB-EXP-010Default Web Server Page ServedInformation ExposureLowLowFail
WEB-HDR-004Missing X-Content-Type-OptionsWeb Application SecurityLowLowFail
WEB-HDR-005Missing Referrer-PolicyWeb Application SecurityLowLowFail
WEB-HDR-006Missing Permissions-PolicyWeb Application SecurityLowLowFail
WEB-HDR-007Server Software Version DisclosedInformation ExposureLowLowFail
WEB-NGX-001nginx Version Shown in Server HeaderInformation ExposureLowLowFail
WEB-NGX-005nginx OCSP Stapling Off or Session Tickets OnCryptography and TLSLowLowFail
WEB-NODE-003Node.js Service Not Running in Production ModeSecure ConfigurationLowLowFail
WEB-PHP-002PHP Version Exposed in HeadersInformation ExposureLowLowFail
HOST-CTR-009Docker Not Running in Rootless ModeSecure ConfigurationHighInfoFail
HOST-PAM-006Password Expiry Warning Too ShortIdentity and AuthenticationLowInfoFail
HOST-PKG-003Third-Party Package Repositories PresentPatch and Vulnerability ManagementMediumInfoFail
HOST-PWD-005Forced Periodic Password Rotation ConfiguredIdentity and AuthenticationLowInfoFail
WEB-APA-008Apache Has No Request Filtering ModuleSecure ConfigurationLowInfoFail
WEB-APP-008Dependency Lock Files Older Than a YearPatch and Vulnerability ManagementMediumInfoFail
WEB-CMS-017WordPress Cron Reachable by VisitorsSecure ConfigurationLowInfoFail
WEB-NGX-006nginx Request Limits Not ConfiguredSecure ConfigurationLowInfoFail
WEB-SEC-001No security.txt Contact FileWeb Application SecurityLowInfoFail
NET-FW-006Firewall Exposure Map of Listening ServicesNetwork ExposureLowInfoPass
NET-LSN-001Inventory of Listening Network ServicesNetwork ExposureLowInfoPass

Methodology

Limitations

How to Cite

Report generated by OpenVAPT (unreleased build) on 2026-10-16. Using these results in research, teaching or a report? Please cite OpenVAPT.

APA 7: OpenVAPT. (2026). OpenVAPT: An open academic vulnerability assessment tool (Version unreleased build) [Computer software]. https://github.com/OpenVAPT/openvapt

BibTeX:

@software{openvapt_2026,
  author       = {{OpenVAPT}},
  title        = {{OpenVAPT: An Open Academic Vulnerability Assessment Tool}},
  year         = {2026},
  version      = {unreleased build},
  url          = {https://github.com/OpenVAPT/openvapt},
  note         = {Built by AI Cybersecurity Engineers. https://openvapt.com},
  license      = {LicenseRef-OpenVAPT-SAL-1.3}
}

Credit when you share this report: Produced with OpenVAPT (https://openvapt.com), built by AI Cybersecurity Engineers, used under the OpenVAPT Source-Available Licence 1.3. Use does not imply endorsement.

Generated locally by OpenVAPT. Nothing in this report was sent anywhere.