Lambda Attack Surface Analyzer — risk analysis for AWS Lambda packages. Zero pip dependencies.
Project description
lasa — risk analysis for AWS Lambda packages
Analyze a Lambda's deployed bytes for supply-chain risk: third-party dependencies, distinct PyPI maintainer accounts your code trusts, KEV- listed CVEs in installed versions, and the declared AWS API surface your handler actually calls.
Outputs a 0-100 score, a catalog.conf-shaped attack-surface listing,
and a punchy human-readable report.
$ lasa risk --aws-lambda my-handler --region us-east-1
Lambda: my_handler.handler (semcom score: 94/100)
==================================================
Third-party code: 1.98 MB (100% of deployed package)
First-party code: 6.5 KB (111 LOC)
Top contributors:
urllib3 724.6 KB 1.26.15 · transitive · 2 maintainers
idna 464.8 KB 3.4 · transitive · 1 maintainers
requests 335.5 KB 2.28.1 · transitive · 2 maintainers
certifi 280.7 KB 2022.12.7 · transitive · 2 maintainers
charset-normalizer 221.1 KB 2.1.1 · transitive · 1 maintainers
Reachable maintainers: 8 distinct PyPI accounts
KEV-listed affected: 0 installed versions (0 CVEs)
Declared AWS surface: (none detected)
Score breakdown:
Third-party bytes: -2.0 points (1.98 MB)
Maintainers: -4.0 points (8 accounts)
KEV CVEs: -0.0 points (0 affected)
AWS API surface: -0.0 points (0 distinct)
--------
Total penalty: -6.0 points
Score: 94 / 100
What it analyzes
| Input | What it does |
|---|---|
path/to/lambda.zip |
Read the zip; analyze contents in-memory |
path/to/source/ |
Walk the directory; same analysis as for a zip |
--aws-lambda <name> |
Fetch the deployed zip via boto3, then analyze |
What the score means
The score combines four penalty axes (each capped at the value in parens, total possible penalty = 100):
- Third-party bytes (cap 40) — every megabyte of vendored code is a megabyte you didn't audit.
- Maintainers (cap 20) — every distinct PyPI account that can push to a dependency is an account whose laptop, if compromised, ships to your prod.
- KEV CVEs (cap 20) — CVEs in CISA's Known Exploited Vulnerabilities catalog. We surface only KEV-listed (not all advisories) — the floor below which "this is fine" stops being defensible.
- AWS API surface (cap 20) — every distinct (service, method) pair your code can reach is an action your IAM role must permit. Smaller surface ⇒ smaller blast radius if creds are compromised.
Full methodology: docs/lasa/METHODOLOGY.md.
Subcommands
lasa analyze <input> emit raw analysis JSON
lasa catalog <input> [--out FILE] emit catalog.conf-shaped text
lasa risk <input> [--json|--score-only]
lasa verify <input> <catalog> check source still implies catalog
lasa batch [--region X] leaderboard across an account
lasa ratchet <new> --against <baseline> CI gate: PR can't lower score
lasa version
CI ratchet (GitHub Action)
Drop this in a PR workflow to make sure no one merges a regression:
- uses: lanethompson/lasa@v0.7
with:
new: dist/lambda.zip
baseline: baseline/lambda.zip # checkout from main
max-drop: 5 # allow up to 5 pts of slip
comment-on-pr: true # posts the breakdown as a PR comment
The action exits non-zero (failing the PR check) when the new score
falls below the baseline minus max-drop, and posts a markdown
table comparing baseline vs new scores per axis. See
.github/workflows/example-ratchet.yml for a complete example.
<input> is one of: a path to a .zip, a path to a source directory,
or --aws-lambda <name> [--region <region>] [--profile <profile>].
Install
Requires Python 3.10+. Zero pip dependencies — stdlib only, including SigV4 signing for the AWS Lambda API.
pip install lasa
lasa version
Or from source:
git clone https://github.com/Apilify/lasa
cd lasa
make install # creates .venv, installs the package
.venv/bin/lasa version
The supply-chain claim we make about other people's Lambdas applies
to ourselves first: lasa has no third-party transitive dependencies
to be hijacked by the next worm. pip install lasa adds nothing to
your Python environment beyond lasa itself.
Why catalog.conf
The catalog is informational — it describes what the code does (detected from source), not what it's structurally constrained to do. The catalog file is not enforced by the runtime; nothing prevents the Lambda from doing things outside this list at runtime.
Catalog-disciplined deployments — where the catalog IS structurally enforced by the linker / runtime — are a separate product. lasa analyzes existing Python Lambdas; it does not transform them.
Caching
PyPI maintainer counts and OSV vulnerability lookups are cached to
~/.cache/semcom/ for 7 days. Override with --no-cache or
--cache-ttl SECONDS.
Versioning
This is v0.1. The Python implementation is the oracle — it defines the score and catalog format. v1 is Forth + dlsym; v2 is verified IR caps. Field names and types in the JSON output are the public ABI both later versions must match.
lasa version prints the implementation version + the methodology
version; the methodology version bumps whenever weights or rules
change.
License
MIT.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lasa-0.9.0.tar.gz.
File metadata
- Download URL: lasa-0.9.0.tar.gz
- Upload date:
- Size: 79.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e7f3be4b06c3851b0fbd3a38759bd645604ba7c8d9cc3eeb74b86dd79a953f76
|
|
| MD5 |
0e64ba1b32d96fded8c24bd8798a498b
|
|
| BLAKE2b-256 |
1dff47cea00eed87fee5b7d6dd4eac16b42e1f513f55529f4919ff22ecd4e364
|
File details
Details for the file lasa-0.9.0-py3-none-any.whl.
File metadata
- Download URL: lasa-0.9.0-py3-none-any.whl
- Upload date:
- Size: 95.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7e7634b1663d64172e4527a5802d8524b54d646bd431ca1d60ea85e0f5ea6fb2
|
|
| MD5 |
cb883cce29c188e6d1ad08b98ccaa8b8
|
|
| BLAKE2b-256 |
585298a1eab0c1920c27ea598703335a13f8f92fc6dfcf68f30209d97aa299bd
|