JSON, HTML, and SQL escaping: three contexts, three different jobs
Pick the target context — a JSON string, HTML entities, or a SQL literal — paste the text, and press Escape. Press Unescape to go back. JSON mode returns the contents of a string, without the surrounding double quotes.
When escaping is genuinely needed
You are hand-writing a JSON request body and need to drop user input into a single string value. JSON mode returns exactly what belongs between the quotes: backslashes, double quotes, newlines, and tabs are already handled, so you can replace the placeholder directly.
You are unravelling layered escaping: a log or API field shows text like ", so unescape it once in HTML mode. If " remains, it was escaped at least twice; keep unescaping until it reads normally.
You are building a SQL literal by hand to inspect data, and you need the statement not to fail on a syntax error. That is a debugging convenience, not a pattern for application code.
- Put user input into a JSON string value by hand
- Work out how many layers of HTML escaping a value has
- Build a SQL literal for debugging
- Escape text before embedding it in a config or template
How to get it right
JSON mode handles a single string value and does not validate a document. It will not pair braces or check commas; run the payload through the JSON formatter when you need validation.
Unescaping parses the entire input as one JSON string, so an unescaped quote inside it is an error rather than a partial result. Do not use it to guess what a truncated sequence meant.
When the result goes inside a <script> block in HTML, JSON escaping alone is not enough: </script> and U+2028/U+2029 must also be handled, or the script closes early or fails to parse.
HTML mode replaces five characters — &, <, >, the double quote, and the apostrophe — which keeps text from being parsed as markup but is not XSS protection. on* event attributes, javascript: URLs, and unquoted attributes pass straight through. Sanitising user-submitted HTML requires a whitelist sanitizer such as DOMPurify, not a hand-written regex.
SQL mode doubles single quotes, the standard way to quote a literal. MySQL still treats backslash as an escape character by default, so a backslash before a quote can still break out; numeric positions, ORDER BY column names, and LIKE wildcards are entirely outside its protection.
Escaping is not idempotent. The first pass turns & into &, and the second turns the & inside & into &amp;. If you see a literal & or &amp; on a page, the data carries one more layer of escaping than the rendering expects. Escape exactly once, at the moment you write into the target context.
- JSON mode handles a single string value, not a whole document
- Inside <script>, also handle </script>, U+2028, and U+2029
- HTML mode covers five characters and is not XSS protection
- SQL mode only doubles quotes and does not stop injection
Alternatives and limits
For JSON, use the language's serializer. JSON.stringify handles escaping correctly and processes a whole object at once, so there is no hand-built string to get wrong.
For HTML, rely on your template engine's automatic escaping or the standard library's html.escape. Sanitise rich text with a whitelist library such as DOMPurify rather than writing regex.
For SQL, use parameterised queries or prepared statements (? or $1), passing values as data instead of concatenating them. That is the only approach that also covers numbers, identifiers, and wildcards; escaping is a fallback at best.
The limits here are explicit: JSON mode handles one string value, HTML mode covers five characters, and SQL mode only doubles single quotes, which does not protect MySQL backslash mode or numeric positions.
- JSON → JSON.stringify
- HTML → template auto-escaping or DOMPurify
- SQL → parameterised queries
- Escape once; never stack passes
FAQ
Does SQL escaping prevent SQL injection?
Not on its own. SQL mode doubles single quotes, which is how standard SQL quotes a literal. MySQL still treats backslash as an escape character by default, so a backslash-quote sequence can still break out, wide-character encodings have historically introduced their own bypasses, and numeric parameters, ORDER BY column names, and LIKE wildcards are not addressed by quoting at all. Use parameterised queries or prepared statements in application code; treat escaping as a debugging convenience.
Why is there no surrounding double quote in the JSON output?
Because the tool returns the contents of the string, ready to drop between an existing pair of quotes. Add the outer quotes yourself when you need a complete JSON literal. When unescaping, the whole input is parsed as one JSON string, so an unescaped quote is an error rather than a partial result.
Escaping twice turned & into &amp;. Is that a bug?
No. Escaping is not idempotent: the first pass turns & into &, and the second escapes the & inside & again. That is how a page ends up showing & or &amp; literally — one more layer of escaping than the output expects. Escape once, at the point where you write into the target context, and when you receive already-escaped data, work out how many layers it has before unescaping.
Related tool:Text Escape