notify doctors work, audit work, new product advisory sprints
This commit is contained in:
55
docs/examples/binary-diff/README.md
Normal file
55
docs/examples/binary-diff/README.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Binary Diff Examples
|
||||
|
||||
This directory contains examples demonstrating the binary diff attestation feature.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- StellaOps CLI (`stella`) installed
|
||||
- Access to a container registry
|
||||
- Docker or containerd runtime (for image pulling)
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Comparison
|
||||
|
||||
[basic-comparison.md](./basic-comparison.md) - Simple binary diff between two image versions
|
||||
|
||||
### DSSE Attestation
|
||||
|
||||
[dsse-attestation.md](./dsse-attestation.md) - Generating and verifying DSSE-signed attestations
|
||||
|
||||
### Policy Integration
|
||||
|
||||
[policy-integration.md](./policy-integration.md) - Using binary diff evidence in policy rules
|
||||
|
||||
### CI/CD Integration
|
||||
|
||||
[ci-cd-integration.md](./ci-cd-integration.md) - GitHub Actions and GitLab CI examples
|
||||
|
||||
## Sample Outputs
|
||||
|
||||
The `sample-outputs/` directory contains:
|
||||
|
||||
- `diff-table.txt` - Sample table-formatted output
|
||||
- `diff.json` - Sample JSON output
|
||||
- `attestation.dsse.json` - Sample DSSE envelope
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Compare two image versions
|
||||
stella scan diff --base myapp:1.0.0 --target myapp:1.0.1
|
||||
|
||||
# Generate attestation
|
||||
stella scan diff --base myapp:1.0.0 --target myapp:1.0.1 \
|
||||
--mode=elf --emit-dsse=./attestations/
|
||||
|
||||
# Verify attestation
|
||||
stella verify attestation ./attestations/linux-amd64-binarydiff.dsse.json
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Binary Diff Attestation Architecture](../../modules/scanner/binary-diff-attestation.md)
|
||||
- [BinaryDiffV1 JSON Schema](../../schemas/binarydiff-v1.schema.json)
|
||||
- [CLI Reference](../../API_CLI_REFERENCE.md#stella-scan-diff)
|
||||
143
docs/examples/binary-diff/basic-comparison.md
Normal file
143
docs/examples/binary-diff/basic-comparison.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# Basic Binary Comparison
|
||||
|
||||
This example demonstrates how to perform a basic binary diff between two container image versions.
|
||||
|
||||
## Scenario
|
||||
|
||||
You have deployed `myapp:1.0.0` and want to understand what binary changes are in `myapp:1.0.1` before upgrading.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
```bash
|
||||
# Ensure stella CLI is installed
|
||||
stella --version
|
||||
|
||||
# Verify registry access
|
||||
stella registry ping docker://registry.example.com
|
||||
```
|
||||
|
||||
## Basic Comparison
|
||||
|
||||
### Table Output (Default)
|
||||
|
||||
```bash
|
||||
stella scan diff \
|
||||
--base docker://registry.example.com/myapp:1.0.0 \
|
||||
--target docker://registry.example.com/myapp:1.0.1
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
Binary Diff: docker://registry.example.com/myapp:1.0.0 -> docker://registry.example.com/myapp:1.0.1
|
||||
Platform: linux/amd64
|
||||
Analysis Mode: ELF Section Hashes
|
||||
|
||||
PATH CHANGE VERDICT CONFIDENCE
|
||||
--------------------------------------------------------------------------------
|
||||
/usr/lib/libssl.so.3 modified patched 0.95
|
||||
/usr/lib/libcrypto.so.3 modified patched 0.92
|
||||
/app/bin/myapp modified vanilla 0.98
|
||||
|
||||
Summary: 156 binaries analyzed, 3 modified, 153 unchanged
|
||||
```
|
||||
|
||||
### JSON Output
|
||||
|
||||
```bash
|
||||
stella scan diff \
|
||||
--base docker://registry.example.com/myapp:1.0.0 \
|
||||
--target docker://registry.example.com/myapp:1.0.1 \
|
||||
--format=json > diff.json
|
||||
```
|
||||
|
||||
The JSON output contains detailed section-level information. See [sample-outputs/diff.json](./sample-outputs/diff.json) for a complete example.
|
||||
|
||||
### Summary Output
|
||||
|
||||
```bash
|
||||
stella scan diff \
|
||||
--base docker://registry.example.com/myapp:1.0.0 \
|
||||
--target docker://registry.example.com/myapp:1.0.1 \
|
||||
--format=summary
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
Binary Diff Summary
|
||||
-------------------
|
||||
Base: docker://registry.example.com/myapp:1.0.0 (sha256:abc123...)
|
||||
Target: docker://registry.example.com/myapp:1.0.1 (sha256:def456...)
|
||||
Platform: linux/amd64
|
||||
|
||||
Binaries: 156 total, 3 modified, 153 unchanged
|
||||
Verdicts: 2 patched, 1 vanilla
|
||||
```
|
||||
|
||||
## Using Digest References
|
||||
|
||||
For immutable references, use digests instead of tags:
|
||||
|
||||
```bash
|
||||
stella scan diff \
|
||||
--base docker://registry.example.com/myapp@sha256:abc123... \
|
||||
--target docker://registry.example.com/myapp@sha256:def456...
|
||||
```
|
||||
|
||||
## Filtering by Platform
|
||||
|
||||
For multi-arch images, specify the platform:
|
||||
|
||||
```bash
|
||||
# Linux AMD64 only
|
||||
stella scan diff \
|
||||
--base myapp:1.0.0 \
|
||||
--target myapp:1.0.1 \
|
||||
--platform=linux/amd64
|
||||
|
||||
# Linux ARM64
|
||||
stella scan diff \
|
||||
--base myapp:1.0.0 \
|
||||
--target myapp:1.0.1 \
|
||||
--platform=linux/arm64
|
||||
```
|
||||
|
||||
## Including Unchanged Binaries
|
||||
|
||||
By default, unchanged binaries are excluded from output. To include them:
|
||||
|
||||
```bash
|
||||
stella scan diff \
|
||||
--base myapp:1.0.0 \
|
||||
--target myapp:1.0.1 \
|
||||
--include-unchanged
|
||||
```
|
||||
|
||||
## Verbose Output
|
||||
|
||||
For debugging or detailed progress:
|
||||
|
||||
```bash
|
||||
stella scan diff \
|
||||
--base myapp:1.0.0 \
|
||||
--target myapp:1.0.1 \
|
||||
--verbose
|
||||
```
|
||||
|
||||
Output includes:
|
||||
- Layer download progress
|
||||
- Binary detection details
|
||||
- Section hash computation progress
|
||||
|
||||
## Understanding Verdicts
|
||||
|
||||
| Verdict | Meaning | Action |
|
||||
|---------|---------|--------|
|
||||
| `patched` | High confidence that a security patch was applied | Review changelog, consider safe to upgrade |
|
||||
| `vanilla` | Standard code change, no backport evidence | Normal release update |
|
||||
| `unknown` | Cannot determine patch status | Manual review recommended |
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Generate DSSE Attestations](./dsse-attestation.md) for audit trail
|
||||
- [Integrate with Policy](./policy-integration.md) for automated gates
|
||||
- [Add to CI/CD](./ci-cd-integration.md) for continuous verification
|
||||
371
docs/examples/binary-diff/ci-cd-integration.md
Normal file
371
docs/examples/binary-diff/ci-cd-integration.md
Normal file
@@ -0,0 +1,371 @@
|
||||
# CI/CD Integration
|
||||
|
||||
This example demonstrates how to integrate binary diff attestation into your CI/CD pipelines.
|
||||
|
||||
## GitHub Actions
|
||||
|
||||
### Basic Workflow
|
||||
|
||||
```yaml
|
||||
# .github/workflows/binary-diff.yml
|
||||
name: Binary Diff Attestation
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
binary-diff:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write # For keyless signing
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Stella CLI
|
||||
uses: stellaops/setup-stella@v1
|
||||
with:
|
||||
version: 'latest'
|
||||
|
||||
- name: Login to Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Get Previous Tag
|
||||
id: prev-tag
|
||||
run: |
|
||||
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
|
||||
echo "tag=$PREV_TAG" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Binary Diff
|
||||
if: steps.prev-tag.outputs.tag != ''
|
||||
run: |
|
||||
stella scan diff \
|
||||
--base ghcr.io/${{ github.repository }}:${{ steps.prev-tag.outputs.tag }} \
|
||||
--target ghcr.io/${{ github.repository }}:${{ github.ref_name }} \
|
||||
--mode=elf \
|
||||
--emit-dsse=./attestations/ \
|
||||
--format=json > diff.json
|
||||
|
||||
- name: Upload Attestations
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: binary-diff-attestations
|
||||
path: |
|
||||
attestations/
|
||||
diff.json
|
||||
|
||||
- name: Attach Attestation to Image
|
||||
run: |
|
||||
# Using cosign to attach attestation
|
||||
cosign attach attestation \
|
||||
--attestation ./attestations/linux-amd64-binarydiff.dsse.json \
|
||||
ghcr.io/${{ github.repository }}:${{ github.ref_name }}
|
||||
```
|
||||
|
||||
### With Release Gate
|
||||
|
||||
```yaml
|
||||
# .github/workflows/release-gate.yml
|
||||
name: Release Gate with Binary Diff
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
base_version:
|
||||
description: 'Base version to compare'
|
||||
required: true
|
||||
target_version:
|
||||
description: 'Target version to release'
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
binary-diff-gate:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
verdict: ${{ steps.analyze.outputs.verdict }}
|
||||
|
||||
steps:
|
||||
- name: Setup Stella CLI
|
||||
uses: stellaops/setup-stella@v1
|
||||
|
||||
- name: Binary Diff Analysis
|
||||
id: diff
|
||||
run: |
|
||||
stella scan diff \
|
||||
--base myapp:${{ inputs.base_version }} \
|
||||
--target myapp:${{ inputs.target_version }} \
|
||||
--format=json > diff.json
|
||||
|
||||
- name: Analyze Results
|
||||
id: analyze
|
||||
run: |
|
||||
# Check for unknown verdicts
|
||||
UNKNOWN_COUNT=$(jq '.summary.verdicts.unknown // 0' diff.json)
|
||||
if [ "$UNKNOWN_COUNT" -gt "0" ]; then
|
||||
echo "verdict=review-required" >> $GITHUB_OUTPUT
|
||||
echo "::warning::Found $UNKNOWN_COUNT binaries with unknown verdicts"
|
||||
else
|
||||
echo "verdict=approved" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Gate Decision
|
||||
if: steps.analyze.outputs.verdict == 'review-required'
|
||||
run: |
|
||||
echo "Manual review required for unknown binary changes"
|
||||
exit 1
|
||||
```
|
||||
|
||||
## GitLab CI
|
||||
|
||||
### Basic Pipeline
|
||||
|
||||
```yaml
|
||||
# .gitlab-ci.yml
|
||||
stages:
|
||||
- build
|
||||
- analyze
|
||||
- release
|
||||
|
||||
variables:
|
||||
STELLA_VERSION: "latest"
|
||||
|
||||
binary-diff:
|
||||
stage: analyze
|
||||
image: stellaops/cli:${STELLA_VERSION}
|
||||
script:
|
||||
- |
|
||||
# Get previous tag
|
||||
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
|
||||
|
||||
if [ -n "$PREV_TAG" ]; then
|
||||
stella scan diff \
|
||||
--base ${CI_REGISTRY_IMAGE}:${PREV_TAG} \
|
||||
--target ${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG} \
|
||||
--mode=elf \
|
||||
--emit-dsse=attestations/ \
|
||||
--format=json > diff.json
|
||||
|
||||
# Upload to GitLab artifacts
|
||||
echo "Binary diff completed"
|
||||
else
|
||||
echo "No previous tag found, skipping diff"
|
||||
fi
|
||||
artifacts:
|
||||
paths:
|
||||
- attestations/
|
||||
- diff.json
|
||||
expire_in: 30 days
|
||||
only:
|
||||
- tags
|
||||
```
|
||||
|
||||
### With Security Gate
|
||||
|
||||
```yaml
|
||||
# .gitlab-ci.yml
|
||||
security-gate:
|
||||
stage: analyze
|
||||
image: stellaops/cli:latest
|
||||
script:
|
||||
- |
|
||||
stella scan diff \
|
||||
--base ${CI_REGISTRY_IMAGE}:${BASE_VERSION} \
|
||||
--target ${CI_REGISTRY_IMAGE}:${TARGET_VERSION} \
|
||||
--format=json > diff.json
|
||||
|
||||
# Fail if any unknown verdicts
|
||||
UNKNOWN=$(jq '.summary.verdicts.unknown // 0' diff.json)
|
||||
if [ "$UNKNOWN" -gt "0" ]; then
|
||||
echo "Security gate failed: $UNKNOWN unknown binary changes"
|
||||
jq '.findings[] | select(.verdict == "unknown")' diff.json
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Security gate passed"
|
||||
allow_failure: false
|
||||
```
|
||||
|
||||
## Jenkins Pipeline
|
||||
|
||||
```groovy
|
||||
// Jenkinsfile
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
environment {
|
||||
STELLA_VERSION = 'latest'
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Binary Diff') {
|
||||
steps {
|
||||
script {
|
||||
def prevTag = sh(
|
||||
script: 'git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo ""',
|
||||
returnStdout: true
|
||||
).trim()
|
||||
|
||||
if (prevTag) {
|
||||
sh """
|
||||
stella scan diff \\
|
||||
--base ${REGISTRY}/${IMAGE}:${prevTag} \\
|
||||
--target ${REGISTRY}/${IMAGE}:${TAG} \\
|
||||
--mode=elf \\
|
||||
--emit-dsse=attestations/ \\
|
||||
--format=json > diff.json
|
||||
"""
|
||||
|
||||
archiveArtifacts artifacts: 'attestations/*, diff.json'
|
||||
|
||||
// Parse and check results
|
||||
def diff = readJSON file: 'diff.json'
|
||||
if (diff.summary.verdicts.unknown > 0) {
|
||||
unstable("Found ${diff.summary.verdicts.unknown} unknown binary changes")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Azure DevOps
|
||||
|
||||
```yaml
|
||||
# azure-pipelines.yml
|
||||
trigger:
|
||||
tags:
|
||||
include:
|
||||
- v*
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
steps:
|
||||
- task: Bash@3
|
||||
displayName: 'Install Stella CLI'
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: |
|
||||
curl -sSL https://get.stellaops.io | sh
|
||||
stella --version
|
||||
|
||||
- task: Docker@2
|
||||
displayName: 'Login to Registry'
|
||||
inputs:
|
||||
containerRegistry: 'myRegistry'
|
||||
command: 'login'
|
||||
|
||||
- task: Bash@3
|
||||
displayName: 'Binary Diff'
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: |
|
||||
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
|
||||
if [ -n "$PREV_TAG" ]; then
|
||||
stella scan diff \
|
||||
--base $(REGISTRY)/$(IMAGE):${PREV_TAG} \
|
||||
--target $(REGISTRY)/$(IMAGE):$(Build.SourceBranchName) \
|
||||
--mode=elf \
|
||||
--emit-dsse=$(Build.ArtifactStagingDirectory)/attestations/ \
|
||||
--format=json > $(Build.ArtifactStagingDirectory)/diff.json
|
||||
fi
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathToPublish: '$(Build.ArtifactStagingDirectory)'
|
||||
artifactName: 'binary-diff'
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Always Use Digest References in Production
|
||||
|
||||
```bash
|
||||
# Instead of tags
|
||||
stella scan diff --base myapp:v1.0.0 --target myapp:v1.0.1
|
||||
|
||||
# Use digests for immutability
|
||||
stella scan diff \
|
||||
--base myapp@sha256:abc123... \
|
||||
--target myapp@sha256:def456...
|
||||
```
|
||||
|
||||
### 2. Store Attestations with Releases
|
||||
|
||||
Attach DSSE attestations to your container images or store them alongside release artifacts.
|
||||
|
||||
### 3. Set Appropriate Timeouts
|
||||
|
||||
```bash
|
||||
# For large images, increase timeout
|
||||
stella scan diff \
|
||||
--base myapp:v1 \
|
||||
--target myapp:v2 \
|
||||
--timeout=600
|
||||
```
|
||||
|
||||
### 4. Use Caching
|
||||
|
||||
```yaml
|
||||
# GitHub Actions with caching
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.stella/cache
|
||||
key: stella-${{ runner.os }}-${{ hashFiles('**/Dockerfile') }}
|
||||
```
|
||||
|
||||
### 5. Fail Fast on Critical Issues
|
||||
|
||||
```bash
|
||||
# Exit code indicates issues
|
||||
stella scan diff --base old --target new --format=json > diff.json
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Diff failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for critical verdicts
|
||||
jq -e '.summary.verdicts.unknown == 0' diff.json || exit 1
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Registry Authentication
|
||||
|
||||
```bash
|
||||
# Use Docker config
|
||||
stella scan diff \
|
||||
--base myapp:v1 \
|
||||
--target myapp:v2 \
|
||||
--registry-auth=~/.docker/config.json
|
||||
```
|
||||
|
||||
### Platform Issues
|
||||
|
||||
```bash
|
||||
# Explicitly specify platform for multi-arch
|
||||
stella scan diff \
|
||||
--base myapp:v1 \
|
||||
--target myapp:v2 \
|
||||
--platform=linux/amd64
|
||||
```
|
||||
|
||||
### Timeout Issues
|
||||
|
||||
```bash
|
||||
# Increase timeout for slow registries
|
||||
stella scan diff \
|
||||
--base myapp:v1 \
|
||||
--target myapp:v2 \
|
||||
--timeout=900
|
||||
```
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"payloadType": "stellaops.binarydiff.v1",
|
||||
"payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoiZG9ja2VyOi8vcmVnaXN0cnkuZXhhbXBsZS5jb20vYXBwQHNoYTI1NjpkZWY0NTZhYmM3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1NjdlZmdoIiwiZGlnZXN0Ijp7InNoYTI1NiI6ImRlZjQ1NmFiYzc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2N2VmZ2gifX1dLCJwcmVkaWNhdGVUeXBlIjoic3RlbGxhb3BzLmJpbmFyeWRpZmYudjEiLCJwcmVkaWNhdGUiOnsiaW5wdXRzIjp7ImJhc2UiOnsiZGlnZXN0Ijoic2hhMjU2OmFiYzEyM2RlZjQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNGFiY2QifSwidGFyZ2V0Ijp7ImRpZ2VzdCI6InNoYTI1NjpkZWY0NTZhYmM3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1NjdlZmdoIn19LCJmaW5kaW5ncyI6W3sicGF0aCI6Ii91c3IvbGliL2xpYnNzbC5zby4zIiwiY2hhbmdlVHlwZSI6Im1vZGlmaWVkIiwidmVyZGljdCI6InBhdGNoZWQiLCJjb25maWRlbmNlIjowLjk1fV0sIm1ldGFkYXRhIjp7InRvb2xWZXJzaW9uIjoiMS4wLjAiLCJhbmFseXNpc1RpbWVzdGFtcCI6IjIwMjYtMDEtMTNUMTI6MDA6MDBaIn19fQ==",
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
|
||||
"sig": "MEUCIQDKZokqnCjrRtw5EXP14JvsBwFDRPfCp9K0UoOlWGdlDQIgSNpOGPqKNLv5MNZLYc5iE7q5b3wW6K0cDpjNxBxCWdU="
|
||||
}
|
||||
],
|
||||
"_note": "This is a sample DSSE envelope for documentation purposes. The payload is base64-encoded and contains an in-toto statement with a BinaryDiffV1 predicate. In production, the signature would be cryptographically valid.",
|
||||
"_rekorMetadata": {
|
||||
"logIndex": 12345678,
|
||||
"entryUuid": "24296fb24b8ad77aa3e6b0d1b6e0e3a0c9f8d7e6b5a4c3d2e1f0a9b8c7d6e5f4",
|
||||
"integratedTime": "2026-01-13T12:00:05Z",
|
||||
"logUrl": "https://rekor.sigstore.dev"
|
||||
}
|
||||
}
|
||||
27
docs/examples/binary-diff/sample-outputs/diff-table.txt
Normal file
27
docs/examples/binary-diff/sample-outputs/diff-table.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
Binary Diff: docker://registry.example.com/app:1.0.0 -> docker://registry.example.com/app:1.0.1
|
||||
Platform: linux/amd64
|
||||
Analysis Mode: ELF Section Hashes
|
||||
Analyzed Sections: .text, .rodata, .data, .symtab, .dynsym
|
||||
|
||||
PATH CHANGE VERDICT CONFIDENCE SECTIONS CHANGED
|
||||
--------------------------------------------------------------------------------------------------
|
||||
/usr/lib/x86_64-linux-gnu/libssl.so.3 modified patched 0.95 .text, .rodata
|
||||
/usr/lib/x86_64-linux-gnu/libcrypto.so.3 modified patched 0.92 .text
|
||||
/usr/bin/openssl modified unknown 0.75 .text, .data, .symtab
|
||||
/lib/x86_64-linux-gnu/libc.so.6 unchanged - - -
|
||||
/lib/x86_64-linux-gnu/libpthread.so.0 unchanged - - -
|
||||
/usr/lib/x86_64-linux-gnu/libz.so.1 unchanged - - -
|
||||
/app/bin/myapp modified vanilla 0.98 .text, .rodata, .data
|
||||
|
||||
Summary
|
||||
-------
|
||||
Total binaries analyzed: 156
|
||||
Modified: 4
|
||||
Unchanged: 152
|
||||
|
||||
Verdicts:
|
||||
Patched: 2 (high confidence backport detected)
|
||||
Vanilla: 1 (standard update, no backport evidence)
|
||||
Unknown: 1 (insufficient evidence for classification)
|
||||
|
||||
Analysis completed in 12.4s
|
||||
179
docs/examples/binary-diff/sample-outputs/diff.json
Normal file
179
docs/examples/binary-diff/sample-outputs/diff.json
Normal file
@@ -0,0 +1,179 @@
|
||||
{
|
||||
"schemaVersion": "1.0.0",
|
||||
"base": {
|
||||
"reference": "docker://registry.example.com/app:1.0.0",
|
||||
"digest": "sha256:abc123def456789012345678901234567890123456789012345678901234abcd",
|
||||
"manifestDigest": "sha256:111222333444555666777888999000aaabbbcccdddeeefff000111222333444555"
|
||||
},
|
||||
"target": {
|
||||
"reference": "docker://registry.example.com/app:1.0.1",
|
||||
"digest": "sha256:def456abc789012345678901234567890123456789012345678901234567efgh",
|
||||
"manifestDigest": "sha256:666777888999000aaabbbcccdddeeefff000111222333444555666777888999000"
|
||||
},
|
||||
"platform": {
|
||||
"os": "linux",
|
||||
"architecture": "amd64"
|
||||
},
|
||||
"analysisMode": "elf",
|
||||
"timestamp": "2026-01-13T12:00:00.000000Z",
|
||||
"findings": [
|
||||
{
|
||||
"path": "/usr/lib/x86_64-linux-gnu/libssl.so.3",
|
||||
"changeType": "modified",
|
||||
"binaryFormat": "elf",
|
||||
"layerDigest": "sha256:aaa111bbb222ccc333ddd444eee555fff666777888999000aaabbbcccdddeeef",
|
||||
"baseHashes": {
|
||||
"buildId": "abc123def456789012345678",
|
||||
"fileHash": "1111111111111111111111111111111111111111111111111111111111111111",
|
||||
"sections": {
|
||||
".text": {
|
||||
"sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"size": 524288,
|
||||
"offset": 4096
|
||||
},
|
||||
".rodata": {
|
||||
"sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
"size": 131072,
|
||||
"offset": 528384
|
||||
}
|
||||
}
|
||||
},
|
||||
"targetHashes": {
|
||||
"buildId": "def789abc012345678901234",
|
||||
"fileHash": "2222222222222222222222222222222222222222222222222222222222222222",
|
||||
"sections": {
|
||||
".text": {
|
||||
"sha256": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
||||
"size": 524544,
|
||||
"offset": 4096
|
||||
},
|
||||
".rodata": {
|
||||
"sha256": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
|
||||
"size": 131200,
|
||||
"offset": 528640
|
||||
}
|
||||
}
|
||||
},
|
||||
"sectionDeltas": [
|
||||
{
|
||||
"section": ".text",
|
||||
"status": "modified",
|
||||
"baseSha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"targetSha256": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
||||
"sizeDelta": 256
|
||||
},
|
||||
{
|
||||
"section": ".rodata",
|
||||
"status": "modified",
|
||||
"baseSha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
"targetSha256": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
|
||||
"sizeDelta": 128
|
||||
},
|
||||
{
|
||||
"section": ".data",
|
||||
"status": "identical",
|
||||
"baseSha256": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
|
||||
"targetSha256": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
|
||||
"sizeDelta": 0
|
||||
},
|
||||
{
|
||||
"section": ".symtab",
|
||||
"status": "identical",
|
||||
"baseSha256": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"targetSha256": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"sizeDelta": 0
|
||||
}
|
||||
],
|
||||
"confidence": 0.95,
|
||||
"verdict": "patched"
|
||||
},
|
||||
{
|
||||
"path": "/usr/lib/x86_64-linux-gnu/libcrypto.so.3",
|
||||
"changeType": "modified",
|
||||
"binaryFormat": "elf",
|
||||
"layerDigest": "sha256:aaa111bbb222ccc333ddd444eee555fff666777888999000aaabbbcccdddeeef",
|
||||
"sectionDeltas": [
|
||||
{
|
||||
"section": ".text",
|
||||
"status": "modified",
|
||||
"sizeDelta": 1024
|
||||
},
|
||||
{
|
||||
"section": ".rodata",
|
||||
"status": "identical",
|
||||
"sizeDelta": 0
|
||||
}
|
||||
],
|
||||
"confidence": 0.92,
|
||||
"verdict": "patched"
|
||||
},
|
||||
{
|
||||
"path": "/usr/bin/openssl",
|
||||
"changeType": "modified",
|
||||
"binaryFormat": "elf",
|
||||
"sectionDeltas": [
|
||||
{
|
||||
"section": ".text",
|
||||
"status": "modified",
|
||||
"sizeDelta": 512
|
||||
},
|
||||
{
|
||||
"section": ".data",
|
||||
"status": "modified",
|
||||
"sizeDelta": 64
|
||||
},
|
||||
{
|
||||
"section": ".symtab",
|
||||
"status": "modified",
|
||||
"sizeDelta": 128
|
||||
}
|
||||
],
|
||||
"confidence": 0.75,
|
||||
"verdict": "unknown"
|
||||
},
|
||||
{
|
||||
"path": "/app/bin/myapp",
|
||||
"changeType": "modified",
|
||||
"binaryFormat": "elf",
|
||||
"sectionDeltas": [
|
||||
{
|
||||
"section": ".text",
|
||||
"status": "modified",
|
||||
"sizeDelta": 2048
|
||||
},
|
||||
{
|
||||
"section": ".rodata",
|
||||
"status": "modified",
|
||||
"sizeDelta": 512
|
||||
},
|
||||
{
|
||||
"section": ".data",
|
||||
"status": "modified",
|
||||
"sizeDelta": 128
|
||||
}
|
||||
],
|
||||
"confidence": 0.98,
|
||||
"verdict": "vanilla"
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"totalBinaries": 156,
|
||||
"modified": 4,
|
||||
"unchanged": 152,
|
||||
"added": 0,
|
||||
"removed": 0,
|
||||
"verdicts": {
|
||||
"patched": 2,
|
||||
"vanilla": 1,
|
||||
"unknown": 1,
|
||||
"incompatible": 0
|
||||
},
|
||||
"sectionsAnalyzed": [".text", ".rodata", ".data", ".symtab", ".dynsym"],
|
||||
"analysisDurationMs": 12400
|
||||
},
|
||||
"metadata": {
|
||||
"toolVersion": "1.0.0",
|
||||
"analysisTimestamp": "2026-01-13T12:00:00.000000Z",
|
||||
"configDigest": "sha256:config123456789abcdef0123456789abcdef0123456789abcdef0123456789ab"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user