In today's cybersecurity landscape, it's essential to proactively monitor your website for potential weaknesses. In this post, we'll walk through a powerful yet simple Python-based web security scanner that checks:
HTTP security headers
SSL certificate details
Common open ports
Vulnerabilities like SQL Injection (SQLi) and Cross-site Scripting (XSS)
This tool is ideal for developers, ethical hackers, or DevSecOps engineers looking to automate routine security scans.
import socket
import requests
import ssl
from urllib.parse import urlparse
from jinja2 import Template
import os
SECURITY_HEADERS = [
"Content-Security-Policy",
"Strict-Transport-Security",
"X-Content-Type-Options",
"X-Frame-Options",
"X-XSS-Protection",
"Referrer-Policy",
"Permissions-Policy"
]
COMMON_PORTS = {
21: "FTP", 22: "SSH", 23: "Telnet", 25: "SMTP",
53: "DNS", 80: "HTTP", 110: "POP3", 143: "IMAP",
443: "HTTPS", 3306: "MySQL", 8080: "HTTP-Alt"
}
def check_http_headers(url):
result = {"status_code": None, "server": None, "headers": {}}
try:
response = requests.get(url, timeout=10)
result["status_code"] = response.status_code
result["server"] = response.headers.get("Server", "N/A")
for header in SECURITY_HEADERS:
result["headers"][header] = response.headers.get(header, None)
except Exception as e:
result["error"] = str(e)
return result
def check_ssl_certificate(hostname):
cert_info = dict()
try:
context = ssl.create_default_context()
with socket.create_connection((hostname, 443), timeout=5) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
cert = ssock.getpeercert()
cert_info["issuer"] = cert.get("issuer")
cert_info["subject"] = cert.get("subject")
cert_info["notBefore"] = cert.get("notBefore")
cert_info["notAfter"] = cert.get("notAfter")
except Exception as e:
cert_info["error"] = str(e)
return cert_info
def scan_ports(hostname):
open_ports = []
for port, service in COMMON_PORTS.items():
try:
with socket.create_connection((hostname, port), timeout=1):
open_ports.append((port, service))
except Exception as e:
pass
return open_ports
def test_sqli_xss(url):
payloads = {
"SQLi": "' OR '1'='1",
"XSS": "<script>alert('XSS')</script>"
}
results = dict()
for test, payload in payloads.items():
try:
response = requests.get(url, params={'test': payload}, timeout=10)
if payload in response.text:
results[test] = "Possible vulnerability detected!"
else:
results[test] = "No vulnerability detected"
except Exception as e:
results[test] = f"Error: {e}"
return results
def generate_html_report(data, filename="scan_report.html"):
template = Template("""
<html>
<head><title>Security Scan Report</title></head>
<body style="font-family:sans-serif">
<h1>Security Scan Report for {{ target }}</h1>
<h2>HTTP Info</h2>
<p>Status Code: {{ http.status_code }}</p>
<p>Server: {{ http.server }}</p>
<h3>Security Headers</h3>
<ul>
{% for k, v in http.headers.items() %}
<li>{{ k }}: {{ "Present" if v else "Missing" }}</li>
{% endfor %}
</ul>
<h2>SSL Certificate</h2>
<ul>
{% for k, v in ssl.items() %}
<li>{{ k }}: {{ v }}</li>
{% endfor %}
</ul>
<h2>Open Ports</h2>
<ul>
{% for port, service in ports %}
<li>{{ port }} ({{ service }})</li>
{% endfor %}
</ul>
<h2>Vulnerability Test</h2>
<ul>
{% for k, v in vuln.items() %}
<li>{{ k }}: {{ v }}</li>
{% endfor %}
</ul>
</body>
</html>
""")
output = template.render(**data)
with open(filename, "w", encoding="utf-8") as f:
f.write(output)
return filename
def run_full_scan(target_url):
parsed = urlparse(target_url)
hostname = parsed.hostname or target_url.replace("http://", "").replace("https://", "")
print(f"[+] Scanning: {target_url}")
http_info = check_http_headers(target_url)
ssl_info = check_ssl_certificate(hostname)
open_ports = scan_ports(hostname)
vuln_test = test_sqli_xss(target_url)
report_data = {
"target": target_url,
"http": http_info,
"ssl": ssl_info,
"ports": open_ports,
"vuln": vuln_test
}
report_file = generate_html_report(report_data)
print(f"\n✅ Report generated: {report_file}")
return report_file
if __name__ == "__main__":
url = input("Enter website URL (e.g., https://example.com): ")
run_full_scan(url)
This script performs a full scan on a given target URL:
Checks HTTP Security Headers
Ensures presence of critical headers like:
Content-Security-Policy
Strict-Transport-Security
X-Frame-Options
And others that prevent clickjacking, content sniffing, and XSS.
Scans for Open Common Ports
Uses raw socket connections to identify open ports like:
80 (HTTP), 443 (HTTPS), 21 (FTP), 22 (SSH), etc.
Analyzes SSL Certificate Info
Extracts certificate validity, issuer, subject, and expiration date.
Tests for SQL Injection & XSS Vulnerabilities
Sends basic payloads to detect if the site reflects malicious code or logic bypass attempts.
Generates an HTML Report
Clean, readable scan results are saved in an easy-to-read scan_report.html
.
Result:
And the HTML report will include sections like:
HTTP Status & Security Headers (Present / Missing)
SSL certificate details (Not Before / Not After)
List of open ports and their associated services
SQLi and XSS test results
requests
for HTTP/S requests
socket
and ssl
for raw network connections
jinja2
for HTML templating
urllib.parse
for URL parsing
Developers can integrate this into CI pipelines for basic security checks.
Security researchers can use it for quick assessments of target domains.
Educators can teach web vulnerability concepts interactively.
SQLi: ' OR '1'='1
XSS: <script>alert('XSS')</script>
These are simple test cases and should not be used on systems you don't own or have permission to test (black-box testing without consent is illegal).
This script is intended for educational and authorized testing only. Scanning websites without permission may violate terms of service or local laws. Always have written consent when testing systems you do not own.
Learn how to automatically scan your local network using Nmap with Python, detect active devices and operating systems, and export scan results to JSON format.
5 min readLearn how to fingerprint LAN devices using Python, Scapy, and Impacket. Collect OS info, open ports, HTTP server data, and SMB banners with a single script.
5 min readLearn how to write a Python script to scan local networks using TCP SYN packets, detect live hosts, and discover connected devices with IPs and hostnames.
5 min readLearn how to use Python and Scapy to scan your local network, detect connected devices by IP and hostname, and quickly discover active hosts in your LAN.
5 min readLearn how to test common Django security vulnerabilities like XSS, CSRF, SQL Injection, and more using Python scripts.
5 min read