Hostile Test Inputs
Test forms, parsers and imports with tricky strings. Choose the cases and export them for your tests.
Search 158 hostile test strings for forms, APIs, imports and file names, each with what it tests, and copy them as JSON, CSV, JavaScript or Python.
129 strings ready to copy. Data only, no active payloads.
Every string here is data that a system should store and show unchanged. Injection, formula and path payloads are hidden until you include them.
The list is built into the page. Searching, filtering and copying happen in your browser.
Nothing is sent or stored. No server request is made for any input.
Copy the list
Strings
(empty string)Is an empty value refused, stored as nothing or stored as the text "null"?
'An unbalanced quote that breaks naive string building.
"The same for double quotes and JSON.
`Shell and template-literal delimiter.
\An escape character with nothing to escape.
\\Is a backslash stored once, twice or not at all?
%A URL escape that is not followed by two hex digits, and a SQL wildcard.
&Is an HTML entity shown as typed, decoded, or decoded twice?
<>Markup with nothing in it.
{}An empty JSON object, and a template placeholder start.
[]An empty JSON array.
""Two quote characters, which some CSV and JSON handling reads as empty.
One space: blank to a person, not empty to a program.
Several spaces: does a "required" check count them as a value?
A tab: blank, and a column separator in TSV.
A line break in a single-line field.
⟦CR⟧A Windows line break.
leading spaceIs the value trimmed, or does it become a different record?
trailing spaceLooks the same as the trimmed value on screen.
line one line twoA newline inside a value: breaks CSV rows, log lines and headers.
non⟦U+00A0⟧breakingA no-break space: trim() and split(" ") treat it differently from a space.
⟦U+3000⟧A full-width space; blank, and not removed by a plain ASCII trim.
line⟦U+2028⟧separatorA line break that JSON, regexes and many editors do not count as one.
ad⟦U+200B⟧minLooks like "admin" and compares unequal. Duplicate-account and allow-list checks miss it.
⟦U+200B⟧Looks empty, passes a "not empty" check.
a⟦U+200D⟧bInvisible joiner between two letters.
⟦U+FEFF⟧valueA byte order mark at the start, as left by some editors and exports.
⟦U+3164⟧Renders blank but is a letter, so "must not be blank" checks accept it.
⟦U+2800⟧A blank-looking symbol that is not whitespace.
invoice⟦U+202E⟧txt.exeThe right-to-left override reverses what follows it, so a file named "invoice" + override + "txt.exe" is shown as "invoiceexe.txt" while it really ends in .exe.
مرحبا بالعالمRight-to-left text: alignment, cursor movement and truncation.
abc אבג 123Mixed directions in one line; digits and punctuation reorder.
pаypalThe "a" is Cyrillic. Looks identical to "paypal" and is a different string.
ΑppleThe first letter is Greek capital alpha.
caféThe "é" is "e" plus a combining accent: 5 code points that look like 4 characters, unequal to the composed form.
caféThe composed form of the same word. Store both and compare.
ÅAngstrom sign, which normalizes to a different character (Å) and so changes under NFC.
ffiThe "ffi" ligature as one character: length 1, uppercases to "FFI" (length 3), and NFKC turns it into three.
⟦U+FF21⟧⟦U+FF22⟧⟦U+FF23⟧⟦U+FF11⟧⟦U+FF12⟧⟦U+FF13⟧Fullwidth letters and digits: look like ASCII, compare unequal, and NFKC makes them ASCII.
Z͑ͫ̓ͪ̂ͫ̽⟦U+034F⟧̴̙̤̞͉͚à́̂̃̄̅̆̇l̀́̂̃̄̅̆̇g̀́̂̃̄̅̆̇ò́̂̃̄̅̆̇Stacked combining marks that spill out of the line.
😀One character, two UTF-16 units, four UTF-8 bytes.
👨👩👧👦One visible character made of seven code points; cut in the middle, it falls apart into four people.
🏳️🌈A flag built from a flag, a variation selector, a joiner and a rainbow.
👍🏽An emoji with a modifier: two code points, one character.
⟦U+D83D⟧Half of a surrogate pair. Not valid Unicode: JSON and UTF-8 encoders replace or reject it.
⟦U+10FFFF⟧The last valid code point, a noncharacter.
tag⟦U+E0041⟧⟦U+E0042⟧Invisible tag characters that can smuggle hidden text.
before⟦U+0000⟧afterA NUL byte inside a value: ends the string in C and some databases.
⟦U+FFFD⟧The replacement character, as left by an earlier decoding error.
İstanbul ısıDotted capital İ and dotless ı: case conversion depends on locale.
StraßeUppercases to "STRASSE": a different length.
ΟΔΟΣLowercases to a word ending in the final sigma "ς", not "σ".
é́́́́́́́́́́́́́́́́́́́́́́́́́́́́́́́́́́́́́́́Forty accents on one letter.
caféMojibake: UTF-8 text that was read as Windows-1252. Seen in imports and old exports.
“quotedâ€⟦U+009D⟧The same damage on curly quotes.
caféDamaged twice.
© 😀Numeric character references in a field that is not HTML.
%E2%9C%93%20okIs already-encoded input decoded, encoded again, or kept?
%c0%afAn overlong UTF-8 encoding of "/" that filters have missed.
dGVzdA==Looks like Base64; does anything decode it on its own?
O'BrienAn apostrophe in a real surname: breaks naive SQL and quote handling.
NullA real surname that systems turn into a missing value.
Smith-JonesA hyphenated family name.
NgA two-letter name, and "X" alone is a legal given name in places.
SukarnoOne name only: there is no first and last.
WolfeschlegelsteinhausenbergerdorffA long real surname.
李小龍No spaces, three characters, 9 UTF-8 bytes.
Nguyễn Thị Hồng NhungStacked diacritics in Vietnamese; very often stored decomposed.
Mary Jo van der BergSeveral spaces and particles.
Bruce Wayne 3rdA digit in a name field.
0Zero as text: false in some languages, and a valid value.
-0Negative zero.
0.30000000000000004The result of 0.1 + 0.2 in binary floating point.
2147483648One more than the largest signed 32-bit integer.
-2147483649One less than the smallest signed 32-bit integer.
4294967296One more than the largest unsigned 32-bit integer.
9007199254740993Not representable as a double: becomes 9007199254740992.
9223372036854775808One more than the largest signed 64-bit integer.
1e309Overflows a double to Infinity.
NaNNot a number, written as text.
InfinityParsed as a number by some languages.
0x1FParsed as a number by some parsers and not by others.
010Eight or ten? A leading zero changes the meaning in some parsers.
1,000.50Comma thousands separator.
1.000,50The same amount in many European locales.
١٢٣Arabic-Indic digits: \d matches them in some regex engines and parseInt rejects them.
⟦U+FF11⟧⟦U+FF12⟧⟦U+FF13⟧Fullwidth digits.
nullThe word, not the value.
undefinedWhat JavaScript prints for a missing value.
NoneWhat Python prints for a missing value.
trueA boolean written as text.
[object Object]What an object looks like after bad string conversion.
nilWhat Ruby and Go print for a missing value.
\NThe text-export marker for NULL in MySQL.
2024-02-29Valid only in leap years.
2023-02-29Not a date; some parsers roll it to 1 March.
0000-00-00The "zero date" some databases accept and others reject.
1970-01-01T00:00:00ZThe Unix epoch: often treated as "no date".
2038-01-19T03:14:08ZOne second past the signed 32-bit time limit.
2016-12-31T23:59:60ZA leap second; many parsers refuse it.
9999-12-31T23:59:59ZThe last second many systems can store.
03/04/2025March 4th or April 3rd?
2025-03-09T02:30:00A local time that does not exist in US time zones.
first.last+tag@example.comA valid address that many forms reject.
"first last"@example.comA valid address with a space in it.
user@localhostValid in mail systems, refused by many validators.
user@exämple.comAn internationalized domain name.
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@example.comThe longest allowed local part (64 characters).
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@example.comOne over the local part limit.
https://user:pass@example.com/Credentials in a URL.
http://[::1]:8080/An IPv6 literal host.
#sectionA relative reference.
https://例え.テスト/パス?q=値Non-ASCII host, path and query.
+1 (555) 010-0100 ext. 7Punctuation, a country code and an extension.
00000000-0000-0000-0000-000000000000The nil UUID: valid, and often treated as "unset".
123E4567-E89B-12D3-A456-426614174000Uppercase: equal to the lowercase form, unequal as text.
192.168.001.001Decimal or octal? Parsers disagree.
127.1A shortened loopback address that parsers and browsers accept.
a,"b",cCommas and quotes inside a value; exports must quote and double them.
%_LIKE wildcards in a search box.
invoice.pdf.exeA file name that looks like a PDF.
CONA reserved device name on Windows.
NUL.txtReserved on Windows even with an extension.
COM1Another reserved name on Windows.
report.Windows removes the trailing dot, so this collides with "report".
.htaccessA hidden configuration file name.
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff.txt259 characters, over the 255-byte limit of most file systems.
README.mdCollides with "readme.md" on case-insensitive file systems.
résumé 日本語 😀.pdfNon-ASCII file name: headers, ZIP entries and paths encode it differently.
How it works
The list is built into the page: 158 strings in eleven groups, from empty values and whitespace to invisible Unicode, encoding damage, real names that break validation rules, numbers and keywords written as text, dates, emails and URLs, spreadsheet formulas, injection and paths. Each string says what it tests. Search matches the name, the reason and the value, including code points such as U+200B. Copy one string, or copy and download the filtered list as JSON, JavaScript, Python, CSV or one value per line. JSON, JavaScript and Python exports escape invisible characters. CSV preserves values with CSV quoting, and one-per-line export keeps raw values.
The full method, every rule and worked examples are on docs.tamperbox.dev.
Limits and interpretation
Active payloads (injection, spreadsheet formulas and path traversal) are hidden until you include them. They are built to be acted on if they reach a parser, interpreter or file system, so use them only against systems you own or are allowed to test. None of them is malware and none needs a network. The list is a starting set, not a complete security test: a value that is stored and shown unchanged has passed, and anything else is worth a closer look. The one-per-line format cannot hold values that contain line breaks; use JSON or CSV for those. Nothing is stored.
Frequently asked questions
What is a naughty string?
A value that is valid input from a person or another system but that software often mishandles: an apostrophe in a surname, an emoji that is two units long in JavaScript, a zero width space that makes two names look the same, or a cell that a spreadsheet runs as a formula.
Is it safe to paste these into a staging system?
The default list is data only and should be stored and shown unchanged. Active payloads are off until you include them, because they are designed to trigger behaviour in systems that mishandle them. Use those only where you are allowed to test.
How is this different from the Big List of Naughty Strings?
The idea is the same. This set is smaller, every string carries a reason, active payloads are separated from plain data, and the list can be filtered and exported with invisible characters escaped.
References
OWASP Web Security Testing Guide · OWASP: CSV Injection · Unicode Technical Standard #39: Unicode Security Mechanisms · RFC 5321: Simple Mail Transfer Protocol, section 4.5.3.1 · Microsoft: Naming files, paths, and namespaces.
Are you an AI agent? You are in the right place.
This page and every tool are available as plain text with their methods and limits, and the same checks run over MCP.