Wiz Research Discovers One in Five Organizations Exposed to Systemic Risks in Vibe-Coded Applications - Here's How to Secure Them

New research reveals four common security risks systematically affecting vibe-coded applications - with remediation strategies curated together with Lovable.

The LLM revolution has profoundly transformed code generation, giving rise to "vibe coding," where natural language prompts replace traditional programming. This paradigm shift empowers a new generation of builders (many with little to no technical background) to create and deploy fully functional applications with unprecedented ease.

Pioneering platforms like Lovable are at the forefront of this movement. They have enabled the creation of millions of applications, from simple personal tools to enterprise-grade solutions. Organizations now rely on these platforms to build internal chatbots, create complex automations, and, critically, entrust them with sensitive corporate data.

As part of our mission to identify emerging cloud and AI risks, Wiz Research investigated the security posture of applications generated by these vibe-coding platforms. Our findings were significant; we discovered a pattern of common, high-impact misconfigurations and found that 1 in 5 organizations build on these platforms, inadvertently exposing themselves to risk.

The good news is that these issues are easily preventable. This post details the most common pitfalls we found and provides clear, actionable guidance to help you secure your vibe-coded applications.

1. Authentication Logic Living Entirely in the Browser

A common flaw we discovered is applications that handle the entire authentication process—password entry and validation—on the client side, without contacting any backend server. In these cases, the browser downloads all the code meant to ‘protect’ the app, meaning the password is embedded directly in the JavaScript files and visible to anyone who inspects them.

Here are two practical, anonymized examples of this flaw that we saw in the wild:

Example A: Hardcoded String as the Password

// Anonymized example of client-side validation
{
    isAuthenticated: e,
    isLoading: n,
    login: s => s === "welcometoredacted" ? (t(!0),
    localStorage.setItem("app-auth-token", "authenticated"),
    !0) : !1,
    logout: () => {
        t(!1),
        localStorage.removeItem("app-auth-token")
    }
}

What's happening in the code:

The login function checks if the provided password(s) is exactly equal to the string "welcometoredacted". If they match, it sets an authentication flag in LocalStorage. The password is plainly visible to anyone who views the application's source code.

Example B: Password in a Variable

// Anonymized example using a variable for the password 
const pC = "marketingdocs2025" 
const ic = "my-app-auth-secret"; 
function vC({children: e}) 
{ // ... state and effects const o = l => l === pC ? (n(!0), 
localStorage.setItem(ic, "authenticated"), r("password"), !0) : !1 // ... }

What's happening in the code:

The password "marketingdocs2025" is first assigned to a variable pC. The login function then compares the user's input (l) to this variable. While it's not a direct string comparison inside the function, the password variable is defined in the same client-side file, making it just as easy for an attacker to find and use.

These two real-world examples share the same fundamental flaw. They treat the user's browser as a trusted environment for authentication, which it is not. Whether it's a single password as a string, a password stored in a variable, the outcome is identical; the secrets are shipped directly to the client.

Furthermore, both examples rely on setting a simple, predictable flag in LocalStorage (like "authenticated" or "true") to manage the session.

This creates a second, often easier, path for attackers. An attacker doesn't need to bother with the login form at all; they can read the code to see what value is expected in LocalStorage, manually set it using their browser's developer tools, and gain immediate, unauthorized access.

SOLUTION:

Enforce Server-Side Authentication. Ensure that all authentication and authorization decisions are made on a backend server, the client-side application should only send user-provided credentials to the server for validation; it should never contain the logic or data required to validate them itself.

The best way is to enforce server-side authentication with providers such as OAuth or Cognito, and to ensure AI prompts always treat client-side code as publicly exposed.

We have worked together with Lovable to help enforce a global system prompt change to consider client-side secrets embedding a security risk and unwanted act. For further guidance, see Lovable's best practices on Authentication Security.

2. API Keys and Secrets Exposed in Client Side Code

Beyond user credentials, we frequently found other sensitive secrets like third-party API keys and service account credentials hardcoded directly into client-side JavaScript files, which often looks like the following:

const h$ = "sk-proj-FSAFCREDACTEDOVY7EfDD-XIMrVayZub7TakA"; function Pc() { localStorage.removeItem("openai_api_key"), localStorage.setItem("openai_api_key", h$); const t = h$.slice(-4); console.log(`✅ OpenAI key successfully updated and working (ending in ${t})`) }

SOLUTION:

The solution is to proxy all third-party API calls through a secure backend - a role perfectly handled by Supabase Edge Functions in a Lovable application. Store your API Keys and secrets securely in Supabase Secrets, then have your client-side code call your Edge Function, which retrieves the key at runtime and forwards the request to the third-party service. This simple pattern ensures sensitive credentials never reach the browser, eliminating the risk of exposure as we have seen in many cases across vibe-coded applications.

3. Database Tables Wide-Open to the World

Vibe-coding platforms make it easy to connect applications to powerful databases like Supabase, which use Row-Level Security (RLS) to control data access. However, we found that developers often implement overly permissive RLS policies or forget to enable them at all across sensitive tables, leaking confidential and private information.

