Question
Why do some Google private JSON responses begin with while (1);?
For example, when toggling a calendar setting in Google Calendar, the response may look like this:
while (1);
[
['u', [
['smsSentFlag', 'false'],
['hideInvitations', 'false'],
['remindOnRespondedEventsOnly', 'true'],
['hideInvitations_remindOnRespondedEventsOnly', 'false_true'],
['Calendar ID stripped for privacy', 'false'],
['smsVerifiedFlag', 'true']
]]
]
It seems like this might be done to stop developers from calling eval() directly on the response, since the response is no longer valid JavaScript data by itself. However, someone could still manually remove the prefix.
I have also seen similar prefixes such as &&&START&&&, and in some cases both while(1); and &&&START&&& together.
What is the purpose of these prefixes, and what problem are they trying to solve?
Short Answer
By the end of this page, you will understand why some web applications prepend strings like while(1); to JSON responses, what JSON hijacking is, why this was historically important in JavaScript applications, and what safer modern alternatives are commonly used today.
Concept
The core idea
Prefixes like while(1); are a defensive trick added before JSON responses so the response is not directly executable as JavaScript.
This was mainly used to reduce the risk of a class of attacks often called JSON hijacking or cross-site script inclusion attacks.
Why this mattered
In older web applications, some endpoints returned sensitive data as raw JSON, often arrays or objects. If that JSON could be loaded in a <script> tag from another site, the browser might execute it as JavaScript in a way that exposed private data.
For example, if an authenticated user visited a malicious site, that site might try to load a private JSON endpoint from another domain:
<script src="https://example.com/private-data"></script>
If the response was valid executable JavaScript, the attacker could sometimes abuse that behavior.
What while(1); does
This prefix makes the response invalid as plain JSON and also useless when treated as a script:
while (1);
[{"secret":"data"}]
If a browser tries to execute that as JavaScript, it gets stuck in an infinite loop before reaching the data. That means the payload cannot be meaningfully consumed through script inclusion.
A legitimate client that expects this format can strip the prefix first, then parse the remaining JSON safely.
Why not just trust developers not to use eval()?
The main goal was not only to discourage eval(). It was to protect against browser behavior and cross-origin attacks, especially in older browsers and older application architectures.
Even if someone can manually remove the prefix, an attacker loading the endpoint through a <script> tag cannot easily do that before execution.
Why other prefixes like &&&START&&& exist
Different applications used different non-JSON prefixes:
while(1);for(;;);)]}',&&&START&&&
All of them serve a similar purpose:
- make the response invalid as raw JSON
- make it non-executable or inconvenient as JavaScript
- require the intended client to explicitly strip the prefix before parsing
Modern context
Today, this is less common because APIs usually rely on stronger protections such as:
- proper
Content-Type: application/json - CORS rules
- CSRF protections
- authentication headers or tokens
SameSitecookies- avoiding sensitive GET JSON endpoints where possible
So the prefix was a practical historical defense, especially for private endpoints used by large JavaScript applications.
Mental Model
Think of the JSON response as a package being shipped.
- A normal JSON response is like a package with the contents immediately visible.
- A prefixed response adds a tamper seal on top.
- The official client knows how to remove the seal first.
- A browser blindly executing it as a script trips over the seal and cannot use the contents directly.
while(1); is an extreme kind of seal: if you try to "run" the package as code, you never get past the first line.
So the prefix is not meant to make the data impossible to read forever. It is meant to stop the browser from accidentally treating private data as executable script in the wrong context.
Syntax and Examples
Basic pattern
A server may return something like this:
while (1);
{"name":"Alice","role":"admin"}
That is not valid JSON because of the extra prefix.
A trusted client can remove the prefix and then parse the rest.
Example in JavaScript
const responseText = 'while (1);{"name":"Alice","role":"admin"}';
const cleaned = responseText.replace(/^while \(1\);/, '');
const data = JSON.parse(cleaned);
console.log(data.name); // Alice
Another common prefix
const responseText = ")]}',\n{"ok":true}";
const cleaned = responseText.replace(/^\)\]\}',\n/, '');
const data = JSON.parse(cleaned);
Important point
Use JSON.parse() after removing the known prefix.
Do not do this:
const data = eval(responseText);
eval() executes code and is unsafe for parsing server responses.
Safer server idea
A modern API would usually just return:
{"name":"Alice","role":"admin"}
and protect the endpoint using proper headers, cookies, tokens, and origin rules rather than relying on a defensive prefix alone.
Step by Step Execution
Example response
while (1);
["red", "green", "blue"]
Client-side processing
const responseText = 'while (1);["red", "green", "blue"]';
const cleaned = responseText.replace(/^while \(1\);/, '');
const colors = JSON.parse(cleaned);
console.log(colors[1]);
Step by step
1. The server sends text
The client receives this exact string:
while (1);["red", "green", "blue"]
2. The prefix is removed
This line removes the anti-execution prefix:
const cleaned = responseText.replace(/^while \(1\);/, '');
Now cleaned becomes:
["red", "green", "blue"]
3. The JSON is parsed
const colors = JSON.parse(cleaned);
Now colors is a real JavaScript array:
["red", "green", "blue"]
4. Normal code can use the data
console.log(colors[1]);
Output:
green
What happens if a browser executes it as a script?
The browser starts with:
while (1);
That creates an infinite loop. The rest is never reached in a useful way. This is exactly why the prefix was used as a defense.
Real World Use Cases
1. Private web app endpoints
Large JavaScript applications such as mail, calendar, and admin dashboards often had internal endpoints returning structured data. Prefixes were used so those endpoints could not be safely included as scripts from another origin.
2. Protecting authenticated GET responses
If a browser automatically sent cookies with a request, a malicious site might try to load a user's private data through a <script> tag. Prefixing the response reduced that risk.
3. Legacy AJAX applications
Before modern browser security features became standard, many applications used custom response formats and defensive prefixes as an extra layer of protection.
4. Internal APIs with custom clients
Some apps controlled both server and client code. That made it practical to add a prefix server-side and remove it client-side before parsing.
5. Defensive parsing conventions
Even today, some systems add a non-JSON prefix like )]}', to ensure the client explicitly recognizes and parses the payload rather than accidentally executing it.
Real Codebase Usage
Common patterns in real projects
Explicit response normalization
Developers often create a small utility that removes known prefixes before parsing:
function parseSafeJson(text) {
const cleaned = text
.replace(/^while \(1\);/, '')
.replace(/^for \(;;\);/, '')
.replace(/^\)\]\}',?\n/, '');
return JSON.parse(cleaned);
}
This keeps the parsing logic in one place.
Guard clauses
A parser may first verify that the payload begins with an expected prefix or valid JSON token:
function parseGoogleStyleResponse(text) {
if (text.startsWith('while (1);')) {
text = text.slice('while (1);'.length);
}
return JSON.parse(text);
}
Validation before parsing
In production code, developers often validate that the cleaned result looks like JSON before parsing:
function looksLikeJson(text) {
return text.trim().startsWith('{') || text.trim().startsWith('[');
}
Error handling
Real code should handle malformed responses gracefully:
function safeParseResponse(text) {
try {
const cleaned = text.replace(/^while \(1\);/, '');
return { ok: true, data: JSON.parse(cleaned) };
} catch (error) {
return { ok: false, error: 'Invalid server response' };
}
}
Why this matters in a real codebase
- keeps parsing logic consistent
- avoids
eval() - makes migrations easier if the server format changes
- centralizes legacy compatibility code
Common Mistakes
1. Treating prefixed JSON as normal JSON
This will fail because the response contains extra characters before the JSON.
Broken code:
const text = 'while (1);{"ok":true}';
JSON.parse(text); // Error
Fix:
const cleaned = text.replace(/^while \(1\);/, '');
JSON.parse(cleaned);
2. Using eval() to parse the response
Broken code:
const data = eval(text);
Why it is wrong:
- executes code instead of parsing data
- unsafe for untrusted input
- unnecessary in modern JavaScript
Fix:
const data = JSON.parse(cleaned);
3. Removing the prefix too loosely
If you do a generic replace, you may accidentally modify valid content later in the string.
Less safe:
text = text.replace('while (1);', '');
Better:
text = text.replace(/^while \(1\);/, '');
The ^ means only remove it from the start.
4. Assuming the prefix is a complete security solution
The prefix is only one defense. It does not replace:
- authentication
- authorization
- CSRF protection
- CORS policy
- secure cookie settings
5. Forgetting that many old endpoints returned arrays
Historically, top-level arrays were especially discussed in JSON hijacking scenarios. Developers sometimes miss the historical context and think the prefix was random formatting rather than a security measure.
Comparisons
Related approaches
| Approach | What it does | Main purpose | Still common? |
|---|---|---|---|
| Raw JSON | Returns plain JSON directly | Simple API responses | Yes |
while(1); prefix | Makes response non-JSON and non-useful as script | Mitigate JSON hijacking | Mostly legacy |
for(;;); prefix | Same idea as while(1); | Mitigate script inclusion abuse | Mostly legacy |
)]}', prefix | Breaks JavaScript parsing and signals custom parsing | XSSI protection | Still seen sometimes |
&&&START&&& prefix | Custom marker before payload | Framing and defensive parsing | Rare, custom |
JSON.parse() vs eval()
| Method | Purpose | Safe for JSON parsing? | Notes |
|---|---|---|---|
JSON.parse() | Parses JSON text | Yes | Preferred approach |
eval() | Executes JavaScript code | No | Dangerous and unnecessary |
Old defense vs modern defense
| Technique | Best use | Limitation |
|---|---|---|
| Prefixing responses | Extra protection for legacy browser behavior | Not enough by itself |
| CORS | Controls which origins can read responses | Does not replace auth |
| CSRF tokens | Protects state-changing requests | Not directly about reading JSON |
SameSite cookies | Restricts cross-site cookie sending | Browser-dependent behavior |
| Auth headers/tokens | Protects private endpoints | Must be implemented correctly |
Cheat Sheet
Quick reference
What is while(1); before JSON?
A defensive prefix added before a JSON payload so the response is not directly executable as JavaScript.
Why was it used?
Mostly to reduce the risk of JSON hijacking or cross-site script inclusion attacks in older web apps.
What should a client do?
- Remove the known prefix
- Parse the remaining text with
JSON.parse()
Example
const cleaned = text.replace(/^while \(1\);/, '');
const data = JSON.parse(cleaned);
Common prefixes
while (1);
for (;;);
)]}',
&&&START&&&
Do not do this
eval(text)
Important rule
A prefix is an extra defense, not a replacement for:
- authentication
- authorization
- CORS
- CSRF protection
- secure cookies
Modern recommendation
Prefer plain JSON with proper web security controls unless you must support a legacy protocol or client.
FAQ
Why does while(1); stop the response from being used as a script?
Because it starts an infinite loop immediately, so the rest of the response is never usefully executed when treated as JavaScript.
Is while(1); valid JSON?
No. It makes the response invalid as raw JSON until the prefix is removed.
Was this mainly about stopping eval()?
Not primarily. It was mainly a defense against browsers loading private JSON endpoints as scripts from another site.
Why could a normal client still use the response?
Because the intended client knows to remove the prefix first and then parse the remaining JSON.
What is JSON hijacking?
It is a class of attacks where a malicious site tries to exploit how browsers handle script loading to access sensitive JSON from another origin.
Why do some services use )]}', instead?
It serves a similar purpose: making the response invalid or non-executable until the client explicitly strips the prefix.
Is this still needed in modern APIs?
Usually not as a primary defense. Modern APIs more commonly rely on CORS, CSRF protection, secure cookies, and token-based authentication.
Should I add while(1); to my own API?
Usually no, unless you are maintaining a legacy client/server contract. For new APIs, plain JSON plus proper security controls is typically better.
Mini Project
Description
Build a small JavaScript parser that accepts server responses containing anti-execution prefixes such as while(1); or )]}', and safely converts them into usable JavaScript data. This mirrors the kind of compatibility code developers write when integrating with legacy or private endpoints.
Goal
Create a function that strips known prefixes and safely parses the remaining JSON using JSON.parse().
Requirements
- Write a function that accepts a response string.
- Remove at least two known protective prefixes if they appear at the start.
- Parse the cleaned text as JSON.
- Return the parsed result.
- Handle invalid input without using
eval().
Keep learning
Related questions
Abort Ajax Requests with jQuery jqXHR.abort()
Learn how to cancel an in-progress jQuery Ajax request with jqXHR.abort(), handle abort status safely, and avoid stale UI updates.
Access the Correct this Inside a JavaScript Callback
Learn why JavaScript this changes in callbacks and how to preserve an object context using bind, arrow functions, and event handler patterns.
Add Key-Value Pairs to JavaScript Objects
Learn how to add key-value pairs to JavaScript objects with dot and bracket notation, dynamic keys, examples, and common mistakes.