DEV Community

Ayus Irfang Filaras
Ayus Irfang Filaras

Posted on

Mencegah SQL Injection di Prisma dengan Middleware dan withAccelerare

Prisma adalah ORM yang sangat populer di ekosistem TypeScript dan Next.js. Namun, untuk aplikasi yang menangani input pengguna secara langsung, keamanan sangat penting. Dalam tutorial ini, kita akan belajar cara menggunakan middleware di Prisma untuk mencegah SQL injection dan mengoptimalkan query dengan withAccelerate.


🔍 Masalah yang Dihadapi

Saat menggunakan Prisma, ada beberapa pola query yang bisa berisiko terhadap SQL Injection, seperti:

  • DROP TABLE users;
  • SELECT * FROM users;
  • INSERT INTO users VALUES (...);
  • DELETE FROM users WHERE ...;
  • UPDATE users SET ...;
  • Komentar SQL yang mencurigakan (-- atau /* */)

Kita ingin memastikan bahwa Prisma dapat memblokir query berbahaya ini sebelum dieksekusi.


Solusi: Middleware Prisma dengan withAccelerate

Prisma versi terbaru (v6.4.1) mendukung middleware berbasis $extends. Kita bisa menggunakannya untuk:

  • Mencegah SQL Injection dengan memeriksa pola query.
  • Mendukung optimasi query dengan withAccelerate.

Berikut adalah implementasi lengkapnya:

import { PrismaClient } from "@prisma/client";
import { withAccelerate } from "@prisma/extension-accelerate";

const prismaClient = new PrismaClient();

const prisma = prismaClient
  .$extends(withAccelerate()) // Mengaktifkan Accelerate
  .$extends({
    query: {
      $allModels: {
        async findMany({ args, query }) {
          const forbiddenPatterns = [
            /drop\s+table/i,
            /select\s+\*/i,
            /insert\s+into/i,
            /delete\s+from/i,
            /update\s+\w+\s+set/i,
            /--/i,
            /\/\*/i,
          ];

          const argsString = JSON.stringify(args);
          if (forbiddenPatterns.some((pattern) => pattern.test(argsString))) {
            throw new Error("Query terdeteksi mengandung pola SQL injection.");
          }

          return query(args);
        },
        async findUnique({ args, query }) {
          return prisma.$queryMiddleware(args, query);
        },
        async findFirst({ args, query }) {
          return prisma.$queryMiddleware(args, query);
        },
      },
    },
  });

export default prisma;
Enter fullscreen mode Exit fullscreen mode

🔄 Bagaimana Cara Kerjanya?

  1. Memeriksa Query sebelum dieksekusi

    • Middleware membaca args dan mengubahnya menjadi string.
    • Jika ada pola SQL yang mencurigakan, query diblokir dengan error.
  2. Menangani findMany, findUnique, dan findFirst secara otomatis

    • Middleware diterapkan ke semua model tanpa perlu kode berulang.
  3. Menggunakan withAccelerate untuk optimasi

    • Menambahkan dukungan caching otomatis dari Prisma.

🚀 Penggunaan di Aplikasi Next.js

Jika Anda menggunakan Next.js dengan Prisma, cukup impor prisma seperti biasa:

import prisma from "@/lib/prisma";

async function getData() {
  return await prisma.post.findMany({
    where: { published: true },
    take: 10,
  });
}
Enter fullscreen mode Exit fullscreen mode

Semua query akan otomatis melewati middleware keamanan dan dipercepat oleh Accelerate.


Error yang Mungkin Terjadi

Saat mencoba menggunakan Prisma di Next.js dengan middleware dan withAccelerate, saya awalnya menambahkan "use server" dalam file lib/prisma.ts. Namun, saya mendapatkan error berikut:

Error: A "use server" file can only export async functions, found object.
Next.js Docs: Invalid use server value

Error ini terjadi karena Prisma tidak bisa diekspor langsung sebagai objek ketika menggunakan "use server".


Solusi: Gunakan Fungsi Async untuk Prisma

Alih-alih mengekspor Prisma secara langsung, kita perlu menggunakan fungsi async untuk memastikan Prisma hanya diakses di lingkungan server.

Perbaikan Kode

import { PrismaClient } from '@prisma/client';
import { withAccelerate } from "@prisma/extension-accelerate";

const prismaClient = new PrismaClient().$extends(withAccelerate());

export async function getPrisma() {
  return prismaClient;
}
Enter fullscreen mode Exit fullscreen mode

Lalu, gunakan Prisma dengan cara berikut dalam fungsi server:

"use server";

import { getPrisma } from "@/lib/prisma";

export async function fetchData() {
  const prisma = await getPrisma();
  const data = await prisma.user.findMany();
  return data;
}
Enter fullscreen mode Exit fullscreen mode

Dengan cara ini, Prisma hanya digunakan dalam lingkungan server, menghindari error yang terjadi sebelumnya.

Image of Quadratic

Free AI chart generator

Upload data, describe your vision, and get Python-powered, AI-generated charts instantly.

Try Quadratic free

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs