From 171fabc2f5a74197ef371e8e06f4b447a3bcad87 Mon Sep 17 00:00:00 2001 From: Yogesh Ojha Date: Wed, 1 Sep 2021 22:52:01 +0530 Subject: [PATCH] Fixed Directory Traversal while fetching Nuclei templates, reported by @k0enm on huntr! --- web/api/views.py | 28 ++++++++++++++++++++-------- web/reNgine/common_func.py | 10 ++++++++++ 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/web/api/views.py b/web/api/views.py index 585fc5e70..d2de14026 100644 --- a/web/api/views.py +++ b/web/api/views.py @@ -18,6 +18,8 @@ from targetApp.models import * from recon_note.models import * +from reNgine.common_func import is_safe_path + class VulnerabilityReport(APIView): def get(self, request): req = self.request @@ -30,29 +32,39 @@ def get(self, request, format=None): name = req.query_params.get('name') if 'nuclei_config' in req.query_params: - f = open("/root/.config/nuclei/config.yaml".format(name), "r") + f = open("/root/.config/nuclei/config.yaml", "r") return Response({'content': f.read()}) if 'subfinder_config' in req.query_params: - f = open("/root/.config/subfinder/config.yaml".format(name), "r") + f = open("/root/.config/subfinder/config.yaml", "r") return Response({'content': f.read()}) if 'naabu_config' in req.query_params: - f = open("/root/.config/naabu/naabu.conf".format(name), "r") + f = open("/root/.config/naabu/naabu.conf", "r") return Response({'content': f.read()}) if 'amass_config' in req.query_params: - f = open("/root/.config/amass.ini".format(name), "r") + f = open("/root/.config/amass.ini", "r") return Response({'content': f.read()}) if 'gf_pattern' in req.query_params: - f = open("/root/.gf/{}.json".format(name), "r") - return Response({'content': f.read()}) + basedir = '/root/.gf' + path = '/root/.gf/{}.json'.format(name) + if is_safe_path(basedir, path): + content = open(path, "r") + else: + content = "Invalid path!" + return Response({'content': content}) if 'nuclei_template' in req.query_params: - f = open("/root/nuclei-templates/{}".format(name), "r") - return Response({'content': f.read()}) + safe_dir = '/root/nuclei-templates' + path = '/root/nuclei-templates/{}'.format(name) + if is_safe_path(safe_dir, path): + content = open(path.format(name), "r") + else: + content = 'Invalid Path!' + return Response({'content': content}) return Response({'content': "ping-pong"}) diff --git a/web/reNgine/common_func.py b/web/reNgine/common_func.py index 0d043e3e6..aaa57688d 100644 --- a/web/reNgine/common_func.py +++ b/web/reNgine/common_func.py @@ -282,3 +282,13 @@ def send_hackerone_report(vulnerability_id): status_code = 111 return status_code + + +def is_safe_path(basedir, path, follow_symlinks=True): + # Source: https://security.openstack.org/guidelines/dg_using-file-paths.html + # resolves symbolic links + if follow_symlinks: + matchpath = os.path.realpath(path) + else: + matchpath = os.path.abspath(path) + return basedir == os.path.commonpath((basedir, matchpath))