#how to write safe server actions?

1 messages · Page 1 of 1 (latest)

peak imp
#

What are the common mistakes and best practices of making server actions?

fallow sableBOT
#

Hi @peak imp. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

To write safe Server Actions in Next.js, you should treat them with the same security rigor as public API endpoints. Here are the best practices and common mistakes, based on the official documentation:


Best Practices for Safe Server Actions

  1. Always Authenticate and Authorize

    • Ensure the user is authenticated and authorized before performing any sensitive operation. For example, check the user's session or role before proceeding:
      'use server'
      import { verifySession } from '@/app/lib/dal'
      
      export async function serverAction(formData: FormData) {
        const session = await verifySession()
        const userRole = session?.user?.role
        if (userRole !== 'admin') {
          return null
        }
        // Proceed with the action
      }
      
      How to implement authentication in Next.js > Authorization
  2. Validate All Client Input

    • Never trust incoming data. Always validate and sanitize input from forms, URL parameters, headers, etc. Use libraries like zod for schema validation:
      'use server'
      import { z } from 'zod'
      const schema = z.object({ email: z.string().email() })
      
      export default async function createUser(formData: FormData) {
        const validatedFields = schema.safeParse({
          email: formData.get('email'),
        })
        if (!validatedFields.success) {
          return { errors: validatedFields.error.flatten().fieldErrors }
        }
        // Mutate data
      }
      
      How to create forms with Server Actions
#
  1. Avoid Side Effects During Rendering

  2. Protect Against CSRF

    • Server Actions only accept POST requests and compare the Origin and Host headers to prevent CSRF. For advanced setups (e.g., behind proxies), configure serverActions.allowedOrigins in next.config.js.
      module.exports = {
        experimental: {
          serverActions: {
            allowedOrigins: ['my-proxy.com', '*.my-proxy.com'],
          },
        },
      }
      
      Allowed origins (advanced)
  3. Limit Request Body Size

  4. Audit and Isolate Data Access

    • Keep your data access layer isolated. Do not import database packages or environment variables outside of this layer.
      Auditing
  5. Remove Sensitive Data from Responses


Common Mistakes

#
  • Not validating user input: Accepting and trusting data directly from the client.
  • Missing authentication/authorization checks: Allowing actions to be performed by unauthorized users.
  • Performing mutations during render: Causing unintended side effects and security issues.
  • Exposing sensitive environment variables: Only variables prefixed with NEXT_PUBLIC_ are safe for the client.
  • Not configuring allowed origins in complex deployments: This can open up CSRF vulnerabilities in multi-domain setups.
  • Logging or returning sensitive data: Accidentally leaking secrets or user data.

By following these practices and avoiding the common mistakes, you can ensure your Server Actions are secure and robust in Next.js. Always treat Server Actions as public endpoints and apply the same security standards as you would for any backend API route.

Mutating Data: Security features and best practices

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@runic oriole Kapa.ai is still learning and improving, please let me know how I did by reacting below.

peak imp
#

@fallow sable I am using server actions to increment the view on the row on supabase? What are your security suggestions?

fallow sableBOT
#

Let me check the knowledge base for you again. Give me one moment! :books:

#

When using Server Actions in Next.js to increment a view count on a Supabase row, here are the key security suggestions based on the official documentation:

  1. Authenticate and Authorize the User
    Even for simple actions like incrementing a view, you should verify the user's identity if the view should only be counted for authenticated users, or if you want to prevent abuse (e.g., bots or repeated views from the same user). Always check the user's session or credentials before performing the mutation.
    How to implement authentication in Next.js > Authorization

  2. Validate Input
    Never trust incoming data from the client. If your Server Action receives any parameters (e.g., a post ID), validate and sanitize them before using them in your Supabase query. This helps prevent injection attacks and accidental data corruption.
    How to think about data security in Next.js > Mutating Data

  3. Avoid Side Effects During Rendering
    Ensure that the increment logic is only triggered by a Server Action (e.g., via a POST request or form submission), not during the render phase of your component.
    Avoiding side-effects during rendering

  4. Protect Against CSRF
    Server Actions in Next.js are protected against most CSRF attacks by only allowing POST requests and checking the Origin and Host headers. If your app is behind a proxy or uses multiple domains, configure serverActions.allowedOrigins to specify trusted origins.
    Allowed origins (advanced)

#
  1. Rate Limiting
    Consider implementing rate limiting to prevent abuse, such as bots rapidly incrementing the view count.
    Backend for frontend: Security

  2. Remove Sensitive Data from Responses
    Only return the necessary data to the client after incrementing the view. Do not expose sensitive information from your Supabase row or user session.
    Backend for frontend: Security

By following these practices, you can help ensure your Server Action for incrementing views is secure and robust.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: