Trustwave SpiderLabs Uncovers Ov3r_Stealer Malware Spread via Phishing and Facebook Advertising. Learn More

Trustwave SpiderLabs Uncovers Ov3r_Stealer Malware Spread via Phishing and Facebook Advertising. Learn More

Managed Detection & Response

Eliminate active threats with 24/7 threat detection, investigation, and response.

Co-Managed SOC (SIEM)

Maximize your SIEM investment, stop alert fatigue, and enhance your team with hybrid security operations support.

Advisory & Diagnostics

Advance your cybersecurity program and get expert guidance where you need it most.

Penetration Testing

Test your physical locations and IT infrastructure to shore up weaknesses before exploitation.

Database Security

Prevent unauthorized access and exceed compliance requirements.

Email Security

Stop email threats others miss and secure your organization against the #1 ransomware attack vector.

Digital Forensics & Incident Response

Prepare for the inevitable with 24/7 global breach response in-region and available on-site.

Firewall & Technology Management

Mitigate risk of a cyberattack with 24/7 incident and health monitoring and the latest threat intelligence.

Microsoft Exchange Server Attacks
Stay protected against emerging threats
Rapidly Secure New Environments
Security for rapid response situations
Securing the Cloud
Safely navigate and stay protected
Securing the IoT Landscape
Test, monitor and secure network objects
Why Trustwave
About Us
Awards and Accolades
Trustwave SpiderLabs Team
Trustwave Fusion Security Operations Platform
Trustwave Security Colony
Technology Alliance Partners
Key alliances who align and support our ecosystem of security offerings
Trustwave PartnerOne Program
Join forces with Trustwave to protect against the most advance cybersecurity threats
SpiderLabs Blog

Persistent Cross-Site Scripting, the MSSQL Way


If you save wide Unicode brackets (i.e. <>) into a char or varchar field, MSSQL Server will convert them into HTML brackets (i.e. <>). So, <img src=x onerror=alert('pxss')> will be converted to <img src=x onerror=alert('pxss')> compliments of the backend DB. This will likely help you sneak past server-side filters, WAFs, etc. and execute a persistent Cross-Site Scripting (PXSS) attack. As a bonus, .NET request validation will not detect it.


I still find myself shaking my head each time I come across this one. This is a known issue – I didn’t discover this. It’s not even a new issue, so it seems weird that I would waste my time to document the issue. Again. Truth be told, I’ve written about this internally for SpiderLabs. We all know about it and employ this payload in common attack scenarios and I still cannot think of a single valid reason for MSSQL to both allow and cause it. It can be an insidious little issue too because you thought you were safe…playing by the good guy rules. Here’s my attempt at explaining it. Again.

Background: SQL Server Data Types

The venerable char/varchar datatypes did a fine job of allowing an application to store variable-length data and minimize its storage footprint by only using up space as the text data grew. 20+ years ago, disk space limitations were a common issue, so prudent table design which minimized waste was common sense. The char/varchar datatypes had a limited character set that would handle only ASCII characters which required only a single byte of storage for each character. Nchar/nvarchar, on the other hand, required 2 bytes in order to store Unicode characters. With these factors in mind, developers and DBAs who had no intention of storing non-ASCII characters would make the obvious choice at the time and use varchar since it would consume as little space as possible and expand to its maximum size as needed. While the issue we’re looking at affects both char and varchar, we’ll stick to talking about varchar from here on.

Square Pegs in Round Holes

Fast forward a bunch of years from the 90’s, and now we have bad guys attacking applications, injecting any and every payload they can into HTTP requests. In our case, we’re going to see what happens when Unicode values (2 bytes) are saved in a database column that can only save ASCII values (1 byte). My initial thought would be to expect some sort of database error, but I would be wrong. Let’s take a look at a very unexpected behavior of SQL Server.

SQL Server Mappings – Enter the Freakshow:

The particular oddity that we’ll be looking at is what SQL Server does when you insert Unicode characters into a varchar field. SQL Server will transparently attempt to map & convert Unicode characters into their visually related ASCII characters. This is where things get interesting. The wide “less-than” Unicode character looks similar to the ASCII “less-than” character, however the former is not blocked by request validation while the latter is.

