CIS Neo4j 5 Benchmark

Security configuration recommendations for Neo4j 5 graph database

v1.0.0 02-2025

Overview

▶

This benchmark provides prescriptive guidance for establishing a secure configuration posture for the Neo4j 5 graph database. It covers installation security, authentication and authorization, network security, logging, database configuration, and backup procedures using neo4j-admin, cypher-shell, and neo4j.conf configuration.

18Recommendations
6Sections
2Profile Levels
SectionAreaFocus
1Installation & PatchingVersion management and dedicated service account configuration
2Authentication & AuthorizationNative auth, password policies, lockout, RBAC, and fine-grained access
3Network SecurityBind addresses, HTTPS, and Bolt TLS encryption enforcement
4Logging & AuditingSecurity event logging and query audit logging
5Database ConfigurationProcedure restrictions, JMX security, and resource limits
6Backup & RecoveryDatabase backup scheduling and integrity verification

Profile Definitions

▶
ProfileDescriptionIntended Use
L1Level 1 — StandardEssential security for all Neo4j 5 deployments; minimal performance impact.
L2Level 2 — HardenedAdvanced hardening for PCI-DSS, HIPAA, or high-security environments.

1 — Installation & Patching

▶

1.1 Version & Service Account

▶
1.1.1 Ensure Neo4j is running the latest stable version (Manual)
L1 Manual
Description

This recommendation verifies that Neo4j is running the latest stable version on the Neo4j 5 graph database. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Neo4j 5 graph database vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check Neo4j version:
neo4j version

# Or via Cypher:
cypher-shell -u neo4j -p PASSWORD \
  "CALL dbms.components() YIELD name, versions RETURN name, versions"
Remediation
# Upgrade to latest stable release:
# Stop Neo4j:
systemctl stop neo4j

# Debian/Ubuntu:
apt update && apt install -y neo4j

# RHEL/CentOS:
dnf update -y neo4j

systemctl start neo4j
1.1.2 Ensure Neo4j runs as a non-root dedicated user (Automated)
L1 Auto
Description

This recommendation verifies that Neo4j runs as a non-root dedicated user on the Neo4j 5 graph database. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Neo4j 5 graph database vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Verify Neo4j runs as non-root:
ps aux | grep neo4j | grep -v grep

# Check service user:
grep '^User=' /lib/systemd/system/neo4j.service

# Verify file ownership:
ls -la /var/lib/neo4j/ | head -5
Remediation
# Configure Neo4j to run as dedicated user:
useradd -r -s /bin/false neo4j
chown -R neo4j:neo4j /var/lib/neo4j /var/log/neo4j /etc/neo4j

# In systemd unit:
# [Service]
# User=neo4j
# Group=neo4j

systemctl daemon-reload && systemctl restart neo4j

2 — Authentication & Authorization

▶

2.1 Authentication

▶
2.1.1 Ensure authentication is enabled (Automated)
L1 Auto
Description

This recommendation verifies that authentication is enabled on the Neo4j 5 graph database. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Neo4j 5 graph database vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Verify authentication is enabled:
grep 'dbms.security.auth_enabled' /etc/neo4j/neo4j.conf

# Should return: dbms.security.auth_enabled=true
# Or in 5.x:
grep 'server.security.auth_enabled' /etc/neo4j/neo4j.conf
Remediation
# Enable authentication in neo4j.conf:
# For Neo4j 5.x:
server.security.auth_enabled=true

# Restart Neo4j:
systemctl restart neo4j
2.1.2 Ensure default password is changed (Manual)
L1 Manual
Description

This recommendation verifies that default password is changed on the Neo4j 5 graph database. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Neo4j 5 graph database vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check if default password was changed:
cypher-shell -u neo4j -p neo4j "RETURN 1" 2>&1
# If successful, default password is still active

# List all users:
cypher-shell -u neo4j -p PASSWORD "SHOW USERS"
Remediation
# Change default neo4j password:
cypher-shell -u neo4j -p neo4j
# Then run:
ALTER CURRENT USER SET PASSWORD FROM 'neo4j' TO 'N3w$trong!P@ss';

