LA NINA // BLOG
Kembali ke Indeks Catatan

Rekayasa Keamanan Graph Database: Mitigasi Cypher Injection, Traversal DoS, dan Otorisasi AST pada Neo4j & GraphQL

Paradigma Keamanan pada Property Graph Model

Adopsi arsitektur berbasis graph database mengalami peningkatan eksponensial seiring kebutuhan pemodelan relasi data kompleks multi-entitasβ€”seperti jejaring finansial, otorisasi RBAC/ABAC terdistribusi, serta mesin rekomendasi real-time. Dalam ekosistem cloud modern, integrasi antara GraphQL dan Neo4j menjadi standar de facto melalui engine seperti @neo4j/graphql.

Mekanisme ini memungkinkan klien melakukan kueri deklaratif terhadap Abstract Syntax Tree (AST) GraphQL, yang kemudian diterjemahkan secara dinamis menjadi kueri graf deklaratif Cypher dan dieksekusi langsung pada mesin database.

TEXT
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Client Workload (Mobile App / Internal Dashboard)      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚ GraphQL Query AST (HTTP POST)
                           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ API Gateway & GraphQL Runtime (Node.js / Go)           β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ AST Validation -> Depth Limiting -> Cost Analysisβ”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                          β”‚ Parameterized Cypher Generation
β”‚                          β–Ό                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ Neo4j Driver (Bolt Protocol / TLS 1.3)          β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚ Bolt Stream (Port 7687)
                           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Neo4j Graph Database Cluster (Isolated VPC 192.0.2.0)   β”‚
β”‚  - APOC Security Sandboxing                            β”‚
β”‚  - Parameter Binding & Cypher Query Engine             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Namun, fleksibilitas ekspresi relasional ini memunculkan lanskap ancaman baru (attack surface). Kesalahan konfigurasi pada middleware, ketergantungan pada dynamic string concatenation, atau kelalaian dalam validasi kedalaman AST dapat mengekspos infrastruktur terhadap Cypher Injection (CIn), Denial of Service melalui Traversal Kartesian, hingga kebocoran data sensitif melalui primitives database.


1. Anatomi Cypher Injection (CIn) pada Resolver Dinamis

Cypher Injection analog dengan SQL Injection pada database relasional, namun memiliki kapabilitas eksfiltrasi yang jauh lebih destruktif karena sifat traversal graf yang bebas batas (unbounded hops). Kerentanan ini umumnya timbul ketika pengembang menginterpolasi parameter klien langsung ke dalam blok Cypher kustom atau directive @cypher.

Contoh Implementasi Rawan (Vulnerable Pattern):

JAVASCRIPT
// CONTOH RAWAN: Interpolasi parameter langsung tanpa sanitasi AST
async function resolveAccountTransactions(parent, args, context) {
  const { accountId, filterTag } = args;
  
  // VULNERABILITY: filterTag digabungkan langsung ke string query
  const query = `
    MATCH (a:Account {uuid: '${accountId}'})-[:TRANSFERRED]->(t:Transaction)
    WHERE t.tag = '${filterTag}'
    RETURN t.id AS id, t.amount AS amount, t.timestamp AS timestamp
  `;
  
  const session = context.driver.session();
  try {
    const result = await session.run(query);
    return result.records.map(record => record.toObject());
  } finally {
    await session.close();
  }
}

Jika aktor ancaman mengirimkan muatan payload eksploitasi pada parameter filterTag:

TEXT
Payload Input:
' OR 1=1 WITH t MATCH (s:SystemSecret) RETURN s.key AS id, 0 AS amount, s.value AS timestamp //

Query yang dikompilasi oleh Neo4j engine berubah menjadi:

CYPHER
MATCH (a:Account {uuid: 'ACC-9901'})-[:TRANSFERRED]->(t:Transaction)
WHERE t.tag = '' OR 1=1 WITH t MATCH (s:SystemSecret) RETURN s.key AS id, 0 AS amount, s.value AS timestamp //'
RETURN t.id AS id, t.amount AS amount, t.timestamp AS timestamp

Hasilnya, pembatas filter dilewati sepenuhnya, dan node sensitif SystemSecret dieksfiltrasi melalui saluran respon GraphQL yang sah.


2. Eksploitasi Graph Traversal DoS (Cartesian Explosion)

