-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathRNScanner.py
More file actions
138 lines (115 loc) · 4.33 KB
/
RNScanner.py
File metadata and controls
138 lines (115 loc) · 4.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
"""
React Native Vulnerability Scanner
----------------------------------
Author: BhattJayD
GitHub: https://github.com/BhattJayD
Email: cbhatt526@gmail.com
Twitter: @ogSplitUnknown
Youtube: https://www.youtube.com/@SplitUnknown
Medium: https://splitunknown.medium.com
License: MIT
Description:
This script scans npm dependencies listed in `modules.json` (extracted from a React Native APK)
and checks for known vulnerabilities using Snyk's vulnerability database.
It provides multi-threaded scanning, colored output, and optional file-saving.
"""
import json
import requests
import argparse
import sys
import time
from bs4 import BeautifulSoup
from colorama import Fore, Style, init
from concurrent.futures import ThreadPoolExecutor, as_completed
from itertools import cycle
from threading import Thread, Lock
from queue import Queue
# Initialize colorama for colored output
init(autoreset=True)
# Argument Parser
parser = argparse.ArgumentParser(
description="Check vulnerabilities in npm packages.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter # Show default values in help
)
parser.add_argument("-f", "--file", help="Path to module.json file", default="modules.json")
parser.add_argument("-o", "--output", help="Save results to a file", action="store_true")
# Show help if no arguments are passed
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
# Parse arguments
try:
args = parser.parse_args()
except SystemExit:
parser.print_help()
sys.exit(1)
# Load JSON data
try:
with open(args.file, "r") as file:
data = json.load(file)
except FileNotFoundError:
print(Fore.RED + f"Error: File '{args.file}' not found!")
sys.exit(1)
# Extract package names
items = list(data.keys())
# Define cookies and headers
cookies = {
'user_utm': '{"utm_medium":"paid-search","utm_source":"google","utm_campaign":"gs_sn:-brand-ind","utm_content":"br_ex","utm_term":"snyk"}',
}
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:135.0) Gecko/20100101 Firefox/135.0',
}
# Queue to store results
results_queue = Queue()
lock = Lock() # Ensure thread-safe operations
# Loading animation
loading = True
def animate():
"""Loading animation while checking vulnerabilities."""
for frame in cycle(["[\\]", "[|]", "[/]", "[-]"]):
if not loading:
break
sys.stdout.write("\r" + Fore.YELLOW + f"Checking vulnerabilities {frame}" + Style.RESET_ALL)
sys.stdout.flush()
time.sleep(0.2)
sys.stdout.write("\r" + " " * 30 + "\r") # Clear loading text
# Function to check vulnerabilities
def check_vulnerability(item):
params = {'search': item}
response = requests.get('https://security.snyk.io/vuln/npm', params=params, cookies=cookies, headers=headers)
# Parse HTML content
soup = BeautifulSoup(response.text, 'html.parser')
# Find elements with the required classes
cells = soup.find_all(class_=['table__data-cell--first-row', 'table__data-cell--first-column', 'table__data-cell'])
# If results are found, add to queue
if cells:
with lock:
results_queue.put((item, data[item])) # Store as tuple (name, version)
# Start loading animation in a separate thread
animation_thread = Thread(target=animate)
animation_thread.start()
# Use ThreadPoolExecutor for multithreading
num_threads = 10 # Adjust based on system capability
with ThreadPoolExecutor(max_workers=num_threads) as executor:
future_to_item = {executor.submit(check_vulnerability, item): item for item in items}
for future in as_completed(future_to_item):
future.result() # Ensure all tasks complete
# Stop loading animation
loading = False
animation_thread.join()
# Collect results
results = []
while not results_queue.empty():
package, version = results_queue.get()
print(Fore.RED + f"{package} : {version}" + Style.RESET_ALL) # Colored output for terminal
results.append(f"{package} : {version}") # Store plain text for file saving
# If no vulnerabilities found, print a message
if not results:
print(Fore.GREEN + "No vulnerabilities found! 🎉")
else:
# Save output to file if requested (without colors)
if args.output:
with open("vulnerable_packages.txt", "w") as f:
f.write("\n".join(results))
print(Fore.GREEN + "\nResults saved to vulnerable_packages.txt")
print(Fore.GREEN + "Done!")