-
Notifications
You must be signed in to change notification settings - Fork 244
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
-r Recursive option #129
-r Recursive option #129
Changes from 19 commits
2ebe595
ef3a21d
38be6e2
759f632
ed38dbb
fcf4638
3ac883c
e246104
2cbac72
7875c82
ca0b2d7
d9db9dd
c35ae81
9c54d8c
40c0f8f
42759f0
5931faf
5546c3d
8d1d805
35b8001
2e4d07a
0c6b082
ae84a44
1944b4a
ba3d438
6a25e25
f42d283
c7b2f73
2afc177
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,7 +30,25 @@ | |
) | ||
|
||
|
||
def main(command_line_args=sys.argv[1:]): # noqa: C901 | ||
def discover_files(targets, excluded_files, recursive=False): | ||
included_files = list() | ||
excluded_list = excluded_files.split(",") | ||
|
||
for target in targets: | ||
if os.path.isdir(target): | ||
if recursive: | ||
for root, dirs, files in os.walk(target): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this line, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i will try to do better for returning "included_files" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: You can de-dent from line |
||
for f in files: | ||
fullpath = os.path.join(root, f) | ||
if os.path.splitext(fullpath)[1] == '.py' and fullpath.split("/")[-1] not in excluded_list: | ||
included_files.append(fullpath) | ||
else: | ||
if target not in excluded_list: | ||
included_files.append(targets[0]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So if targets is a list of files, e.g. |
||
return included_files | ||
|
||
|
||
def main(command_line_args=sys.argv[1:]): | ||
args = parse_args(command_line_args) | ||
|
||
ui_mode = UImode.NORMAL | ||
|
@@ -39,66 +57,74 @@ def main(command_line_args=sys.argv[1:]): # noqa: C901 | |
elif args.trim_reassigned_in: | ||
ui_mode = UImode.TRIM | ||
|
||
path = os.path.normpath(args.filepath) | ||
files = discover_files( | ||
args.targets, | ||
args.excluded_paths, | ||
args.recursive | ||
) | ||
vulnerabilities = list() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, That's odd, I'll checkout/test your code later today to try and find the issue. 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's really weird, I'll look more in-depth on Monday 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I checked out your branch and it was |
||
for path in files: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Before this vulnerabilities.append(find_vulnerabilities(
cfg_list,
ui_mode,
args.blackbox_mapping_file,
args.trigger_word_file,
nosec_lines
)) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it find vulnerabilities in all the files, or just the last file (i.e. last iteration of the loop)? If I'm reading it write I think it might do e.g. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (As an aside, it seems strange it's not printing out the vulnerability info, and just seems to print the object.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right, it taking last item on the list. have you idea for fix? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the fix is having a list outside of the for loop and adding the vulnerabilities of each file to it. The code from my first comment should do it, although now that I think about it it's probably extend and not append. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ^Ahh, this was it! 👍 Just change |
||
print(path) | ||
if args.ignore_nosec: | ||
nosec_lines = set() | ||
else: | ||
file = open(path, 'r') | ||
lines = file.readlines() | ||
nosec_lines = set( | ||
lineno for | ||
(lineno, line) in enumerate(lines, start=1) | ||
if '#nosec' in line or '# nosec' in line | ||
) | ||
|
||
if args.ignore_nosec: | ||
nosec_lines = set() | ||
else: | ||
file = open(path, 'r') | ||
lines = file.readlines() | ||
nosec_lines = set( | ||
lineno for | ||
(lineno, line) in enumerate(lines, start=1) | ||
if '#nosec' in line or '# nosec' in line | ||
) | ||
if args.project_root: | ||
directory = os.path.normpath(args.project_root) | ||
else: | ||
directory = os.path.dirname(path) | ||
project_modules = get_modules(directory) | ||
local_modules = get_directory_modules(directory) | ||
tree = generate_ast(path) | ||
|
||
if args.project_root: | ||
directory = os.path.normpath(args.project_root) | ||
else: | ||
directory = os.path.dirname(path) | ||
project_modules = get_modules(directory) | ||
local_modules = get_directory_modules(directory) | ||
cfg = make_cfg( | ||
tree, | ||
project_modules, | ||
local_modules, | ||
path | ||
) | ||
cfg_list = [cfg] | ||
|
||
tree = generate_ast(path) | ||
|
||
cfg = make_cfg( | ||
tree, | ||
project_modules, | ||
local_modules, | ||
path | ||
) | ||
cfg_list = [cfg] | ||
framework_route_criteria = is_flask_route_function | ||
if args.adaptor: | ||
if args.adaptor.lower().startswith('e'): | ||
framework_route_criteria = is_function | ||
elif args.adaptor.lower().startswith('p'): | ||
framework_route_criteria = is_function_without_leading_ | ||
elif args.adaptor.lower().startswith('d'): | ||
framework_route_criteria = is_django_view_function | ||
# Add all the route functions to the cfg_list | ||
FrameworkAdaptor( | ||
cfg_list, | ||
project_modules, | ||
local_modules, | ||
framework_route_criteria | ||
) | ||
framework_route_criteria = is_flask_route_function | ||
if args.adaptor: | ||
if args.adaptor.lower().startswith('e'): | ||
framework_route_criteria = is_function | ||
elif args.adaptor.lower().startswith('p'): | ||
framework_route_criteria = is_function_without_leading_ | ||
elif args.adaptor.lower().startswith('d'): | ||
framework_route_criteria = is_django_view_function | ||
# Add all the route functions to the cfg_list | ||
FrameworkAdaptor( | ||
cfg_list, | ||
project_modules, | ||
local_modules, | ||
framework_route_criteria | ||
) | ||
|
||
initialize_constraint_table(cfg_list) | ||
analyse(cfg_list) | ||
vulnerabilities = find_vulnerabilities( | ||
cfg_list, | ||
ui_mode, | ||
args.blackbox_mapping_file, | ||
args.trigger_word_file, | ||
nosec_lines | ||
) | ||
initialize_constraint_table(cfg_list) | ||
analyse(cfg_list) | ||
vulnerabilities.extend(find_vulnerabilities( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Look good to you? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, there are no vulnerability in a.py b.py and c.py but it printing from xss.py There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't figure out the bug yet, gonna look more tomorrow 😁 This is harder than expected to track down There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok, i fixed it. its about |
||
cfg_list, | ||
ui_mode, | ||
args.blackbox_mapping_file, | ||
args.trigger_word_file, | ||
nosec_lines | ||
)) | ||
|
||
if args.baseline: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can keep this, but just de-dent it so that we only trim once. |
||
vulnerabilities = get_vulnerabilities_not_in_baseline( | ||
vulnerabilities, | ||
args.baseline | ||
) | ||
vulnerabilities = get_vulnerabilities_not_in_baseline( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for de-denting the |
||
vulnerabilities, | ||
args.baseline | ||
) | ||
|
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: You can delete this newline |
||
if args.json: | ||
json.report(vulnerabilities, args.output_file) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,9 +30,8 @@ def valid_date(s): | |
def _add_required_group(parser): | ||
required_group = parser.add_argument_group('required arguments') | ||
required_group.add_argument( | ||
'-f', '--filepath', | ||
help='Path to the file that should be analysed.', | ||
type=str | ||
'targets', metavar='targets', type=str, nargs='*', | ||
help='source file(s) or directory(s) to be tested' | ||
) | ||
|
||
|
||
|
@@ -91,6 +90,17 @@ def _add_optional_group(parser): | |
action='store_true', | ||
help='do not skip lines with # nosec comments' | ||
) | ||
optional_group.add_argument( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe make it
|
||
'-r', '--recursive', dest='recursive', | ||
action='store_true', help='find and process files in subdirectories' | ||
) | ||
optional_group.add_argument( | ||
'-x', '--exclude', | ||
dest='excluded_paths', | ||
action='store', | ||
default='', | ||
help='Separate files with commas' | ||
) | ||
|
||
|
||
def _add_print_group(parser): | ||
|
@@ -110,8 +120,8 @@ def _add_print_group(parser): | |
|
||
|
||
def _check_required_and_mutually_exclusive_args(parser, args): | ||
if args.filepath is None: | ||
parser.error('The -f/--filepath argument is required') | ||
if args.targets is None: | ||
parser.error('The targets argument is required') | ||
|
||
|
||
def parse_args(args): | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,14 +25,14 @@ def test_no_args(self): | |
|
||
self.maxDiff = None | ||
|
||
EXPECTED = """usage: python -m pyt [-h] [-f FILEPATH] [-a ADAPTOR] [-pr PROJECT_ROOT] | ||
EXPECTED = """usage: python -m pyt [-h] [-a ADAPTOR] [-pr PROJECT_ROOT] | ||
[-b BASELINE_JSON_FILE] [-j] [-m BLACKBOX_MAPPING_FILE] | ||
[-t TRIGGER_WORD_FILE] [-o OUTPUT_FILE] [--ignore-nosec] | ||
[-trim] [-i] | ||
[-r] [-x EXCLUDED_PATHS] [-trim] [-i] | ||
[targets [targets ...]] | ||
|
||
required arguments: | ||
-f FILEPATH, --filepath FILEPATH | ||
Path to the file that should be analysed. | ||
targets source file(s) or directory(s) to be tested | ||
|
||
optional arguments: | ||
-a ADAPTOR, --adaptor ADAPTOR | ||
|
@@ -52,6 +52,9 @@ def test_no_args(self): | |
-o OUTPUT_FILE, --output OUTPUT_FILE | ||
write report to filename | ||
--ignore-nosec do not skip lines with # nosec comments | ||
-r, --recursive find and process files in subdirectories | ||
-x EXCLUDED_PATHS, --exclude EXCLUDED_PATHS | ||
Separate files with commas | ||
|
||
print arguments: | ||
-trim, --trim-reassigned-in | ||
|
@@ -62,7 +65,7 @@ def test_no_args(self): | |
|
||
self.assertEqual(stdout.getvalue(), EXPECTED) | ||
|
||
def test_valid_args_but_no_filepath(self): | ||
'''def test_valid_args_but_no_filepath(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. filepath option removed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 You can change this to match something along the lines of |
||
with self.assertRaises(SystemExit): | ||
with capture_sys_output() as (_, stderr): | ||
parse_args(['-j']) | ||
|
@@ -73,7 +76,7 @@ def test_valid_args_but_no_filepath(self): | |
[-trim] [-i] | ||
python -m pyt: error: The -f/--filepath argument is required\n""" | ||
|
||
self.assertEqual(stderr.getvalue(), EXPECTED) | ||
self.assertEqual(stderr.getvalue(), EXPECTED)''' | ||
|
||
# def test_using_both_mutually_exclusive_args(self): | ||
# with self.assertRaises(SystemExit): | ||
|
@@ -89,7 +92,7 @@ def test_valid_args_but_no_filepath(self): | |
|
||
def test_normal_usage(self): | ||
with capture_sys_output() as (stdout, stderr): | ||
parse_args(['-f', 'foo.py']) | ||
parse_args(['foo.py']) | ||
|
||
self.assertEqual(stdout.getvalue(), '') | ||
self.assertEqual(stderr.getvalue(), '') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So having
if recursive:
here it will make it so that if you don't have-r
then you won't search directories.You can change it to: