C

Comprehensive Sql Module

Streamline your workflow with this skill, should, used, user. Includes structured workflows, validation checks, and reusable patterns for security.

SkillClipticssecurityv1.0.0MIT
0 views0 copies

Comprehensive SQL Module

Master SQL injection detection, exploitation, and prevention techniques for web application security testing. This skill covers manual SQL injection testing, blind injection techniques, out-of-band extraction, WAF bypass methods, and secure coding practices to prevent SQL injection vulnerabilities.

When to Use This Skill

Choose Comprehensive SQL Module when you need to:

  • Manually test web applications for SQL injection vulnerabilities
  • Understand and exploit different SQL injection types (union, blind, error-based)
  • Bypass Web Application Firewalls that block common SQLi payloads
  • Implement secure coding practices to prevent SQL injection

Consider alternatives when:

  • You need automated SQL injection testing (use SQLMap)
  • You need general API fuzzing (use API Fuzzing skill)
  • You need database administration security (use database hardening guides)

Quick Start

import requests from urllib.parse import quote class SQLInjectionTester: """Manual SQL injection testing toolkit (authorized testing only).""" DETECTION_PAYLOADS = { 'single_quote': "'", 'double_quote': '"', 'comment': "' --", 'or_true': "' OR '1'='1", 'or_false': "' OR '1'='2", 'semicolon': "'; --", 'integer_math': "1+1", 'sleep_5': "' OR SLEEP(5)--", } def __init__(self, base_url, proxy=None): self.base_url = base_url self.session = requests.Session() if proxy: self.session.proxies = {'http': proxy, 'https': proxy} def detect_sqli(self, url, param, method='GET', data=None): """Test a parameter for SQL injection indicators.""" findings = [] # Baseline request baseline_params = {param: 'normalvalue'} if method == 'GET': baseline = self.session.get(url, params=baseline_params, timeout=10) else: baseline = self.session.post(url, data=baseline_params, timeout=10) baseline_len = len(baseline.content) baseline_time = baseline.elapsed.total_seconds() for name, payload in self.DETECTION_PAYLOADS.items(): test_params = {param: payload} try: if method == 'GET': resp = self.session.get(url, params=test_params, timeout=15) else: resp = self.session.post(url, data=test_params, timeout=15) indicators = [] # Error-based detection error_patterns = [ 'sql syntax', 'mysql_', 'ORA-', 'pg_query', 'sqlite3', 'unclosed quotation', 'quoted string', 'syntax error', 'unexpected end of SQL', ] for pattern in error_patterns: if pattern.lower() in resp.text.lower(): indicators.append(f'SQL error: {pattern}') # Boolean-based detection if name == 'or_true' and len(resp.content) != baseline_len: indicators.append('Boolean: true condition changed response') # Time-based detection if 'sleep' in name and resp.elapsed.total_seconds() > baseline_time + 4: indicators.append(f'Time-based: {resp.elapsed.total_seconds():.1f}s delay') if indicators: findings.append({ 'payload': name, 'indicators': indicators, 'status': resp.status_code, }) except requests.exceptions.Timeout: if 'sleep' in name: findings.append({ 'payload': name, 'indicators': ['Time-based: request timed out (likely vulnerable)'], }) return findings # tester = SQLInjectionTester("https://target.example.com") # findings = tester.detect_sqli("https://target.example.com/search", "q")

Core Concepts

SQL Injection Types

TypeDetection MethodData ExtractionSpeed
Error-basedDatabase errors in responseError messages contain dataFast
Union-basedUNION SELECT returns dataData in normal responseFast
Boolean blindResponse changes (true/false)One bit at a timeSlow
Time-based blindResponse time variesOne bit at a timeVery slow
Out-of-bandDNS/HTTP callbacksData via external channelMedium
Stacked queriesMultiple statements executeFull DB accessFast (if supported)

Prevention: Parameterized Queries

# VULNERABLE — string concatenation # NEVER DO THIS def get_user_vulnerable(username): query = f"SELECT * FROM users WHERE username = '{username}'" cursor.execute(query) # SQL injection! # SECURE — parameterized query def get_user_secure(username): query = "SELECT * FROM users WHERE username = %s" cursor.execute(query, (username,)) # Safe # SECURE — ORM (SQLAlchemy) def get_user_orm(username): return User.query.filter_by(username=username).first() # Safe # SECURE — prepared statement (psycopg2) def get_user_prepared(username): cursor.execute( "PREPARE user_lookup AS SELECT * FROM users WHERE username = $1" ) cursor.execute("EXECUTE user_lookup (%s)", (username,)) # For dynamic queries (column names, table names): ALLOWED_COLUMNS = {'username', 'email', 'created_at'} def get_users_sorted(sort_column): if sort_column not in ALLOWED_COLUMNS: raise ValueError(f"Invalid sort column: {sort_column}") query = f"SELECT * FROM users ORDER BY {sort_column}" # Safe: whitelist-validated cursor.execute(query)

Configuration

ParameterDescriptionDefault
target_urlTarget URL to testRequired
injection_paramParameter to inject intoRequired
methodHTTP method (GET, POST)"GET"
dbmsTarget database (mysql, postgres, mssql, oracle, sqlite)Auto-detect
techniqueInjection technique to useAuto-detect
time_delaySeconds for time-based detection5
proxyProxy for request inspectionNone
waf_bypassEnable WAF bypass techniquesfalse

Best Practices

  1. Always test with both string and integer injection contexts — String context requires quote characters (') to break out. Integer context doesn't need quotes but requires different payloads (1 OR 1=1). Test both because the injection context determines which payloads work.

  2. Use time-based blind injection as the definitive confirmation test — If error-based and boolean-based detection are inconclusive, a time-based payload (' OR SLEEP(5)--) that consistently adds 5 seconds to the response time is strong confirmation. Run it 3 times to rule out network latency.

  3. Always use parameterized queries — there are no exceptions — String sanitization, escaping, and blacklisting are all bypassable. The only reliable prevention is parameterized queries (prepared statements) which separate SQL code from data at the database protocol level.

  4. Test for second-order SQL injection — First-order SQLi executes immediately. Second-order SQLi stores the payload and executes it later (e.g., a username stored in the database that triggers SQLi when used in an admin query). Test by injecting payloads in registration forms and checking admin panels.

  5. Document the exact injection point and database type for handoff — When reporting SQLi, specify: the exact URL and parameter, the HTTP method, the database type, the injection type (union/blind/error), and a proof-of-concept that extracts data (e.g., database version). Generic "SQLi found" reports are unhelpful.

Common Issues

WAF blocks common SQL injection payloads — Use encoding bypasses: URL encoding (%27 for '), double URL encoding (%2527), unicode (%u0027), or case variation (SeLeCt). Use comments to break keywords: SEL/**/ECT. Use alternative syntax: CASE WHEN 1=1 THEN instead of OR 1=1.

Boolean-based blind injection gives inconsistent results — Network latency and dynamic content cause response size variations. Establish a reliable baseline by sending the same request 5 times and measuring the response size range. Only flag boolean differences that exceed the natural variation.

Application uses ORM but is still vulnerable — ORMs prevent SQLi in standard queries but can be bypassed through raw SQL methods (Model.objects.raw() in Django, ActiveRecord.find_by_sql() in Rails). Search for raw SQL usage in the codebase — these are the injection points.

Community

Reviews

Write a review

No reviews yet. Be the first to review this template!

Similar Templates