For PoC purposes we can see that the wide less than (%ef%bc%9c) stored as a .NET string is 0xff1c in hex.

PoC Code:

using System;
using System.Web;
using System.Text;
public class Program

  public static void Main(){
  string fromInput = System.Web.HttpUtility.UrlDecode("%ef%bc%9c");
  int intVal = (int)fromInput[0];

  Console.WriteLine("Wide angle bracket from input: {0}", fromInput);
  Console.WriteLine(String.Format("Associated int-to-hex value: {0:X}", intVal));


Wide angle bracket from input: <
Associated int-to-hex value: FF1C

If this hex value is inserted into a SQL table’s varchar column, we’ll see SQL Server convert the wide less-than to a regular less-than due to a homoglyphic transformation – a given character looks like another character and is subsequently converted.


CREATE TABLE UnicodeConvert
 col1 varchar(10) /* cannot handle unicode values */
 ,col2 nvarchar(10) /*can handle unicode values */
INSERT INTO UnicodeConvert VALUES (NCHAR(0xff1c),NCHAR(0xff1c));

select col1 as varcharData, unicode(col1) as varcharCharacterCode, col2 as storedAsUnicode, unicode(col2) as storeAsUnicodeCharacterChode from UnicodeConvert;

Select Statement Output (comments added for clarity):

varcharData: < /* b00$h! that's a valid html bracket*/
varcharCharacterCode: 60
storedAsUnicode: <  /* <-- that bracket will not be useful as HTML */
storeAsUnicodeCharacterChode: 65308

We see %EF%BC%9C will be the open bracket and %EF%BC%9E will be the closing bracket that is not caught by .NET request validation and (if stored in a varchar field) could easily be returned as a proper persistent Cross-Site Scripting payload.

Full payload to test with:

%EF%BC%9Cscript%EF%BC%9Ealert%28%27PXSS%27%29%EF%BC%9C%2Fscript%EF%BC%9E i.e. <script>alert('PXSS')</script>


We have just saved a completely benign set of strings and let the database convert it into a malicious payload!  So why is MSSQL converting Unicode to ASCII? We reached out to Microsoft to give them the opportunity to comment, but have not received a response. I’m guessing that in a kinder, gentler time, this was a helpful feature that they added.  The bracket trick is just one of several transformations that could be useful for attackers. I’ve read other sources that outline using this same technique for bypassing filters and successfully executing SQL injection attacks when the conditions were right. 

So, what should you do? Can filters be applied to look for known malicious Unicode patterns?  Probably, but it's likely that there are also other clever bypasses out there that require some fringy, esoteric DBMS knowledge to execute.  If it were up to me, I’d dump the DDL for my SQL tables and look for char/varchar and change those to nchar/nvarchar respectively.  Knowing that DBAs can be resistant to change for fear of breaking legacy apps, I’d show them this post and let them know that the situation is serious, and it’s been serious for a long time.  So, keep chanting “defense-in-depth”, run your WAF, apply your filters and change those data types. If Microsoft provides feedback on this issue we will update the post accordingly.

Try It Yourself!

Latest SpiderLabs Blogs

Welcome to Adventures in Cybersecurity: The Defender Series

I’m happy to say I’m done chasing Microsoft certifications (AZ104/AZ500/SC100), and as a result, I’ve had the time to put some effort into a blog series that hopefully will entertain and inform you...

Read More

Trustwave SpiderLabs: Insights and Solutions to Defend Educational Institutions Against Cyber Threats

Security teams responsible for defending educational institutions at higher education and primary school levels often find themselves facing harsh lessons from threat actors who exploit the numerous...

Read More

Breakdown of Tycoon Phishing-as-a-Service System

Just weeks after Trustwave SpiderLabs reported on the Greatness phishing-as-a-service (PaaS) framework, SpiderLabs’ Email Security team is tracking another PaaS called Tycoon Group.

Read More