Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Open Source
Browse files Browse the repository at this point in the history
  • Loading branch information
adeptex committed Apr 29, 2019
0 parents commit 4b41369
Show file tree
Hide file tree
Showing 58 changed files with 3,232 additions and 0 deletions.
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
*.aws
*.DS_Store
*.vscode
venv
*__pycache__
*cache*
*.pytest_cache
*.pypirc
*.egg-info
dev
lambdaguard_output*
build
dist
29 changes: 29 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Contributing to lambdaguard
We're glad you want to make a contribution!

Fork this repository and send in a pull request when you're finished with your changes. Link any relevant issues in too.

Take note of the build status of your pull request, only builds that pass will be accepted. Please also keep to our conventions and style so we can keep this repository as clean as possible.

## License
By contributing your code, you agree to license your contribution under the terms of the APLv2:
https://github.com/Skyscanner/sonar-secrets/blob/master/LICENSE

All files are released with the Apache 2.0 license.

If you are adding a new file it should have a header like this:
```
/**
* Copyright 2019 Skyscanner Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * limitations under the License.
*/
```
7 changes: 7 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Copyright [2019] Skyscanner Ltd

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
recursive-include lambdaguard *.html *.css *.png *.js
include lambdaguard/version.txt
41 changes: 41 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
install:
python3 setup.py install

test:
python3 -m pytest -W ignore

dev:
python3 -m venv dev
echo "\nNow run: \n\n. dev/bin/activate\n"

install-dev:
python3 setup.py develop
pip3 install pytest

clean:
set -e
find . -iname "dist" -exec rm -rf {} \;
find . -iname "build" -exec rm -rf {} \;
find . -iname "dev" -exec rm -rf {} \;
find . -iname "*.DS_Store*" -exec rm -rf {} \;
find . -iname "*__pycache__*" -exec rm -rf {} \;
find . -iname "*.pytest_cache*" -exec rm -rf {} \;
find . -iname "lambdaguard.egg-info" -exec rm -rf {} \;
find . -iname "lambdaguard_output" -exec rm -rf {} \;
python3 setup.py clean
sudo pip3 uninstall lambdaguard

