Magic link

    What is a magic link?

    SHORT ANSWER

    A magic link is a one-time login link sent to a user's email address. They click it and they're logged in, with no password to remember. It's safe when the link is random, expires quickly and works only once.

    Also called: Passwordless email login

    ON THIS PAGE

    What it means

    Instead of checking a password, the app proves the person has access to the inbox. This removes weak and reused passwords from the picture entirely.

    The risk moves to the link itself. A link that is easy to guess, lives for days, or can be reused is as weak as a bad password.

    Why it matters for vibe-coded apps

    Magic links are popular in AI-built apps because they're quick to add. The danger is building your own version instead of using your login provider's, and getting the details wrong.

    IF THIS IS WRONG IN YOUR APP
    • A guessable or reusable link lets someone log in as another user.
    • Links that never expire can be found later in old emails or browser history.
    • Without a limit on requests, someone can flood a user's inbox.

    Example

    A homemade magic link.

    ✕ RISKYThe link contains the user, not a secret
    // link: https://app.com/login?user=42
    app.get("/login", (req, res) => {
      req.session.userId = req.query.user; // anyone can log in as anyone
    });
    ✓ SAFERA random, single-use link from your auth provider
    // Supabase sends a random one-time link that expires
    await supabase.auth.signInWithOtp({
      email,
      options: { emailRedirectTo: "https://app.com/auth/callback" },
    });

    Use your login provider's built-in magic link feature rather than building your own.

    How to check if your app has this problem

    1. 1Request a link, then check it contains a long random code and not something readable such as a user ID.
    2. 2Click the same link twice, and wait past its expiry. Both should fail.

    The quicker way: LetMeCheck tests for this automatically, from the outside, the way an attacker would.

    Run a free scan →

    How to fix it

    1. 1Use your auth provider's built-in email login.
    2. 2Make links expire in 15 minutes or less and work once.
    3. 3Rate limit how many links one email can request.
    4. 4Show the same message whether or not the email has an account.
    FIX PROMPT · PASTE INTO YOUR AI TOOL

    Replace my custom email login with Supabase signInWithOtp magic links. Links must be single-use and expire within 15 minutes, requests must be rate limited per email, and the screen must say the same thing whether or not the account exists.

    Check if your app has this problem

    Paste your website and we'll check for magic link issues and other common issues in AI-built apps. Free, about a minute, and nothing on your site is changed.

    Last updated