# Or via neo4j-admin:
neo4j-admin dbms set-initial-password 'N3w$trong!P@ss'
2.1.3 Ensure minimum password length is configured (Automated)
L1 Auto
Description

This recommendation verifies that minimum password length is configured on the Neo4j 5 graph database. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Neo4j 5 graph database vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Verify minimum password length:
grep 'dbms.security.auth_minimum_password_length' /etc/neo4j/neo4j.conf

# Check password policy:
cypher-shell -u neo4j -p PASSWORD \
  "CALL dbms.listConfig() YIELD name, value WHERE name CONTAINS 'password' RETURN name, value"
Remediation
# Set minimum password length in neo4j.conf:
dbms.security.auth_minimum_password_length=14

# Restart:
systemctl restart neo4j
2.1.4 Ensure account lockout is configured (Automated)
L1 Auto
Description

This recommendation verifies that account lockout is configured on the Neo4j 5 graph database. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Neo4j 5 graph database vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check maximum failed attempts:
grep 'dbms.security.auth_max_failed_attempts' /etc/neo4j/neo4j.conf

# Check lockout duration:
grep 'dbms.security.auth_lock_time' /etc/neo4j/neo4j.conf
Remediation
# Configure account lockout in neo4j.conf:
dbms.security.auth_max_failed_attempts=5
dbms.security.auth_lock_time=300s

systemctl restart neo4j

2.2 Authorization

▶
2.2.1 Ensure least privilege roles are configured (Manual)
L1 Manual
Description

This recommendation verifies that least privilege roles are configured on the Neo4j 5 graph database. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Neo4j 5 graph database vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# List all roles:
cypher-shell -u neo4j -p PASSWORD "SHOW ROLES"

# Check role assignments:
cypher-shell -u neo4j -p PASSWORD \
  "SHOW USERS YIELD user, roles RETURN user, roles"
Remediation
# Create custom role with least privilege:
cypher-shell -u neo4j -p PASSWORD <<'EOF'
CREATE ROLE analyst;
GRANT MATCH {*} ON GRAPH * TO analyst;
GRANT TRAVERSE ON GRAPH * TO analyst;
DENY WRITE ON GRAPH * TO analyst;
GRANT ROLE analyst TO analyst_user;
EOF
2.2.2 Ensure fine-grained access control is enforced (Manual)
L2 Manual
Description

This recommendation ensures that fine-grained access control is enforced on the Neo4j 5 graph database. Enforcing this requirement establishes a minimum security standard and prevents insecure configurations.

Rationale

Without this enforcement, the Neo4j 5 graph database may accept insecure configurations that weaken overall security posture. Mandating this control ensures consistent protection against common attack vectors.

Audit
# Verify fine-grained access control:
cypher-shell -u neo4j -p PASSWORD \
  "SHOW PRIVILEGES YIELD role, access, action, segment RETURN role, access, action, segment"

# Check for overly broad grants:
cypher-shell -u neo4j -p PASSWORD "SHOW ROLE admin PRIVILEGES"
Remediation
# Apply fine-grained privileges:
cypher-shell -u neo4j -p PASSWORD <<'EOF'
DENY CREATE NEW NODE LABEL ON GRAPH production TO developer;
DENY DELETE ON GRAPH production TO analyst;
GRANT READ {name, email} ON GRAPH production NODE Person TO analyst;
EOF

3 — Network Security

▶

3.1 Transport & Binding

▶
3.1.1 Ensure listening address is restricted (Automated)
L1 Auto
Description

This setting ensures that listening address is restricted on the Neo4j 5 graph database. Restricting this capability limits potential abuse and enforces the principle of least privilege across the environment.

Rationale

Unrestricted access to this capability could allow unauthorized users or processes to perform actions beyond their intended scope. Applying least-privilege principles to the Neo4j 5 graph database is essential for defense in depth.

Audit
# Check listening address:
grep 'server.default_listen_address' /etc/neo4j/neo4j.conf
grep 'server.bolt.listen_address' /etc/neo4j/neo4j.conf
grep 'server.http.listen_address' /etc/neo4j/neo4j.conf

# Verify actual bindings:
ss -tlnp | grep -E '7474|7473|7687'
Remediation
# Restrict listening to specific interface in neo4j.conf:
server.default_listen_address=127.0.0.1

# Or bind to specific internal IP:
server.bolt.listen_address=10.0.1.5:7687
server.http.listen_address=10.0.1.5:7474

systemctl restart neo4j
3.1.2 Ensure HTTPS is enabled and HTTP is disabled (Automated)
L1 Auto
Description

This recommendation verifies that HTTPS is enabled and HTTP is disabled on the Neo4j 5 graph database. Disabling or removing unnecessary components reduces the attack surface and limits potential vectors for exploitation.

Rationale

Running unnecessary components on the Neo4j 5 graph database increases the attack surface and the risk of exploitation. Disabling or removing them follows the principle of least functionality and reduces exposure to known vulnerabilities.

Audit
# Verify HTTPS is enabled and HTTP is disabled:
grep 'server.https.enabled' /etc/neo4j/neo4j.conf
grep 'server.http.enabled' /etc/neo4j/neo4j.conf
grep 'server.bolt.tls_level' /etc/neo4j/neo4j.conf
Remediation
# Enable HTTPS and disable HTTP in neo4j.conf:
server.https.enabled=true
server.http.enabled=false
server.bolt.tls_level=REQUIRED

# Configure SSL:
dbms.ssl.policy.https.enabled=true
dbms.ssl.policy.https.base_directory=certificates/https
dbms.ssl.policy.https.private_key=private.key
dbms.ssl.policy.https.public_certificate=public.crt

systemctl restart neo4j
3.1.3 Ensure Bolt encryption is required (Automated)
L1 Auto
Description

This recommendation ensures that Bolt encryption is required on the Neo4j 5 graph database. Enforcing this requirement establishes a minimum security standard and prevents insecure configurations.

Rationale

Without this enforcement, the Neo4j 5 graph database may accept insecure configurations that weaken overall security posture. Mandating this control ensures consistent protection against common attack vectors.

Audit
# Verify Bolt encryption is required:
grep 'server.bolt.tls_level' /etc/neo4j/neo4j.conf
# Should be: REQUIRED

# Check SSL policy for bolt:
grep 'dbms.ssl.policy.bolt' /etc/neo4j/neo4j.conf
Remediation
# Enforce Bolt TLS in neo4j.conf:
server.bolt.tls_level=REQUIRED

dbms.ssl.policy.bolt.enabled=true
dbms.ssl.policy.bolt.base_directory=certificates/bolt
dbms.ssl.policy.bolt.private_key=private.key
dbms.ssl.policy.bolt.public_certificate=public.crt
dbms.ssl.policy.bolt.client_auth=NONE

systemctl restart neo4j

4 — Logging & Auditing

▶

4.1 Log Configuration

▶
4.1.1 Ensure security logging is enabled (Automated)
L1 Auto
Description

This recommendation verifies that security logging is enabled on the Neo4j 5 graph database. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Neo4j 5 graph database vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Verify security log is enabled:
grep 'dbms.security.log_successful_authentication' /etc/neo4j/neo4j.conf
grep 'dbms.logs.security.level' /etc/neo4j/neo4j.conf

# Check log file exists:
ls -la /var/log/neo4j/security.log
Remediation
# Enable security logging in neo4j.conf:
dbms.security.log_successful_authentication=true
dbms.logs.security.level=INFO

# Set log rotation:
dbms.logs.security.rotation.size=20m
dbms.logs.security.rotation.keep_number=7

systemctl restart neo4j
4.1.2 Ensure query logging is enabled (Automated)
L2 Auto
Description

This recommendation verifies that query logging is enabled on the Neo4j 5 graph database. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Neo4j 5 graph database vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Verify query logging:
grep 'dbms.logs.query.enabled' /etc/neo4j/neo4j.conf
grep 'dbms.logs.query.threshold' /etc/neo4j/neo4j.conf

# Check log:
ls -la /var/log/neo4j/query.log
Remediation
# Enable query logging in neo4j.conf:
dbms.logs.query.enabled=INFO
dbms.logs.query.threshold=0s
dbms.logs.query.parameter_logging_enabled=false

