Skip to content

Commit 9275864

Browse files
authored
Added --minimize option to scan command to reduce report size (#126)
* Fixes #125 by adding --minimize option to the scan command * Make the example report match the most recent version * Make pylint happy * Fix minimize
1 parent fe84e38 commit 9275864

File tree

11 files changed

+624
-5891
lines changed

11 files changed

+624
-5891
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ iam-report-fake-000011112222.html
2121
iam-triage-fake-000011112222.csv
2222
#index.html
2323
iam-triage-fake.csv
24-
iam-results-example.json
24+
/iam-results-example.json
2525
iam-triage-example.csv
2626
iam-report-example.html
2727
iam-report-fake.html

CHANGELOG.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@
33
## Unreleased
44
* Docker
55

6-
## 0.2.3 (Unreleased)
6+
## 0.2.4 (Unreleased)
77
* UI
8-
* Credentials Exposure as a new finding (`#99`)
9-
* Service Wildcard as a new finding (`#82`)
108
* Inline Explanation of findings (`#115`)
119
* Better formatting for Privilege Escalation findings (`#114`)
1210
* Exclusions config is in its own tab in the UI (`#107`)
11+
12+
## 0.2.3 (2020-10-12)
13+
* `scan` command now has a `--minimize` option, which you can use to reduce your report size. The example report size was reduced from 3.9MB (ouch!) to 212KB. (Fixes #125)
14+
* UI
15+
* Credentials Exposure as a new finding (`#99`)
16+
* Service Wildcard as a new finding (`#82`)
1317
* Backend
1418
* Updated tests to include updated sample data
1519

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ It will create an HTML report like [this](https://opensource.salesforce.com/clou
195195

196196
It will also create a raw JSON data file:
197197

198-
* `default-iam-results.json`: This contains the raw JSON output of the report. You can use this data file for operating on the scan results for various purposes. For example, you could write a Python script that parses this data and opens up automated JIRA issues or Salesforce Work Items. An example entry is shown below. The full example can be viewed at [examples/output/example-authz-details-results.json](examples/files/iam-results-example.json)
198+
* `default-iam-results.json`: This contains the raw JSON output of the report. You can use this data file for operating on the scan results for various purposes. For example, you could write a Python script that parses this data and opens up automated JIRA issues or Salesforce Work Items. An example entry is shown below. The full example can be viewed at [examples/files/iam-results-example.json](examples/files/iam-results-example.json)
199199

200200
```json
201201
{

cloudsplaining/bin/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# pylint: disable=missing-module-docstring
2-
__version__ = "0.2.2"
2+
__version__ = "0.2.3"

cloudsplaining/command/scan.py

+15-4
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,17 @@
5858
help="Don't open the HTML report in the web browser after creating. "
5959
"This helps when running the report in automation.",
6060
)
61+
@click.option(
62+
"--minimize",
63+
required=False,
64+
default=False,
65+
is_flag=True,
66+
help="Reduce the size of the HTML Report by pulling the Cloudsplaining Javascript code over the internet."
67+
)
6168
@click_log.simple_verbosity_option()
6269
# pylint: disable=redefined-builtin
6370
def scan(
64-
input_file, exclusions_file, output, skip_open_report
71+
input_file, exclusions_file, output, skip_open_report, minimize
6572
): # pragma: no cover
6673
"""
6774
Given the path to account authorization details files and the exclusions config file, scan all inline and
@@ -84,7 +91,8 @@ def scan(
8491
contents = f.read()
8592
account_authorization_details_cfg = json.loads(contents)
8693
rendered_html_report = scan_account_authorization_details(
87-
account_authorization_details_cfg, exclusions, account_name, output, write_data_files=True
94+
account_authorization_details_cfg, exclusions, account_name, output, write_data_files=True,
95+
minimize=minimize
8896
)
8997
html_output_file = os.path.join(output, f"iam-report-{account_name}.html")
9098
logger.info("Saving the report to %s", html_output_file)
@@ -116,7 +124,8 @@ def scan(
116124
account_name = Path(file).stem
117125
# Scan the Account Authorization Details config
118126
rendered_html_report = scan_account_authorization_details(
119-
account_authorization_details_cfg, exclusions, account_name, output, write_data_files=True
127+
account_authorization_details_cfg, exclusions, account_name, output, write_data_files=True,
128+
minimize=minimize
120129
)
121130
html_output_file = os.path.join(output, f"iam-report-{account_name}.html")
122131
logger.info("Saving the report to %s", html_output_file)
@@ -136,7 +145,8 @@ def scan(
136145

137146

138147
def scan_account_authorization_details(
139-
account_authorization_details_cfg, exclusions, account_name="default", output_directory=os.getcwd(), write_data_files=False
148+
account_authorization_details_cfg, exclusions, account_name="default", output_directory=os.getcwd(),
149+
write_data_files=False, minimize=False
140150
): # pragma: no cover
141151
"""
142152
Given the path to account authorization details files and the exclusions config file, scan all inline and
@@ -162,6 +172,7 @@ def scan_account_authorization_details(
162172
account_id=account_id,
163173
account_name=account_name,
164174
results=results,
175+
minimize=minimize
165176
)
166177
rendered_report = html_report.get_html_report()
167178

cloudsplaining/output/report.py

+32-7
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,42 @@
1010

1111
class HTMLReport:
1212
"""Inject the JS files and report results into the final HTML report"""
13-
def __init__(self, account_id, account_name, results):
13+
def __init__(self, account_id, account_name, results, minimize=False):
1414
self.account_name = account_name
1515
self.account_id = account_id
1616
self.report_generated_time = datetime.datetime.now().strftime("%Y-%m-%d")
17-
17+
self.minimize = minimize
1818
self.results = f"var iam_data = {json.dumps(results)}"
19-
with open(app_bundle_path, "r") as f:
20-
self.app_bundle = f.read()
21-
vendor_bundle_path = get_vendor_bundle_path()
22-
with open(vendor_bundle_path, "r") as f:
23-
self.vendor_bundle = f.read()
19+
20+
@property
21+
def app_bundle(self):
22+
"""The Cloudsplaining Javascript application code should be loaded either from the CDN or locally,
23+
depending on if the user specified the --minimize option"""
24+
if self.minimize:
25+
js_url = f"https://cdn.jsdelivr.net/gh/salesforce/cloudsplaining@{__version__}/cloudsplaining/output/dist/js/index.js"
26+
bundle = f"<script type=\"text/javascript\" src=\"{js_url}\"></script>"
27+
return bundle
28+
else:
29+
with open(app_bundle_path, "r") as f:
30+
bundle_content = f.read()
31+
bundle = f"<script type=\"text/javascript\">\n{bundle_content}\n</script>"
32+
return bundle
33+
34+
@property
35+
def vendor_bundle(self):
36+
"""The Javascript vendor bundle should be loaded either from the CDN or locally,
37+
depending on if the user specified the --minimize option"""
38+
39+
if self.minimize:
40+
js_url = f"https://cdn.jsdelivr.net/gh/salesforce/cloudsplaining@{__version__}/cloudsplaining/output/dist/js/chunk-vendors.js"
41+
bundle = f"<script type=\"text/javascript\" src=\"{js_url}\"></script>"
42+
return bundle
43+
else:
44+
vendor_bundle_path = get_vendor_bundle_path()
45+
with open(vendor_bundle_path, "r") as f:
46+
bundle_content = f.read()
47+
bundle = f"<script type=\"text/javascript\">\n{bundle_content}\n</script>"
48+
return bundle
2449

2550
def get_html_report(self):
2651
"""Returns the rendered HTML report"""

cloudsplaining/output/template.html

+5-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<head>
44
<meta charset="utf-8">
55
<meta content="IE=edge" http-equiv="X-UA-Compatible">
6+
<meta http-equiv="X-Content-Type-Options" content="nosniff"/>
67
<meta content="width=device-width,initial-scale=1.0" name="viewport">
78
<title>Cloudsplaining report</title>
89
<!-- Load required Bootstrap and BootstrapVue CSS -->
@@ -43,12 +44,10 @@
4344
console.log(`iam data keys: ${Object.keys(iam_data)}`);
4445

4546
</script>
46-
<script>
47-
{{ t.vendor_bundle_js }}
48-
</script>
49-
<script>
50-
{{ t.app_bundle_js }}
51-
</script>
47+
48+
{{ t.vendor_bundle_js }}
49+
50+
{{ t.app_bundle_js }}
5251

5352
</body>
5453
<!-- Bootstrap-->

examples/files/iam-report-example.html

+8-339
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)