SQLiDetector: error-based SQL injection triage on a URL list
Simple python script supported with BurpBouty profile that helps you to detect SQL injection "Error based" by sending multiple requests with 14 payloads and checking for 152 regex patterns for different databases.
At a glance
- What is it?
- SQLiDetector is a small Python script that sends fourteen quote-style payloads to every parameter in a list of URLs and matches the responses against 152 database error regexes. It is a triage aid for pentesters and bug bounty hunters, not a general SQL injection scanner.
- Who is it for?
- Adopt SQLiDetector when you already have a filtered list of parameterized URLs and want a quick error-based triage pass, or when you work inside Burp and want the same payloads injected into parameter names, values, headers and paths. Do not rely on it as a complete SQL injection assessment, since it only reports error-based behaviour and will miss blind and time-based cases.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 19 days ago.
- What is it written in?
- Mainly Clojure, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What SQLiDetector actually checks: database errors, not injection
SQLiDetector is a Python script for finding error based SQL injection. Its name and topic suggest a general SQL injection scanner, but the scope is narrower. It sends a fixed set of fourteen payloads to each parameter and looks for a database error in the response, using 152 regular expressions covering different database products.
The regex list is borrowed rather than written for this project. The documentation points at the sqlmap project's data/xml/errors.xml as the source of the error patterns.
The payloads themselves are variations on quote characters appended to a marker value:
'123
''123
`123
")123
"))123
`)123
`))123
'))123
')123"123
[]123
""123
'"123
"'123
\123Each one tries to break out of a quoted context in a different way, so a database that returns a syntax error for one of them surfaces its product and dialect in the response body. If a response matches one of the 152 patterns, the tool considers the URL vulnerable. The repository is written by Eslam Akl and Khaled Nassar, and the version banner in the README reads 1.0.0.
What the tool does not do is extract data, manipulate boolean conditions or measure timing. It is a detector for one error-based signal, which narrows both its usefulness and its false positive profile.
One request per parameter, and one output file per worker
The testing logic is straightforward. Take a URL with two parameters such as https://example.com?file=aykalam&username=eslam3kl and derive two candidate vulnerable URLs, one per parameter position:
https://example.com?file=123'&username=eslam3kl
https://example.com?file=aykalam&username=123'For each candidate the script sends a request, checks whether one of the error patterns matches, and writes any vulnerable link to a separate file for each process. That last detail matters when you read the results: findings are split across per-process output files rather than collected into one report, so a run with many workers leaves you with several files to merge.
The BurpBounty module applies the same payloads in more places than the script does. The bundled profile injects at the parameter name, the parameter value, headers and paths, and the documentation argues that this is what makes it useful for POST requests that the Python script cannot reach. In practice the script works on GET URLs read from a file, and anything requiring a request body, a specific header set or a session cookie is better handled from the proxy.
Both routes share the payload set and the error patterns, so the two are complementary rather than competing.
Running the script: install, then feed it a URL file
The project documents a two step setup. Dependencies come from requirements.txt, which pins rich 12.5.1, exurl 1.2.1 and requests 2.22.0:
~/eslam3kl/SQLiDetector# pip3 install -r requirements.txt The input is a plain text file of URLs, one per line, and the documented format is a URL with query parameters:
https://aykalam.com?x=test&y=fortest
http://test.com?parameter=ayhagaThe tool's own help output shows the full flag set:
usage: sqlidetector.py [-h] -f FILE [-w WORKERS] [-p PROXY] [-t TIMEOUT] [-o OUTPUT]
A simple tool to detect SQL errors
optional arguments:
-h, --help show this help message and exit]
-f FILE, --file FILE [File of the urls]
-w WORKERS, --workers [WORKERS Number of threads]
-p PROXY, --proxy [PROXY Proxy host]
-t TIMEOUT, --timeout [TIMEOUT Connection timeout]
-o OUTPUT, --output [OUTPUT [Output file]Only the file flag is required. Threads, proxy, timeout and output path are all optional, and a working invocation looks like this:
# cat urls.txt
http://testphp.vulnweb.com/artists.php?artist=1# python3 sqlidetector.py -f urls.txt -w 50 -o output.txt -t 10 Two details to expect. The help text shows a slightly malformed bracket on the output option, which is a cosmetic sign that the argument parsing was hand written. And the request count grows quickly: fourteen payloads times two positions per parameter times every URL in the file, which is why the workers and timeout flags exist.
The URL list is the real work, and the README spells out the pipeline
The documentation is unusually honest that the script is the last step of a longer chain. The listed workflow starts with a subdomain grabber, passes the collected subdomains to httpx or httprobe to keep only live hosts, gathers wayback URLs with tools such as waybackurls, gau or gauplus, filters them with URO, and finally greps for links that contain parameters, using Grep or the GF tool.
Only after that does the URL file reach SQLiDetector.
This matters for expectations. The script does no crawling and no subdomain enumeration, so it finds nothing on its own. The quality of the results is bounded by the filtering you did beforehand, and the parameter-only grep is the step that decides how much noise the tool has to sort through.
The documentation also notes that the BurpBounty profile was built to cover the cases the file based script cannot, which is an honest framing of the split between the two modes: bulk triage over a list you already prepared, and manual injection from the proxy for anything that needs a request body.
The Docker image exists, but the entrypoint is the help flag
The repository includes a Dockerfile built on python:3.10-slim. It copies the source in, installs the requirements with pip install --no-cache-dir -r requirements.txt, and sets the entrypoint to the script itself:
FROM python:3.10-slim
WORKDIR /sqlidecetor
COPY . .
RUN pip install --no-cache-dir -r requirements.txt
ENTRYPOINT ["python3", "sqlidetector.py"]
CMD ["-h"]The default command is the help flag, so a bare docker run prints usage rather than scanning anything. To scan, you need to override the command with your own arguments and mount a URL file into the container.
One small thing worth noticing: the work directory is spelled /sqlidecetor, with the letters transposed. That is harmless inside the container, but it means a path you hard code in a wrapper script has to match the typo exactly. The image also carries no volume or port configuration, since the tool only makes outbound HTTP requests to the URLs you give it.
The repository layout matches the script: sqlidetector.py at the root, a core directory, a txt directory, the BurpBounty profile file ErrorBased SQL Injection.bb, and urls-fortesting.txt for a quick trial.
Limits of an error-only detector, and how to read its output
The clearest limitation is that error based detection is one of several SQL injection classes. A target that swallows database errors, returns a generic page, or stores its data without surfacing driver messages will not produce a match no matter how injectable it is. Blind and time based injection leave no error to match at all, so those cases need a different tool.
The second limitation is the reverse of the first. A page that echoes user input inside a message, a PHP notice that happens to contain a database word, or a stack trace from an unrelated service can match one of the 152 patterns by coincidence. Every hit needs a manual look at the actual response before it is reported.
The third is scope. The script consumes a URL list and does not attempt authentication, crawling or parameter discovery, so a target behind a login or a complex POST flow is out of reach for the script mode and belongs to the BurpBounty profile route.
On maintenance, the last push to the repository was on 2026-10-04 and the project has no GitHub releases, so there is no version history to pin against beyond the 1.0.0 banner in the README. The licence is listed as unknown and the repository has no LICENSE file, which is a real consideration if you plan to use the code in a commercial engagement rather than as a personal tool.
Editorial conclusion
Adopt SQLiDetector when you already have a filtered list of parameterized URLs and want a quick error-based triage pass, or when you work inside Burp and want the same payloads injected into parameter names, values, headers and paths. Do not rely on it as a complete SQL injection assessment, since it only reports error-based behaviour and will miss blind and time-based cases. Before trusting the output, confirm that each hit reflects a database error rather than a coincidental string match, and note that the repository has no tagged releases, so you are pinning an unpinned script.
Frequently asked questions
What payloads does SQLiDetector send and how does it decide a URL is vulnerable?
It sends 14 quote-style payloads per parameter position and checks the response against 152 error regular expressions taken from the sqlmap project's data/xml/errors.xml. A match means the response contains a database error signature.
How do I run SQLiDetector against a list of URLs?
Install the dependencies with pip3 install -r requirements.txt, put one parameterized URL per line in a text file, then run python3 sqlidetector.py -f urls.txt. Threads, proxy, timeout and output path are optional flags, for example python3 sqlidetector.py -f urls.txt -w 50 -o output.txt -t 10.
Does SQLiDetector find blind or time based SQL injection?
No. The tool matches database error messages in responses, so it only detects error based SQL injection. It extracts no data and performs no boolean or timing based tests, so injectable targets that do not surface driver errors will be missed.
What is the BurpBounty profile in SQLiDetector for?
It injects the same payloads in more positions than the script, including the parameter name, parameter value, headers and paths. The documentation presents it as the way to cover POST requests and cases the Python script cannot test.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/eslam3kl-sqlidetector)Was this useful?