# Set rotation:
dbms.logs.query.rotation.size=20m
dbms.logs.query.rotation.keep_number=7

systemctl restart neo4j

5 — Database Configuration

▶

5.1 Runtime Security

▶
5.1.1 Ensure unrestricted procedures are limited (Automated)
L1 Auto
Description

This setting ensures that unrestricted procedures are limited on the Neo4j 5 graph database. Restricting this capability limits potential abuse and enforces the principle of least privilege across the environment.

Rationale

Unrestricted access to this capability could allow unauthorized users or processes to perform actions beyond their intended scope. Applying least-privilege principles to the Neo4j 5 graph database is essential for defense in depth.

Audit
# Verify unrestricted procedures are limited:
grep 'dbms.security.procedures.unrestricted' /etc/neo4j/neo4j.conf

# List loaded procedures:
cypher-shell -u neo4j -p PASSWORD "SHOW PROCEDURES YIELD name RETURN name"
Remediation
# Restrict procedure access in neo4j.conf:
# Only allow specific safe procedures:
dbms.security.procedures.unrestricted=apoc.load.*,apoc.meta.*

# Allowlist procedures:
dbms.security.procedures.allowlist=apoc.coll.*,apoc.load.*,gds.*

systemctl restart neo4j
5.1.2 Ensure remote shell and JMX are restricted (Automated)
L1 Auto
Description

This setting ensures that remote shell and JMX are restricted on the Neo4j 5 graph database. Restricting this capability limits potential abuse and enforces the principle of least privilege across the environment.

Rationale

Unrestricted access to this capability could allow unauthorized users or processes to perform actions beyond their intended scope. Applying least-privilege principles to the Neo4j 5 graph database is essential for defense in depth.

Audit
# Verify remote shell is disabled:
grep 'dbms.shell.enabled' /etc/neo4j/neo4j.conf

# Check JMX remote is restricted:
grep 'dbms.jvm.additional.*jmxremote' /etc/neo4j/neo4j.conf
Remediation
# Disable remote shell and restrict JMX in neo4j.conf:
dbms.shell.enabled=false

# Restrict JMX:
dbms.jvm.additional=-Dcom.sun.management.jmxremote.authenticate=true
dbms.jvm.additional=-Dcom.sun.management.jmxremote.ssl=true
dbms.jvm.additional=-Dcom.sun.management.jmxremote.local.only=true

systemctl restart neo4j
5.1.3 Ensure memory limits and transaction timeout are configured (Automated)
L1 Auto
Description

This recommendation verifies that memory limits and transaction timeout are configured on the Neo4j 5 graph database. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Neo4j 5 graph database vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Verify page cache and memory settings:
grep 'server.memory.heap' /etc/neo4j/neo4j.conf
grep 'server.memory.pagecache' /etc/neo4j/neo4j.conf

# Check runtime:
cypher-shell -u neo4j -p PASSWORD \
  "CALL dbms.listConfig() YIELD name, value WHERE name CONTAINS 'memory' RETURN name, value"
Remediation
# Configure memory limits in neo4j.conf:
server.memory.heap.initial_size=2g
server.memory.heap.max_size=4g
server.memory.pagecache.size=2g

# Set transaction timeout:
db.transaction.timeout=60s

systemctl restart neo4j

6 — Backup & Recovery

▶

6.1 Backup Configuration

▶
6.1.1 Ensure regular backups are configured (Manual)
L1 Manual
Description

This recommendation verifies that regular backups are configured on the Neo4j 5 graph database. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Neo4j 5 graph database vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Verify backup configuration:
neo4j-admin database check neo4j

# Check last backup:
ls -la /var/lib/neo4j/backups/

# Verify backup integrity:
neo4j-admin database check --check-consistency neo4j
Remediation
# Perform database backup:
neo4j-admin database dump neo4j --to-path=/var/lib/neo4j/backups/

# Or online backup (Enterprise):
neo4j-admin database backup neo4j --to-path=/var/lib/neo4j/backups/

# Schedule via cron:
# 0 2 * * * neo4j-admin database dump neo4j --to-path=/backups/neo4j-$(date +\%Y\%m\%d).dump