├── API Vulnerability Scanner.py ├── LICENSE └── README.md /API Vulnerability Scanner.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import messagebox, filedialog 3 | import requests 4 | import threading 5 | import csv 6 | import json 7 | import time 8 | from datetime import datetime 9 | 10 | class VulnerabilityScanner: 11 | def __init__(self, api_url, proxy=None, timeout=10, user_agent=None): 12 | self.api_url = api_url 13 | self.proxy = proxy 14 | self.timeout = timeout 15 | self.user_agent = user_agent 16 | self.stop_flag = False 17 | 18 | # Helper method to stop scanning 19 | def stop_scan(self): 20 | self.stop_flag = True 21 | 22 | # Test 1: SQL Injection 23 | def test_sql_injection(self): 24 | if self.stop_flag: 25 | return "Scan Stopped", "orange" 26 | 27 | payload = "' OR '1'='1" 28 | try: 29 | response = requests.get(self.api_url + payload, proxies=self.proxy, timeout=self.timeout, headers={'User-Agent': self.user_agent}) 30 | if "error" in response.text.lower(): 31 | return "Possible SQL Injection vulnerability found!", "red" 32 | except requests.exceptions.RequestException: 33 | return "Error connecting to the API", "orange" 34 | return "No SQL Injection detected.", "green" 35 | 36 | # Test 2: XSS (Cross-Site Scripting) 37 | def test_xss(self): 38 | if self.stop_flag: 39 | return "Scan Stopped", "orange" 40 | 41 | payload = "" 42 | try: 43 | response = requests.get(self.api_url + payload, proxies=self.proxy, timeout=self.timeout, headers={'User-Agent': self.user_agent}) 44 | if payload in response.text: 45 | return "Possible XSS vulnerability found!", "red" 46 | except requests.exceptions.RequestException: 47 | return "Error connecting to the API", "orange" 48 | return "No XSS detected.", "green" 49 | 50 | # Test 3: Command Injection 51 | def test_command_injection(self): 52 | if self.stop_flag: 53 | return "Scan Stopped", "orange" 54 | 55 | payload = "; ls" 56 | try: 57 | response = requests.get(self.api_url + payload, proxies=self.proxy, timeout=self.timeout, headers={'User-Agent': self.user_agent}) 58 | if "bash" in response.text or "sh" in response.text: 59 | return "Possible Command Injection vulnerability found!", "red" 60 | except requests.exceptions.RequestException: 61 | return "Error connecting to the API", "orange" 62 | return "No Command Injection detected.", "green" 63 | 64 | # Test 4: CSRF (Cross-Site Request Forgery) 65 | def test_csrf(self): 66 | if self.stop_flag: 67 | return "Scan Stopped", "orange" 68 | 69 | headers = { 70 | 'Content-Type': 'application/x-www-form-urlencoded', 71 | 'X-Requested-With': 'XMLHttpRequest' 72 | } 73 | data = {'user': 'admin', 'password': 'password'} 74 | try: 75 | response = requests.post(self.api_url, data=data, headers=headers, proxies=self.proxy, timeout=self.timeout) 76 | if response.status_code == 200: 77 | return "Possible CSRF vulnerability found!", "red" 78 | except requests.exceptions.RequestException: 79 | return "Error connecting to the API", "orange" 80 | return "No CSRF detected.", "green" 81 | 82 | # Test 5: Directory Traversal 83 | def test_directory_traversal(self): 84 | if self.stop_flag: 85 | return "Scan Stopped", "orange" 86 | 87 | payload = "../../../../etc/passwd" 88 | try: 89 | response = requests.get(self.api_url + payload, proxies=self.proxy, timeout=self.timeout, headers={'User-Agent': self.user_agent}) 90 | if "root" in response.text: 91 | return "Possible Directory Traversal vulnerability found!", "red" 92 | except requests.exceptions.RequestException: 93 | return "Error connecting to the API", "orange" 94 | return "No Directory Traversal detected.", "green" 95 | 96 | # Test 6: Insecure HTTP Methods (PUT, DELETE) 97 | def test_insecure_http_methods(self): 98 | if self.stop_flag: 99 | return "Scan Stopped", "orange" 100 | 101 | methods = ['PUT', 'DELETE'] 102 | for method in methods: 103 | try: 104 | response = requests.request(method, self.api_url, proxies=self.proxy, timeout=self.timeout) 105 | if response.status_code != 405: # If status is not 405, method is allowed 106 | return f"Possible Insecure HTTP Method vulnerability with {method} found!", "red" 107 | except requests.exceptions.RequestException: 108 | return "Error connecting to the API", "orange" 109 | return "No Insecure HTTP Methods detected.", "green" 110 | 111 | # Test 7: Header Injection 112 | def test_header_injection(self): 113 | if self.stop_flag: 114 | return "Scan Stopped", "orange" 115 | 116 | headers = {'X-Injected-Header': 'Injected Value'} 117 | try: 118 | response = requests.get(self.api_url, headers=headers, proxies=self.proxy, timeout=self.timeout) 119 | if 'Injected Value' in response.text: 120 | return "Possible Header Injection vulnerability found!", "red" 121 | except requests.exceptions.RequestException: 122 | return "Error connecting to the API", "orange" 123 | return "No Header Injection detected.", "green" 124 | 125 | # Additional Tests: Clickjacking, Session Fixation, Open Redirect, etc. 126 | def test_clickjacking(self): 127 | if self.stop_flag: 128 | return "Scan Stopped", "orange" 129 | 130 | headers = {'X-Frame-Options': 'DENY'} 131 | try: 132 | response = requests.get(self.api_url, headers=headers, proxies=self.proxy, timeout=self.timeout) 133 | if 'X-Frame-Options' not in response.headers or response.headers['X-Frame-Options'] != 'DENY': 134 | return "Possible Clickjacking vulnerability found!", "red" 135 | except requests.exceptions.RequestException: 136 | return "Error connecting to the API", "orange" 137 | return "No Clickjacking detected.", "green" 138 | 139 | # Test 9: Session Fixation 140 | def test_session_fixation(self): 141 | if self.stop_flag: 142 | return "Scan Stopped", "orange" 143 | 144 | try: 145 | response = requests.get(self.api_url, proxies=self.proxy, timeout=self.timeout) 146 | if 'JSESSIONID' in response.cookies: 147 | return "Possible Session Fixation vulnerability found!", "red" 148 | except requests.exceptions.RequestException: 149 | return "Error connecting to the API", "orange" 150 | return "No Session Fixation detected.", "green" 151 | 152 | # Test 10: Open Redirect 153 | def test_open_redirect(self): 154 | if self.stop_flag: 155 | return "Scan Stopped", "orange" 156 | 157 | payload = "?redirect=https://evil.com" 158 | try: 159 | response = requests.get(self.api_url + payload, proxies=self.proxy, timeout=self.timeout, headers={'User-Agent': self.user_agent}) 160 | if "evil.com" in response.url: 161 | return "Possible Open Redirect vulnerability found!", "red" 162 | except requests.exceptions.RequestException: 163 | return "Error connecting to the API", "orange" 164 | return "No Open Redirect detected.", "green" 165 | 166 | # Add additional tests from 11 to 20 in the same way... 167 | 168 | def run(self): 169 | results = [] 170 | tests = [ 171 | self.test_sql_injection, 172 | self.test_xss, 173 | self.test_command_injection, 174 | self.test_csrf, 175 | self.test_directory_traversal, 176 | self.test_insecure_http_methods, 177 | self.test_header_injection, 178 | self.test_clickjacking, 179 | self.test_session_fixation, 180 | self.test_open_redirect, 181 | # Continue adding more tests up to 20 182 | ] 183 | 184 | for test in tests: 185 | result, color = test() 186 | results.append((result, color)) 187 | if self.stop_flag: 188 | break 189 | return results 190 | 191 | def start_scan(): 192 | api_url = entry.get() 193 | if not api_url: 194 | messagebox.showerror("Error", "Please enter an API URL") 195 | return 196 | 197 | scan_button.config(state=tk.DISABLED) 198 | stop_button.config(state=tk.NORMAL) 199 | results_text.delete(1.0, tk.END) 200 | 201 | def scan_thread(): 202 | scanner = VulnerabilityScanner(api_url) 203 | results = scanner.run() 204 | 205 | for result, color in results: 206 | results_text.insert(tk.END, result + "\n") 207 | results_text.tag_add("start", f"{results_text.index('end-1c')} linestart", f"{results_text.index('end')} lineend") 208 | results_text.tag_configure("start", foreground=color) 209 | 210 | scan_button.config(state=tk.NORMAL) 211 | stop_button.config(state=tk.DISABLED) 212 | 213 | threading.Thread(target=scan_thread).start() 214 | 215 | def stop_scan(): 216 | global scanner 217 | if hasattr(scanner, 'stop_scan'): 218 | scanner.stop_scan() 219 | stop_button.config(state=tk.DISABLED) 220 | scan_button.config(state=tk.NORMAL) 221 | 222 | def save_results(): 223 | results = results_text.get("1.0", tk.END).strip() 224 | if not results: 225 | messagebox.showerror("Error", "No results to save") 226 | return 227 | 228 | file_path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text files", "*.txt"), ("CSV files", "*.csv"), ("JSON files", "*.json")]) 229 | if not file_path: 230 | return 231 | 232 | file_extension = file_path.split('.')[-1].lower() 233 | 234 | try: 235 | if file_extension == "txt": 236 | with open(file_path, "w") as file: 237 | file.write(results) 238 | elif file_extension == "csv": 239 | with open(file_path, "w", newline="") as file: 240 | writer = csv.writer(file) 241 | writer.writerow(["Vulnerability", "Severity"]) 242 | for line in results.split("\n"): 243 | writer.writerow([line.strip(), "N/A"]) 244 | elif file_extension == "json": 245 | json_data = [{"vulnerability": line.strip(), "severity": "N/A"} for line in results.split("\n")] 246 | with open(file_path, "w") as file: 247 | json.dump(json_data, file, indent=4) 248 | messagebox.showinfo("Success", f"Results saved to {file_path}") 249 | except Exception as e: 250 | messagebox.showerror("Error", f"Failed to save results: {e}") 251 | 252 | # GUI setup 253 | window = tk.Tk() 254 | window.title("API Vulnerability Scanner") 255 | 256 | frame = tk.Frame(window) 257 | frame.pack(padx=10, pady=10) 258 | 259 | label = tk.Label(frame, text="Enter API URL:") 260 | label.grid(row=0, column=0) 261 | 262 | entry = tk.Entry(frame, width=50) 263 | entry.grid(row=0, column=1) 264 | 265 | # Buttons in a single row 266 | button_frame = tk.Frame(window) 267 | button_frame.pack(pady=10) 268 | 269 | scan_button = tk.Button(button_frame, text="Start Scan", command=start_scan) 270 | scan_button.grid(row=0, column=0, padx=5) 271 | 272 | stop_button = tk.Button(button_frame, text="Stop Scan", command=stop_scan, state=tk.DISABLED) 273 | stop_button.grid(row=0, column=1, padx=5) 274 | 275 | save_button = tk.Button(button_frame, text="Save Results", command=save_results) 276 | save_button.grid(row=0, column=2, padx=5) 277 | 278 | results_text = tk.Text(window, height=15, width=60) 279 | results_text.pack(padx=10, pady=10) 280 | 281 | window.mainloop() 282 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Amir Hossein 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # API Vulnerability Scanner 2 | 3 | A GUI-based Python tool for scanning APIs for potential vulnerabilities using predefined test cases. 4 | 5 | ## Features 6 | - **SQL Injection Detection** 7 | - **Cross-Site Scripting (XSS) Detection** 8 | - **Command Injection Detection** 9 | - **Cross-Site Request Forgery (CSRF) Detection** 10 | - **Directory Traversal Detection** 11 | - **Insecure HTTP Methods Detection** 12 | - **Header Injection Detection** 13 | - **Clickjacking Detection** 14 | - **Session Fixation Detection** 15 | - **Open Redirect Detection** 16 | - Save scan results in **TXT**, **CSV**, or **JSON** formats. 17 | 18 | ## Requirements 19 | - Python 3.x 20 | - Libraries: `tkinter`, `requests`, `threading`, `csv`, `json`, `time`, `datetime` 21 | --------------------------------------------------------------------------------