Open In App

How to Build a SQL Injection Scanner in Python?

Last Updated : 24 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

In general terms, SQLi is the most prevalent and dangerous code insertion technique.  An SQLi attack is meant to send malicious SQL commands to the database server. The most common attack goal is bulk extraction of knowledge. Attackers can dump database tables with many thousands of customer records. Depending on the environment, SQL injection also can be exploited to switch or delete data, execute arbitrary OS commands, or launch denial-of-service (DoS) attacks.

Building SQL Injection Scanner in Python

Using the below approach we will extract the web forms first because SQL injection is carried through user input. Then, we will check whether a web page has SQL errors in it, this will be useful when checking for SQL injection attacks and finally, we will test it on HTML forms.

For this, we will require requests and BeautifulSoup package.

Approach:

  1. Import Modules:
    • Use requests for HTTP requests, BeautifulSoup for parsing HTML, and urljoin to handle relative URLs.
  2. Initialize Session:
    • Create a session with requests.Session() and set a User-Agent header to mimic a real browser.
  3. Extract Forms:
    • Fetch all forms from the page using BeautifulSoup and return a list of form tags.
  4. Extract Form Details:
    • Get form action (submission URL), method (POST/GET), and inputs (name, type, and value).
  5. Check for Vulnerabilities:
    • Search for common SQL error messages in the response (e.g., "quoted string not properly terminated").
  6. Test SQL Injection:
    • For each form, inject special characters ('") into the inputs and submit the form.
    • Check if the response contains SQL errors indicating a vulnerability.
  7. Submit Data & Detect:
    • Use POST or GET to submit the form data and check if it’s vulnerable to SQL injection based on the response errors.
  8. Run Script:
    • Pass the URL as an argument and scan for SQL injection vulnerabilities on the page.

Program:

Python
import requests
from bs4 import BeautifulSoup
import sys
from urllib.parse import urljoin

s = requests.Session()
s.headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"


def get_forms(url):
    # Make a GET request to the URL and parse the HTML content with BeautifulSoup
    soup = BeautifulSoup(s.get(url).content, "html.parser")
    # Find all form tags on the page and return them
    return soup.find_all("form")


def form_details(form):
    detailsOfForm = {}
    
    # Get the form action (URL to which the form is submitted)
    action = form.attrs.get("action", "").lower()  # Default to empty string if no action attribute
    # Get the form method (POST or GET)
    method = form.attrs.get("method", "get").lower()  # Default to "get" if no method attribute
    
    inputs = []
    
    # Iterate through all input tags inside the form
    for input_tag in form.find_all("input"):
        input_type = input_tag.attrs.get("type", "text")  # Default to "text" if no type attribute
        input_name = input_tag.attrs.get("name")
        input_value = input_tag.attrs.get("value", "")  # Default to empty string if no value attribute
        inputs.append({"type": input_type, "name": input_name, "value": input_value})
    
    # Store form details in the dictionary
    detailsOfForm["action"] = action
    detailsOfForm["method"] = method
    detailsOfForm["inputs"] = inputs
    
    return detailsOfForm


def vulnerable(response):
    errors = {"quoted string not properly terminated",
              "unclosed quotation mark after the character string",
              "you have an error in your sql syntax;"}

    for error in errors:
        if error in response.content.decode().lower():
            return True
    return False


def sql_injection_scan(url):
    forms = get_forms(url)
    print(f"[+] Detected {len(forms)} forms on {url}.")
    
    # Iterate over all forms found on the page
    for form in forms:
        details = form_details(form)
        
        # Test for SQL injection using common special characters
        for c in "\"'":
            data = {}
            
            for input_tag in details["inputs"]:
                if input_tag["type"] == "hidden" or input_tag["value"]: 
                    # If the input type is hidden or it already has a value, append the character to the value
                    data[input_tag["name"]] = input_tag["value"] + c
                elif input_tag["type"] != "submit": 
                    # If the input is not a submit button, inject the test character
                    data[input_tag["name"]] = f"test{c}"
            
            # Construct the URL to which the form will be submitted
            url = urljoin(url, details["action"])
            
            # Send the request based on the form method (POST or GET)
            if details["method"] == "post":
                res = s.post(url, data=data)
            elif details["method"] == "get":
                res = s.get(url, params=data)
            
            # Check if the response indicates a possible SQL injection vulnerability
            if vulnerable(res):
                print(f"SQL Injection attack vulnerability detected in form at {url}")
            else:
                print("No SQL Injection vulnerability detected")

if __name__ == "__main__":
    url_arg = "https://www.geeksforgeeks.org/python/python-programming-language-tutorial/"
    sql_injection_scan(url_arg)

Output:

[+] Detected 2 forms on https://www.geeksforgeeks.org/python/python-programming-language-tutorial/
No SQL Injection vulnerability detected
No SQL Injection vulnerability detected
No SQL Injection vulnerability detected
No SQL Injection vulnerability detected

Article Tags :
Practice Tags :

Similar Reads