Model relasional graf secara inheren mendukung relasi sirkular (bidirectional/cyclic relationships). Dalam kueri GraphQL, ketiadaan restriksi kedalaman (query depth) memungkinkan penyerang menyusun payload rekursif berulang yang memaksa database melakukan traversal eksponensial.

GRAPHQL
# Eksploitasi Nested Circular Traversal (DoS Attack)
query GraphExplosionPayload {
  organization(id: "ORG-RFC5737-01") {
    departments {
      members {
        teams {
          members {
            teams {
              members {
                teams {
                  members {
                    name
                    accessTokens {
                      token
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Dalam skenario di mana sebuah organisasi memiliki 20 departemen, masing-masing 50 anggota, dan tiap anggota tergabung dalam 5 tim, kompleksitas komputasi melonjak tajam ke skala $\mathcal{O}(V^K)$ di mana $K$ adalah kedalaman nesting.

Hal ini mengakibatkan:

  1. Alokasi memori heap JVM Neo4j habis seketika (OutOfMemoryError).
  2. Pemanfaatan CPU simpul database mencapai 100% (thread starvation).
  3. Sambungan soket klien lain mengalami timeout, melumpuhkan layanan di seluruh kluster.

3. Vektor SSRF & Eksfiltrasi File via Database Primitives

Secara default, fungsi bawaan Cypher seperti LOAD CSV dirancang untuk memuat dataset dari sumber eksternal via HTTP/HTTPS atau filesystem lokal. Jika Cypher Injection berhasil dieksekusi pada instans yang tidak terisolasi, fungsi ini dapat dipersenjatai untuk melakukan Server-Side Request Forgery (SSRF) dan pembacaan berkas internal:

CYPHER
// Eksfiltrasi data kredensial metadata instance cloud via LOAD CSV
LOAD CSV FROM 'http://198.51.100.254/computeMetadata/v1/instance/service-accounts/default/token' AS line
RETURN line[0] AS leaked_metadata

Kondisi diperparah jika ekstensi APOC (Awesome Procedures on Cypher) dipasang tanpa pembatasan keamanan (unrestricted mode). Prosedur seperti apoc.load.json, apoc.import.file, atau apoc.export.csv memberikan akses penuh kepada penyerang untuk membaca filesystem host dan mengeksekusi arbitrary network egress.


4. Arsitektur Pertahanan & Panduan Hardening Komprehensif

Untuk melindungi infrastruktur Neo4j dan GraphQL pada standar produksi enterprise, strategi pertahanan berlapis (Defense-in-Depth) wajib ditegakkan dari lapisan gateway hingga kernel database.

A. Validasi AST & Pembatasan Kedalaman Kueri (Depth & Complexity Limiting)

Pasang middleware analisis statis AST pada gateway GraphQL untuk menolak kueri sebelum mencapai resolver:

TYPESCRIPT
// gateway-security.ts (Konfigurasi Apollo Server dengan Depth Limiting)
import { ApolloServer } from '@apollo/server';
import depthLimit from 'graphql-depth-limit';
import { createComplexityLimitRule } from 'graphql-validation-complexity';

const server = new ApolloServer({
  schema,
  validationRules: [
    // Membatasi kedalaman traversal nesting maksimal 5 tingkat
    depthLimit(5),
    // Menghitung bobot biaya komputasi field kueri
    createComplexityLimitRule(1000, {
      scalarCost: 1,
      objectCost: 5,
      listFactor: 10,
      onCost: (cost) => console.log(`[AST Audit] Evaluated Query Cost: ${cost}`)
    })
  ],
  // Nonaktifkan Introspection & Playground di lingkungan produksi
  introspection: process.env.NODE_ENV !== 'production'
});

B. Penegakan Otorisasi Deklaratif Berbasis Claims (@authorization)

Hindari logika otorisasi manual di dalam resolver. Manfaatkan directive @authorization pada skema Neo4j GraphQL Library untuk memvalidasi JWT claims secara presisi pada level AST generator:

GRAPHQL
# schema.graphql - Penegakan Zero-Trust Data Access
type Account @authorization(
  validate: [
    # Hanya pemilik akun sah atau role SEC_ADMIN yang dapat membaca data
    {
      operations: [READ],
      where: {
        OR: [
          { node: { ownerId: "$jwt.sub" } },
          { jwt: { roles_INCLUDES: "SEC_ADMIN" } }
        ]
      }
    },
    # Mutasi update hanya diizinkan bagi entitas terverifikasi
    {
      operations: [UPDATE, DELETE],
      where: { jwt: { roles_INCLUDES: "SEC_ADMIN" } }
    }
  ]
) {
  uuid: ID! @id
  ownerId: String!
  accountNumber: String!
  balance: Float!
  transactions: [Transaction!]! @relationship(type: "TRANSFERRED", direction: OUT)
}

C. Parameterized Query Binding Mutlak

Seluruh kueri kustom Cypher harus menggunakan parameter binding resmi protokol Bolt. Mesin Cypher memperlakukan parameter sebagai nilai literal murni, menghilangkan celah injeksi:

TYPESCRIPT
// secure-resolver.ts - Parameterized Cypher Binding
async function getAccountSafely(driver: neo4j.Driver, accountId: string, filterTag: string) {
  const session = driver.session({ defaultAccessMode: neo4j.session.READ });
  try {
    const cypher = `
      MATCH (a:Account {uuid: $accountId})-[:TRANSFERRED]->(t:Transaction)
      WHERE t.tag = $filterTag
      RETURN t.id AS id, t.amount AS amount, t.timestamp AS timestamp
    `;
    
    // Parameter dikirim sebagai dictionary terpisah via protokol biner Bolt
    const result = await session.run(cypher, {
      accountId: accountId,
      filterTag: filterTag
    });
    
    return result.records.map(rec => rec.toObject());
  } finally {
    await session.close();
  }
}

D. Hardening Konfigurasi Engine Neo4j (neo4j.conf)

Kunci antarmuka jaringan dan nonaktifkan kapabilitas impor/ekspor berbahaya pada berkas konfigurasi /etc/neo4j/neo4j.conf:

INI
# /etc/neo4j/neo4j.conf - Production Hardening Specification

# 1. Batasi listener hanya pada interface internal VPC privat (RFC 5737 Synthetic Subnet)
server.default_listen_address=192.0.2.10
server.bolt.listen_address=192.0.2.10:7687
server.http.listen_address=192.0.2.10:7474
server.https.listen_address=192.0.2.10:7473

# 2. Nonaktifkan akses web browser interface publik jika tidak digunakan
dbms.browser.remote_csv_limits=0

# 3. Karantina Prosedur APOC & File IO Primitives
dbms.security.procedures.unrestricted=
dbms.security.procedures.allowlist=apoc.coll.*,apoc.date.*,apoc.math.*
apoc.import.file.enabled=false
apoc.export.file.enabled=false
apoc.import.file.use_neo4j_config=true

# 4. Batasi alokasi waktu eksekusi kueri maksimum (Anti-DoS)
dbms.transaction.timeout=15s
dbms.jvm.additional=-XX:+UseG1GC -Xms8g -Xmx8g

Ringkasan Matriks Pertahanan

Vektor SeranganMekanisme EksploitasiMitigasi UtamaKomponen Enforcer
Cypher InjectionString concat pada directive @cypherParameter Binding & Prepared StatementsGraphQL Resolver / Neo4j Driver
Traversal DoSKueri siklik rekursif tanpa batasAST Depth Limiting & Cost Analysis (Depth $\le$ 5)API Gateway / GraphQL Engine
SSRF / File ReadPenyalahgunaan LOAD CSV & APOCapoc.import.file.enabled=false, Allowlist ProsedurNeo4j Engine Configuration
BOLA / IDORManipulasi ID mutasi autogeneratedDeklaratif @authorization berbasis JWT Claims@neo4j/graphql Schema AST
ReconnaissanceGraphQL Introspection & Browser exposureNonaktifkan Introspection di Prod, VPC BindingApollo Server / Firewall VPC

Dengan menerapkan validasi AST ketat di sisi gerbang GraphQL, otorisasi berbasis klaim JWT pada deklarasi skema, serta penguncian ketat prosedur APOC di sisi database, organisasi dapat memanfaatkan keunggulan pemodelan graf secara maksimal tanpa mengorbankan postur keamanan sistem.

Kembali ke Atas ↑