Proving SQLi on a Shared Tenant Database
A public-facing ASP.NET storefront at shop.contoso.com sits behind Cloudflare and a WAF. You find a time-based blind SQL injection in the sort parameter of /api/products?sort=name. The backend is a shared MSSQL instance hosting 14 tenant databases, including contoso and two other clients of the SaaS provider. The RoE says: 'Demonstrate impact; do not extract customer data or modify records.' The WAF blocks requests containing SLEEP, WAITFOR, and stacked queries; a sqlmap run triggers 403 responses after 20 requests. You have four hours of web scope left, and the client's auditor wants 'proof of exploitable SQLi.' A junior tester suggests dumping the users table to 'show real impact.' The application logs every request with full query strings, and the client's IR team reviews those logs daily.
1. How do you prove the blind SQLi without extracting customer data?
Read the worked answer
Use boolean inference and metadata only.
- Send
sort=name' AND 1=1--andsort=name' AND 1=2--and compare the response length or product ordering. A consistent difference proves injection. - Ask only for context:
AND SUBSTRING(DB_NAME(),1,1)='c'--, thenAND SUBSTRING(@@VERSION,1,1)='1'--. This proves I can read server metadata without touching tenant rows. - Avoid SLEEP and WAITFOR, which the WAF blocks anyway. Use case mixing, inline comments
/**/, URL encoding, and alternate whitespace to get past signature rules, but rate-limit to fewer than 20 requests per minute and stop on 403. - Stay in the current database context. Do not query
information_schemaacross other tenants or enumerate their schemas. - Capture request and response pairs, timestamps, and the DB_NAME result.
For the auditor, 'I can alter query logic and read the current database name/version' is sufficient proof of exploitable SQLi. Dumping users would violate the RoE and expose other tenants.
2. sqlmap returned 200 rows of customer PII. What do you do now?
Read the worked answer
Stop immediately. Kill the sqlmap process and do not open, parse, or copy the output. Record the timestamp, payload, target, and that 200 rows were returned, but do not view the contents. Delete local output files and clear any temporary files. Then notify the client contact under the incident-notification clause: testing caused unintended retrieval of customer data, no exfiltration to third parties occurred, and the data was deleted. Preserve my terminal logs and the sqlmap command line, but not the data itself. Recommend that the client review database access logs and the application logs. In the report, describe this as a testing incident and a data-minimization failure, not as a finding, and do not include any PII. The lesson is to set --stop-at or use manual queries; automated defaults are dangerous on shared databases.
3. The auditor wants 'data exfiltration proof.' How do you respond?
Read the worked answer
I would explain that the RoE prohibits extracting customer data, and that exfiltration is not required to prove SQL injection. I can show query-logic control and metadata disclosure, which is the technical root cause. If the auditor needs a data-impact demonstration, I would propose a synthetic table created by the client in a test tenant, with written scope expansion and a defined record set. That gives a controlled exfiltration proof without touching real customer data. If the client will not create that, the Boolean proof plus a risk statement is the deliverable. I would not dump users, not even hashed passwords, because password hashes are still customer data and would create a new breach. The report can state that data access is possible and that the client chose not to authorize extraction.