dist:
rm -rf dist
python3 setup.py sdist bdist_wheel
python3 -m twine upload dist/*

test-pip:
python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps lambdaguard

sonarqube:
docker build -t sonarqube -f SonarQube.Dockerfile .
docker run -d -p 9000:9000 sonarqube
python3 sonarqube-setup.py

.PHONY: clean dist
61 changes: 61 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# LambdaGuard <img src="lambdaguard/assets/logo.png" width="40px" alt="LambdaGuard" style="">

AWS Lambda is an event-driven, serverless computing platform provided by Amazon Web Services. It is a computing service that runs code in response to events and automatically manages the computing resources required by that code.

LambdaGuard is an AWS Lambda auditing tool designed to create asset visibility and provide actionable results. It provides a meaningful overview in terms of statistical analysis, AWS service dependencies and configuration checks from the security perspective.

## Requirements
- Python 3.6.3+
- Java 8+ (optional for SonarQube)

## Install

### From PyPI
```
pip3 install lambdaguard
```

### From Github
```
git clone https://github.com/Skyscanner/lambdaguard
cd lambdaguard
sudo make install
```

## Run
- `lambdaguard --help`
- `lambdaguard --function arn:aws:lambda:function`
- `lambdaguard --input function-arns.txt`
- `lambdaguard --output /tmp/lambdaguard`
- `lambdaguard --profile aws-profile`
- `lambdaguard --keys ACCESS_KEY_ID SECRET_ACCESS_KEY`
- `lambdaguard --region eu-west-1`
- `lambdaguard --verbose`

## SonarQube: Static Code Analysis

### Build SonarQube
- `make sonarqube`

### Use SonarQube
- `lambdaguard --sonarqube config.json`

Config should have the following format:

```json
{
"command": "java -jar /opt/sonar-scanner-cli.jar -X",
"url": "http://localhost:9000",
"login": "admin",
"password": "admin"
}
```

## Development
```
make -i clean
make dev
. dev/bin/activate
make install-dev
make test
```
39 changes: 39 additions & 0 deletions SonarQube.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
FROM sonarqube:6.7.5

# Remove bundled plugins
RUN ls -la $SONARQUBE_HOME/lib/bundled-plugins && \
rm -rf $SONARQUBE_HOME/lib/bundled-plugins/sonar-java-plugin-*.jar

# Install plugins
ENV SONAR_JAVA_PLUGIN_VERSION 5.9.2.16552
RUN curl --fail --silent --show-error --location --output $SONARQUBE_HOME/extensions/plugins/sonar-java-plugin-${SONAR_JAVA_PLUGIN_VERSION}.jar \
https://binaries.sonarsource.com/Distribution/sonar-java-plugin/sonar-java-plugin-${SONAR_JAVA_PLUGIN_VERSION}.jar

ENV SONAR_JAVASCRIPT_PLUGIN_VERSION 5.1.1.7506
RUN cd $SONARQUBE_HOME/extensions/plugins && \
curl --fail --silent --show-error --location --output sonar-javascript-plugin-${SONAR_JAVASCRIPT_PLUGIN_VERSION}.jar \
https://binaries.sonarsource.com/Distribution/sonar-javascript-plugin/sonar-javascript-plugin-${SONAR_JAVASCRIPT_PLUGIN_VERSION}.jar

ENV SONAR_PYTHON_PLUGIN_VERSION 1.9.1.2080
RUN cd $SONARQUBE_HOME/extensions/plugins && \
curl --fail --silent --show-error --location --output sonar-python-plugin-${SONAR_PYTHON_PLUGIN_VERSION}.jar \
https://binaries.sonarsource.com/Distribution/sonar-python-plugin/sonar-python-plugin-${SONAR_PYTHON_PLUGIN_VERSION}.jar

# Third-party plugins
ENV SONAR_FINDBUGS_PLUGIN_VERSION 3.9.3
RUN cd $SONARQUBE_HOME/extensions/plugins && \
curl --fail --silent --show-error --location --output sonar-findbugs-plugin-${SONAR_FINDBUGS_PLUGIN_VERSION}.jar \
https://github.com/SonarQubeCommunity/sonar-findbugs/releases/download/${SONAR_FINDBUGS_PLUGIN_VERSION}/sonar-findbugs-plugin-${SONAR_FINDBUGS_PLUGIN_VERSION}.jar

# Skyscanner plugins
ENV SONAR_JAVA_SECRETS_PLUGIN_VERSION 1.3.0
RUN cd $SONARQUBE_HOME/extensions/plugins && \
curl --fail --silent --show-error --location --output sonar-secrets-java-${SONAR_JAVA_SECRETS_PLUGIN_VERSION}.jar \
https://github.com/Skyscanner/sonar-secrets/releases/download/v${SONAR_JAVA_SECRETS_PLUGIN_VERSION}/sonar-secrets-java-${SONAR_JAVA_SECRETS_PLUGIN_VERSION}.jar

ENV SONAR_JS_SECRETS_PLUGIN_VERSION 1.3.0
RUN cd $SONARQUBE_HOME/extensions/plugins && \
curl --fail --silent --show-error --location --output sonar-secrets-javascript-${SONAR_JS_SECRETS_PLUGIN_VERSION}.jar \
https://github.com/Skyscanner/sonar-secrets/releases/download/v${SONAR_JS_SECRETS_PLUGIN_VERSION}/sonar-secrets-javascript-${SONAR_JS_SECRETS_PLUGIN_VERSION}.jar

ENTRYPOINT ${SONARQUBE_HOME}/bin/run.sh
17 changes: 17 additions & 0 deletions bin/lambdaguard
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env python3
"""
Copyright 2019 Skyscanner Ltd
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
"""
import lambdaguard
lambdaguard.run()
98 changes: 98 additions & 0 deletions lambdaguard/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"""
Copyright 2019 Skyscanner Ltd
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
"""
import boto3
from pathlib import Path
from shutil import rmtree
from lambdaguard.utils.arnparse import arnparse
from lambdaguard.utils.cli import *
from lambdaguard.utils.log import configure_log
from lambdaguard.core.Lambda import Lambda
from lambdaguard.core.STS import STS
from lambdaguard.visibility.Statistics import Statistics
from lambdaguard.visibility.Report import VisibilityReport
from lambdaguard.visibility.HTMLReport import HTMLReport
from lambdaguard.security.Report import SecurityReport


def get_functions(args):
if args.function:
yield args.function

elif args.input:
with Path(args.input).open() as f:
for _ in f.read().split('\n'):
yield _

else:
client = boto3.Session(
profile_name=args.profile,
aws_access_key_id=args.keys[0],
aws_secret_access_key=args.keys[1],
region_name=args.region
).client('lambda')
marker = None
while True:
pages = client.get_paginator('list_functions').paginate(
PaginationConfig={
'MaxItems': 10,
'PageSize': 10,
'StartingToken': marker
}
)
for page in pages:
for function in page['Functions']:
yield function['FunctionArn']
if 'NextMarker' not in page:
break
marker = page['NextMarker']

def run(arguments=''):
args = parse_args(arguments)
rmtree(args.output, ignore_errors=True)
Path(args.output).mkdir(parents=True, exist_ok=True)
configure_log(args.output)
identity = STS(f'arn:aws:sts:{args.region}', args.profile, args.keys[0], args.keys[1]).identity
if args.verbose:
print(header, end='\n\n')
for _ in ['UserId', 'Account', 'Arn']:
align(_, identity[_], orange)
print('')

statistics = Statistics(args.output)
visibility = VisibilityReport(args.output)

for arn in get_functions(args):
if arnparse(arn):
arn = arnparse(arn)
if args.verbose:
count = '[' + f'{statistics.statistics["lambdas"]+1}'.rjust(4, ' ') + '] '
print(f'\r{green}{count}{arn.resource}{nocolor}'.ljust(100, ' '), end='')
lmbd = Lambda(arn.full, args)
statistics.parse(lmbd.report())
visibility.save(lmbd.report())

SecurityReport(args.output).save()
HTMLReport(args.output).save()

if args.verbose:
print('\r' + ' '*100, end='\r') # clear
align('Lambdas', statistics.statistics["lambdas"])
align('Security', statistics.statistics["security"]["count"])
align('Triggers', statistics.statistics["triggers"]["count"])
align('Resources', statistics.statistics["resources"]["count"])
align('Runtimes', len(statistics.statistics["runtimes"]["items"]))
align('Regions', len(statistics.statistics["regions"]["items"]))
align('Report', f'{args.output}/report.html')
print('\n')
36 changes: 36 additions & 0 deletions lambdaguard/assets/func.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<tr data-toggle="collapse" data-target="#{index}-json">
<td id="{index}" colspan="2">{arn}</td>
<td>{region}</td>
<td>{runtime}</td>
</tr>
<tr class="collapse" id="{index}-json">
<td colspan="4">
<table class="table table-condensed">
<tbody>
<tr><td>ARN</td><td colspan="3">{arn}</td></tr>
<tr><td>Name</td><td colspan="3">{name}</td></tr>
<tr><td>Description</td><td colspan="3">{description}</td></tr>
<tr><td>Region</td><td colspan="3">{region}</td></tr>
<tr><td>Runtime</td><td colspan="3">{runtime}</td></tr>
<tr><td>Handler</td><td colspan="3">{handler}</td></tr>
<tr><td>Role</td><td colspan="3">{role}</td></tr>
<tr><td>Triggers ({triggers_count})</td><td colspan="3">{triggers}</td></tr>
<tr><td>Resources ({resources_count})</td><td colspan="3">{resources}</td></tr>
<tr><td>Security ({security_count})</td><td colspan="3">
<table class="table table-condensed">
<thead>
<th>Level</th>
<th>Text</th>
<th>Where</th>
</thead>
<tbody>
{security}
</tbody>
</table>
</td></tr>
<tr><td>Function policy</td><td colspan="3"><pre>{policy}</pre></td></tr>
<tr><td>Execution role policy</td><td colspan="3"><pre>{role_policy}</pre></td></tr>
</tbody>
</table>
</td>
</tr>
12 changes: 12 additions & 0 deletions lambdaguard/assets/funclist.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<table class="table table-hover table-striped table-bordered" id="functions-table">
<thead>
<tr>
<th colspan="2">ARN</th>
<th>Region</th>
<th>Runtime</th>
</tr>
</thead>
<tbody>
{items}
</tbody>
</table>
5 changes: 5 additions & 0 deletions lambdaguard/assets/funcvuln.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<tr>
<td><span class="label label-{level}">{level}</span></td>
<td>{text}</td>
<td>{where}</td>
</tr>
Loading

0 comments on commit 4b41369

Please sign in to comment.