Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c10f5b2

Browse files
Added Http-headers
1 parent e56e82d commit c10f5b2

File tree

3 files changed

+152
-0
lines changed

3 files changed

+152
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Grab your API key from Open Router:- https://openrouter.ai/
2+
Model is Used is DeepSeek: DeepSeek V3.1 (free). However, feel free to try others.
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#!/usr/bin/env python3
2+
import requests
3+
import json
4+
import os
5+
import argparse
6+
from typing import Dict, List, Tuple
7+
from openai import OpenAI
8+
9+
class SecurityHeadersAnalyzer:
10+
def __init__(self, api_key: str = None, base_url: str = None, model: str = None):
11+
self.api_key = api_key or os.getenv('OPENROUTER_API_KEY') or os.getenv('OPENAI_API_KEY')
12+
self.base_url = base_url or os.getenv('OPENROUTER_BASE_URL', 'https://openrouter.ai/api/v1')
13+
self.model = model or os.getenv('LLM_MODEL', 'deepseek/deepseek-chat-v3.1:free')
14+
15+
if not self.api_key:
16+
raise ValueError("API key is required. Set OPENROUTER_API_KEY or provide --api-key")
17+
18+
self.client = OpenAI(base_url=self.base_url, api_key=self.api_key)
19+
20+
def fetch_headers(self, url: str, timeout: int = 10) -> Tuple[Dict[str, str], int]:
21+
"""Fetch HTTP headers from URL"""
22+
if not url.startswith(('http://', 'https://')):
23+
url = 'https://' + url
24+
25+
try:
26+
response = requests.get(url, timeout=timeout, allow_redirects=True)
27+
return dict(response.headers), response.status_code
28+
except requests.exceptions.RequestException as e:
29+
print(f"Error fetching {url}: {e}")
30+
return {}, 0
31+
32+
def analyze_headers(self, url: str, headers: Dict[str, str], status_code: int) -> str:
33+
"""Analyze headers using LLM"""
34+
prompt = f"""Analyze the HTTP security headers for {url} (Status: {status_code})
35+
36+
Headers:
37+
{json.dumps(headers, indent=2)}
38+
39+
Provide a comprehensive security analysis including:
40+
1. Security score (0-100) and overall assessment
41+
2. Critical security issues that need immediate attention
42+
3. Missing important security headers
43+
4. Analysis of existing security headers and their effectiveness
44+
5. Specific recommendations for improvement
45+
6. Potential security risks based on current configuration
46+
47+
Focus on practical, actionable advice following current web security best practices. Please do not include ** and #
48+
in the response except for specific references where necessary. use numbers, romans, alphabets instead Format the response well please. """
49+
50+
try:
51+
completion = self.client.chat.completions.create(
52+
model=self.model,
53+
messages=[{"role": "user", "content": prompt}],
54+
temperature=0.2
55+
)
56+
return completion.choices[0].message.content
57+
except Exception as e:
58+
return f"Analysis failed: {e}"
59+
60+
def analyze_url(self, url: str, timeout: int = 10) -> Dict:
61+
"""Analyze a single URL"""
62+
print(f"\nAnalyzing: {url}")
63+
print("-" * 50)
64+
65+
headers, status_code = self.fetch_headers(url, timeout)
66+
if not headers:
67+
return {"url": url, "error": "Failed to fetch headers"}
68+
69+
print(f"Status Code: {status_code}")
70+
print(f"\nHTTP Headers ({len(headers)} found):")
71+
print("-" * 30)
72+
for key, value in headers.items():
73+
print(f"{key}: {value}")
74+
75+
print(f"\nAnalyzing with AI...")
76+
analysis = self.analyze_headers(url, headers, status_code)
77+
78+
print("\nSECURITY ANALYSIS")
79+
print("=" * 50)
80+
print(analysis)
81+
82+
return {
83+
"url": url,
84+
"status_code": status_code,
85+
"headers_count": len(headers),
86+
"analysis": analysis,
87+
"raw_headers": headers
88+
}
89+
90+
def analyze_multiple_urls(self, urls: List[str], timeout: int = 10) -> List[Dict]:
91+
"""Analyze multiple URLs"""
92+
results = []
93+
for i, url in enumerate(urls, 1):
94+
print(f"\n[{i}/{len(urls)}]")
95+
result = self.analyze_url(url, timeout)
96+
results.append(result)
97+
return results
98+
99+
def export_results(self, results: List[Dict], filename: str):
100+
"""Export results to JSON"""
101+
with open(filename, 'w') as f:
102+
json.dump(results, f, indent=2, ensure_ascii=False)
103+
print(f"\nResults exported to: {filename}")
104+
105+
def main():
106+
parser = argparse.ArgumentParser(
107+
description='Analyze HTTP security headers using AI',
108+
formatter_class=argparse.RawDescriptionHelpFormatter,
109+
epilog='''Examples:
110+
python security_headers.py https://example.com
111+
python security_headers.py example.com google.com
112+
python security_headers.py example.com --export results.json
113+
114+
Environment Variables:
115+
OPENROUTER_API_KEY - API key for OpenRouter
116+
OPENAI_API_KEY - API key for OpenAI
117+
LLM_MODEL - Model to use (default: deepseek/deepseek-chat-v3.1:free)'''
118+
)
119+
120+
parser.add_argument('urls', nargs='+', help='URLs to analyze')
121+
parser.add_argument('--api-key', help='API key for LLM service')
122+
parser.add_argument('--base-url', help='Base URL for LLM API')
123+
parser.add_argument('--model', help='LLM model to use')
124+
parser.add_argument('--timeout', type=int, default=10, help='Request timeout (default: 10s)')
125+
parser.add_argument('--export', help='Export results to JSON file')
126+
127+
args = parser.parse_args()
128+
129+
try:
130+
analyzer = SecurityHeadersAnalyzer(
131+
api_key=args.api_key,
132+
base_url=args.base_url,
133+
model=args.model
134+
)
135+
136+
results = analyzer.analyze_multiple_urls(args.urls, args.timeout)
137+
138+
if args.export:
139+
analyzer.export_results(results, args.export)
140+
141+
except ValueError as e:
142+
print(f"Error: {e}")
143+
return 1
144+
except KeyboardInterrupt:
145+
print("\nAnalysis interrupted by user")
146+
return 1
147+
148+
if __name__ == '__main__':
149+
main()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
openai

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /