Skip to main content

🗂️PortSwigger Lab Writeup: SQL Injection with Filter Bypass via XML Encoding

PortSwigger lab description page for SQL Injection – XML Enocoding


🎯 Objective

The objective of this lab is to exploit a SQL injection vulnerability in a web application where the application executes a SQL query with user-supplied input from XML in an unsafe way to fetch stock of products and our goal is to extract the administrator password from the table users and log in as administrator.

  • Lab URL: https://portswigger.net/web-security/sql-injection/lab-sql-injection-with-filter-bypass-via-xml-encoding
  • Category: SQL Injection
  • Difficulty: Practitioner

💉 Payloads Used

1. For confirming SQL injection

  • Payload 1 - ✅
1 or 1=1

2. For determining no of columns

  • Payload 2 - ✅
1 UNION SELECT null

3. For confirming user table

  • Payload 3 - ✅
1 UNION SELECT 'a' FROM users

4. For extracting usernames and passwords

  • Payload 4 - ✅
1 UNION SELECT username||'~'||password FROM users

🧪 Exploitation Steps

🕵️Step 1: Observe the Website

  • Open the lab URL in your browser and explore its functionality. SQLi lab instance showing vulnerable shopping site
    Login page of the vulnerable web application in PortSwigger lab
    PortSwigger shopping website stock check page
  • At first glance, the website seems to be a shopping website with an option to see the available stock of a product and also there is a login page. In the lab description, it is mentioned that the vulnerability is in the stock check feature.

🔍Step 2: Find the Vulnerable Endpoint

  • Open the BurpSuite and send a request containing the XML data to Repeater Tab by Ctrl + R BurpSuite Repeater request testing XML input for SQL Injection vulnerability

  • In the Repeater tab, we will first verify the endpoint for SQLi by using a payload - 1 or 1=1 403 Forbidden WAF block response during SQL Injection attempt

  • Hence, after sending this payload, we received a 403 Forbidden response saying that Attack detected which means our payload is getting blocked by WAF.

    info
    • When testing SQL Injection through XML input, many applications block special characters like ', ", <, > or -- using WAF rules, which often results in a 403 Forbidden error.
    • To bypass such filters, BurpSuite’s Hackvertor extension provides the dec_entities encoder. This encoding converts special characters into their decimal HTML entity representations (for example, ' becomes &#39;, " becomes &#34;, < becomes &#60;).
    • While a WAF may only check for raw characters, it often ignores encoded versions. On the backend, however, XML or SQL parsers automatically decode these entities back into their original characters before processing. This means that even though the payload looks harmless in transit, it executes as intended once decoded by the server.
    • For example, <username>admin&#39;</username> bypasses a filter that blocks <username>admin'</username>, yet still delivers the injection. In short, dec_entities is used to obfuscate payloads, bypass naive WAF filtering, and still achieve code execution on the backend.
  • Therefore, encode the payload using Hackvertor to dec_entities and then send it. BurpSuite Hackvertor encoding payload with dec_entities to bypass WAF
    SQL Injection payload successfully executed after XML encoding bypass

  • Hence, this encoded payload worked and returned us all the records confirming the vulnerable endpoint for SQLi.

📊Step 3: Determine the columns

  • Based on my initial observation of the website, it seems that the application is returning one a single column, but still we will verify the the no of columns by using payload - 1 UNION SELECT null Union-based SQL Injection payload confirming single column in query
  • Hence, it is confirmed that the application is returning a single column.

🧾Step 4: Confirm the details

  • Before we directly extract the password, we should verify that if users table exists or not.
  • We will use the payload - 1 UNION SELECT 'a' FROM users for confirming that users table exists or not. SQL Injection payload confirming existence of users table
  • Hence, the payload executed successfully confirming the presence of users table in database.

🔓Step 5: Retrieve the Credentials

  • Now, we will retrieve the credentials of administrator by using a payload - 1 UNION SELECT username||'~'||password FROM users SQL Injection payload retrieving administrator username and password
  • Hence, we successfully got the record of administrator with password.

🧑‍💼Step 6: Log in as Administrator

  • Finally, open the login page and write the credentials of administrator extracted to log in. Login page with administrator credentials entered after successful password extraction
  • And💥Booom!, We got the access of Admin account on the website. Administrator account dashboard after successful login
  • And Finally, the Lab is solved.

🧠 Conclusion

  • In this lab, we exploited a SQL Injection vulnerability inside an XML input where the application directly concatenated user-supplied data into SQL queries without proper sanitization.
  • The presence of a WAF initially blocked our payloads, but we bypassed it using Hackvertor’s dec_entities encoding, which allowed the queries to execute successfully on the backend.
  • By testing different payloads, we were able to:
    • Confirm the vulnerability by bypassing filters.
    • Identified that the query returned a single column.
    • Verified the presence of the users table.
    • Extracted the administrator’s credentials.
    • Logged in successfully as administrator, gaining full control of the account.
  • This lab highlights how simple encoding tricks can bypass weak WAF rules, and why all user input, including XML data, must be strictly validated and parameterized to prevent SQL injection attacks.