Example: A vibe-coded enterprise game leaked all of its users’ PII, IP addresses, and more when players submitted personal details

Attackers would look for applications that expose their Anon Supabase key on their Javascript, it looks similar to.

const AR = (e, t, n) => new NR(e,t,n)
    , IR = "https://plomwredacted.supabase.co"
    , MR = "eyJhbGciredactediIsInR5cCI6IkpXVCJ9.redacted.redacted"
    , Bi = AR(IR, MR, {
      auth: {
          storage: localStorage,
          persistSession: !0,
          autoRefreshToken: !0
      }
  })

Now, they need to check the permissions of the Supabase service, list all the tables and probe 1 by 1 if there are any that expose sensitive data. We have made a simple scanner for that which runs with the following methodology:

# Get the OpenAPI schema to discover all tables
curl -X GET "https://YOUR-PROJECT.supabase.co/rest/v1/" \
  -H "apikey: YOUR_API_KEY" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

# Test each table
for table in $tables; do
  echo "=== Testing table: $table ==="

  response=$(curl -s -w "HTTPSTATUS:%{http_code}" \
    "$SUPABASE_URL/rest/v1/$table?limit=5" \
    -H "apikey: $API_KEY" \
    -H "Authorization: Bearer $API_KEY" \
    -H "Content-Type: application/json")

  http_code=$(echo $response | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
  body=$(echo $response | sed -E 's/HTTPSTATUS:[0-9]{3}$//')

  if [ "$http_code" = "200" ]; then
    echo "✅ ACCESSIBLE - Sample data:"
    echo "$body" | jq '.' 2>/dev/null || echo "$body"

# Check for sensitive fields
    sensitive=$(echo "$body" | jq -r 'if length > 0 then .[0] | keys[] else empty end' 2>/dev/null | grep -iE "(email|phone|password|token|secret|ip|address)" || true)
    if [ ! -z "$sensitive" ]; then
      echo "⚠️  SENSITIVE FIELDS DETECTED: $sensitive"
    fi
  else
    echo "❌ Not accessible (HTTP $http_code)"
  fi
  echo
done

SOLUTION:

Adopt a 'Deny-by-Default' Policy for Data Access. When configuring database security rules like RLS, always start with a policy that denies all access. Then, write explicit and rigorously tested rules to grant access only to the necessary data based on the authenticated user's ID or role. Every database query should be forced to pass through these restrictive filters. Lovable provides detailed guidance on preventing data exposure via Supabase RLS.

4. Internal Applications that are Publicly Facing without Authentication

The speed of vibe-coding makes it an ideal choice for building internal tools, admin dashboards, and staging environments. However, we observed many cases where these applications were deployed on the public internet without authentication. This makes them discoverable by attackers who actively scan and fingerprint web applications to identify those built with specific Vibe-Coding platforms.

Using a simple fingerprinting technology, we searched for matches to “lovable.app” and an additional set of identifying strings, which yielded numerous vibe-coded applications that were never intended to be publicly facing. These included:

  1. Mock websites with real data without any authentication enforced

  2. Internal Knowledge bases leaking propriety information

  3. Internal Chatbots trained on sensitive data 

And more…

SOLUTION:

Always enforce authentication for any application handling sensitive data or internal information to ensure data is not public facing. It all starts with visibility. As an organization, you should know all the vibe-coded applications your developers are interacting with. From there, enforce them to be strictly for public information with no sensitive running on them - at least when authentication is not enforced.

Collaborating with Lovable to Drive Change

Identifying security risks is only the first step. To drive meaningful change across the entire Vibe-Coding landscape, Wiz Research actively partners with the leading platforms in this space to promote secure practices.

A prime example of this is our collaboration with the Lovable security team. We shared our research on these common misconfiguration patterns, and in response, they created a comprehensive Security Best Practices Guide on their website.

This guide provides their users with clear, actionable steps to avoid the exact pitfalls detailed in our research, and is a testament to how they take the security of their users seriously. A proactive, collaborative approach is crucial for securing the Vibe-Coding ecosystem at its source by empowering developers to build securely from the start.

How Wiz can Help

For Wiz customers, identifying potentially vulnerable Vibe-Coding applications is straightforward. You can easily view all your publicly facing Lovable applications with the below query in the Wiz portal.

Find your Lovable applications in Wiz

Summary

Vibe-Coding platforms are an essential part of modern software development, enabling organizations to innovate at an unprecedented pace. These platforms, however, create a new shared responsibility paradigm where the security of an application depends heavily on its implementation. One misconfiguration can jeopardize sensitive data and expose the organization to significant risk. In this blog post, we have described four common vibe-coding misconfigurations and provided tips on how to remediate them. These misconfigurations include client-side authentication, hardcoded secrets, insecure data access policies, and the exposure of internal applications. Implementing the best practices above can significantly reduce your organization’s attack surface and secure your applications. We appreciate the collaboration with Lovable, who showed deep commitment to improving their customers’ security as part of this research.

Get Wiz's State of Code Security Report

Continue reading

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management