Open yihong1120 opened 1 month ago
To solve the bug related to "Uncontrolled data used in path expression," we need to ensure that all user inputs used in path expressions are properly validated and sanitized. This will prevent path traversal vulnerabilities and other security issues. The plan involves:
The bug is caused by the lack of validation and sanitization of user inputs used in path expressions. Specifically:
src/stream_capture.py
, the stream URL is taken directly from user input without validation.src/model_fetcher.py
, the model_name
parameter is used directly to construct file paths without validation.src/live_stream_detection.py
, the output_folder
and model_key
parameters are used in path expressions without proper validation.Here are the implementation details and code snippets to fix the issues:
import re
from urllib.parse import urlparse
import argparse
import gc
import cv2
import time
class StreamCapture:
def __init__(self, stream_url: str, capture_interval: int = 15):
self.stream_url = stream_url
self.cap: cv2.VideoCapture | None = None
self.capture_interval = capture_interval
def initialise_stream(self, stream_url: str) -> None:
self.cap = cv2.VideoCapture(stream_url)
self.cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
self.cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'H264'))
if not self.cap.isOpened():
time.sleep(5)
self.cap.open(stream_url)
def execute_capture(self):
# Implementation of frame capture logic
pass
def is_valid_url(url: str) -> bool:
parsed_url = urlparse(url)
return all([parsed_url.scheme, parsed_url.netloc])
def sanitize_url(url: str) -> str:
url = re.sub(r'[^\w\-/:.?&=]', '', url)
return url
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Capture video stream frames.')
parser.add_argument('--url', type=str, help='Live stream URL', required=True)
args = parser.parse_args()
sanitized_url = sanitize_url(args.url)
if not is_valid_url(sanitized_url):
raise ValueError("Invalid URL provided")
stream_capture = StreamCapture(sanitized_url)
for frame, timestamp in stream_capture.execute_capture():
print(f"Frame at {timestamp} displayed")
del frame
gc.collect()
model_name
parameter to prevent path traversal.from pathlib import Path
import requests
import re
class ModelInfo(TypedDict):
model_name: str
url: str
def sanitize_model_name(model_name: str) -> str:
if not re.match(r'^[\w\-]+$', model_name):
raise ValueError(f"Invalid model name: {model_name}")
return model_name
def download_model(model_name, url):
model_name = sanitize_model_name(model_name)
LOCAL_MODEL_DIRECTORY = Path('models/pt/')
LOCAL_MODEL_DIRECTORY.mkdir(parents=True, exist_ok=True)
local_file_path = LOCAL_MODEL_DIRECTORY / model_name
if local_file_path.exists():
print(f"'{model_name}' exists. Skipping download.")
return
response = requests.get(url, stream=True)
if response.status_code == 200:
with open(local_file_path, 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
print(f"'{model_name}' saved to '{local_file_path}'.")
else:
print(f"Error downloading '{model_name}': {response.status_code}")
def main():
MODEL_URLS = {
'best_yolov8l.pt': 'http://changdar-server.mooo.com:28000/models/best_yolov8l.pt',
'best_yolov8x.pt': 'http://changdar-server.mooo.com:28000/models/best_yolov8x.pt',
}
for model_name, url in MODEL_URLS.items():
download_model(model_name, url)
if __name__ == '__main__':
main()
output_folder
and model_key
parameters.stream_url
parameter.import os
import argparse
import cv2
from pathlib import Path
import re
from urllib.parse import urlparse
class LiveStreamDetector:
def __init__(self, api_url: str = 'http://localhost:5000', model_key: str = 'yolov8l', output_folder: str | None = None, run_local: bool = True):
self.api_url = api_url
self.model_key = self.sanitize_model_key(model_key)
self.output_folder = self.sanitize_output_folder(output_folder)
self.run_local = run_local
def sanitize_output_folder(self, output_folder: str) -> str:
if output_folder:
output_folder = os.path.abspath(output_folder)
if not output_folder.startswith(os.getcwd()):
raise ValueError("Invalid output folder path")
return output_folder
def sanitize_model_key(self, model_key: str) -> str:
if not re.match(r'^[\w\-]+$', model_key):
raise ValueError(f"Invalid model key: {model_key}")
return model_key
def generate_detections_local(self, frame: cv2.Mat) -> list[list[float]]:
model_path = Path('models/pt/') / f"best_{self.model_key}.pt"
# Implementation of detection logic
pass
def run_detection(self, stream_url: str) -> None:
if not self.is_valid_url(stream_url):
raise ValueError("Invalid stream URL")
cap = cv2.VideoCapture(stream_url)
# Implementation of detection logic
pass
def is_valid_url(self, url: str) -> bool:
parsed_url = urlparse(url)
return all([parsed_url.scheme, parsed_url.netloc])
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Perform live stream detection and tracking using YOLOv8.')
parser.add_argument('--url', type=str, help='Live stream URL', required=True)
parser.add_argument('--api_url', type=str, default='http://localhost:5000', help='API URL for detection')
parser.add_argument('--model_key', type=str, default='yolov8n', help='Model key for detection')
parser.add_argument('--output_folder', type=str, help='Output folder for detected frames')
parser.add_argument('--run_local', action='store_true', help='Run detection using local model')
args = parser.parse_args()
detector = LiveStreamDetector(api_url=args.api_url, model_key=args.model_key, output_folder=args.output_folder, run_local=args.run_local)
detector.run_detection(args.url)
For src/stream_capture.py
:
python src/stream_capture.py --url "http://example.com/../../etc/passwd"
For src/model_fetcher.py
:
MODEL_URLS
to include a key like ../etc/passwd
.For src/live_stream_detection.py
:
--output_folder
and --model_key
.python src/live_stream_detection.py --url "http://example.com" --output_folder "../../etc" --model_key "../etc/passwd"
By implementing the recommended changes, these vulnerabilities will be mitigated, ensuring that user inputs are properly validated and sanitized.
Click here to create a Pull Request with the proposed solution
Files used for this task:
Tracking issue for: