Skip to content

Commit

Permalink
added security checklist endpoint (#25)
Browse files Browse the repository at this point in the history
* added security checklist endpoint

* fixing linting and testing errors

* adding docs for security-checklist command

* REST api fixed to use results instead of items as the main key returned

* bumped version number, moved toml from dependency to dev-dependency, updated policy check documentation
  • Loading branch information
eacmen authored Jun 17, 2020
1 parent b72a553 commit 4b28bc8
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 17 deletions.
6 changes: 6 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ Get SBOM Results:
$ centrifuge report --ufid=<REPORT_ID> sbom
Get Security Checklist Results:

.. code-block:: bash
$ centrifuge report --ufid=<REPORT_ID> security-checklist
The code analysis section is a little bit more complicated, since the data is
more structured. To understand how to access this data you need to understand
that when we process a firmware we must extract it first, each time we extract a
Expand Down
2 changes: 1 addition & 1 deletion centrifuge_cli/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.5.0'
__version__ = '0.6.0'
10 changes: 10 additions & 0 deletions centrifuge_cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,14 @@ def binary_hardening(cli):
return(result)


@report.command(name='security-checklist')
@pass_cli
def security_checklist(cli):
result = cli.do_GET(f'/api/report/SecurityChecklist/{cli.ufid}', paginated=False)
cli.echo(result)
return(result)


@report.command(name='check-policy')
@click.option('--policy-yaml', metavar='FILE', type=click.Path(), help='Centrifuge policy yaml file.', required=True)
@click.option('--report-template', metavar='FILE', type=click.Path(), help='Policy report template file.', required=False)
Expand All @@ -407,6 +415,7 @@ def check_policy(cli, ctx, policy_yaml, report_template):
guardian_json = json.loads(ctx.invoke(guardian))
code_summary_json = json.loads(ctx.invoke(code_summary))
passhash_json = json.loads(ctx.invoke(passhash))
checklist_json = json.loads(ctx.invoke(security_checklist))
info_json = json.loads(ctx.invoke(info))

policy_obj = CentrifugePolicyCheck(certificates_json,
Expand All @@ -415,6 +424,7 @@ def check_policy(cli, ctx, policy_yaml, report_template):
guardian_json,
code_summary_json,
passhash_json,
checklist_json,
info_json)

policy_obj.check_rules(policy_yaml)
Expand Down
31 changes: 28 additions & 3 deletions centrifuge_cli/policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@
"method": "checkBinaryHardeningRule",
"status": "Fail",
"reasons": []
},
"securityChecklist": {
"name": "Security Checklist",
"method": "checkSecurityChecklistRule",
"status": "Fail",
"reasons": []
}
}
POLICIES = [
Expand All @@ -56,7 +62,8 @@
'passwordHashes',
'code',
'guardian',
'binaryHardening'
'binaryHardening',
'securityChecklist'
]


Expand All @@ -71,15 +78,18 @@ def __init__(self,
guardian_json,
code_summary_json,
passhash_json,
info_json):
checklist_json,
info_json,
verbose=False):
self.certificates_json = certificates_json
self.private_keys_json = private_keys_json
self.binary_hardening_json = binary_hardening_json
self.guardian_json = guardian_json
self.code_summary_json = code_summary_json
self.passhash_json = passhash_json
self.checklist_json = checklist_json
self.info_json = info_json
self.verbose = False # set to True to generate debug logging
self.verbose = verbose

def verboseprint(self, *args):
"""
Expand All @@ -101,6 +111,21 @@ def match_regex_against_path(self, exception_regex, path_list):
exceptions_in_path = exceptions_in_path + exceptions
return exceptions_in_path

def checkSecurityChecklistRule(self, value):
if not value.get('allowed'):
json_data = self.checklist_json
passing = json_data['summary']['passing']
total = json_data['summary']['total']
if (total - passing) > 0:
reasons = []
for result in json_data['results']:
if result['statusCode'] == 1:
name = result['Analyzer']['name']
reasons.append(f'{name} was found during Security Checklist scan')
return False, reasons

return True, []

def checkCertificateRule(self, value):
self.verboseprint("Checking Certificate Rule...")
rule_passed = True
Expand Down
16 changes: 13 additions & 3 deletions docs/POLICY.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Tested on Linux with python 3.7
pip3 install centrifuge-cli
```

## Using centrifuge-policy-check.py
## Using Centrifuge Policy Check

```
# Command options:
Expand Down Expand Up @@ -49,7 +49,7 @@ policyVersion: 1.0
rules: {}
```

Current policy schema version: `1.0`
Current policy schema version: `1.1`

Refer to example rule definition files included in this repository for more examples.

Expand Down Expand Up @@ -174,4 +174,14 @@ In order to limit this check to a certain list of files, use the `include` modif
include:
- /opt/vendor/*
- /root/*
```

### Rule: Security Checklist

Firmware images can contain pre existing known threats such as backdoors, malware or known exploits. Security
checklist looks for these direct indicators of compromise. We recommend all policies not allow for any Security
Checklist results.
```
securityChecklist:
allowed: false
```
4 changes: 3 additions & 1 deletion docs/example-policy-lenient.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
policyVersion: 1.0
policyVersion: 1.1
rules:
certificates:
expired:
Expand All @@ -13,3 +13,5 @@ rules:
allowed: true
guardian:
cvssScoreThreshold: 9.0
securityChecklist:
allowed: true
4 changes: 3 additions & 1 deletion docs/example-policy-simple.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
policyVersion: 1.0
policyVersion: 1.1
rules:
certificates:
expired:
Expand All @@ -15,3 +15,5 @@ rules:
binaryHardening:
requiredFeatures: [NX, PIE, STRIPPED]
include: [/opt/vendor/bin/*, /usr/lib/*]
securityChecklist:
allowed: false
4 changes: 4 additions & 0 deletions docs/example-policy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,7 @@ rules:
- /lib/modules/*
- /opt/vendor/*
- /root/*

securityChecklist:
# any security checklist results should result in failure in most policies
allowed: false
23 changes: 17 additions & 6 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "centrifuge-cli"
version = "0.5.0"
version = "0.6.0"
description = "A command line utility for interacting with the Centrifuge Firmware Analysis Platform's REST API."
authors = ["Peter Eacmen <[email protected]>"]
readme = 'README.rst'
Expand All @@ -16,12 +16,12 @@ requests = "^2.22"
Click = "^7.0"
pandas = "^0.25.1"
dateparser = "^0.7.2"
toml = "^0.10.0"
pyyaml = "^5.3.1"
chevron = "^0.13.1"

[tool.poetry.dev-dependencies]
pytest = "^3.0"
toml = "^0.10.1"

[tool.poetry.scripts]
centrifuge = "centrifuge_cli.main:cli"
Expand Down

0 comments on commit 4b28bc8

Please sign in to comment.