Skip to content

Commit

Permalink
w
Browse files Browse the repository at this point in the history
  • Loading branch information
andream16 committed Sep 17, 2024
1 parent c10630d commit 5f78135
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 24 deletions.
4 changes: 3 additions & 1 deletion components/enrichers/reachability/internal/atom/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,14 @@ func NewReader(atomFilePath string, purlParser *purl.Parser) (*Reader, error) {
}

// Read deserialises the json content of the provided atom file into Reachables format.
func (r *Reader) Read() (*Response, error) {
func (r *Reader) Read(ctx context.Context) (*Response, error) {
b, err := os.ReadFile(r.atomFilePath)
if err != nil {
return nil, fmt.Errorf("failed to read atom file: %w", err)
}

logging.FromContext(ctx).Debug("sample atom file contents", slog.String("payload", string(b)))

var res Response
if err := json.Unmarshal(b, &res); err != nil {
return nil, fmt.Errorf("failed to unmarshal atom response: %w", err)
Expand Down
52 changes: 49 additions & 3 deletions components/enrichers/reachability/internal/enricher/enricher.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,40 +48,73 @@ func NewEnricher(
// Enrich looks for untagged inputs and processes them outputting if any of them is reachable.
// The reachability checks leverage atom - https://github.com/AppThreat/atom.
func (r *enricher) Enrich(ctx context.Context) error {
logger := logging.FromContext(ctx)
var (
logger = logging.FromContext(ctx).With(
slog.String("producer_results_path", r.cfg.ProducerResultsPath),
slog.String("enriched_results_path", r.cfg.EnrichedResultsPath),
slog.String("atom_file_path", r.cfg.ATOMFilePath),
)
)

logger.Debug("running enrichment step")
logger.Debug("preparing to read tagged response...")

taggedRes, err := r.readWriter.ReadTaggedResponse()
if err != nil {
return fmt.Errorf("could not read tagged response: %w", err)
}

reachablesRes, err := r.atomReader.Read()
logger = logger.With(slog.Int("num_tagged_resources", len(taggedRes)))
logger.Debug("successfully read tagged response!")
logger.Debug("preparing to read atom file...")

reachablesRes, err := r.atomReader.Read(ctx)
if err != nil {
return fmt.Errorf("could not read atom reachables from path %s: %w", r.cfg.ATOMFilePath, err)
}

logger = logger.With(slog.Int("num_atom_reachables", len(reachablesRes.Reachables)))
logger.Debug("successfully read atom file!")
logger.Debug("preparing to check for reachable purls...")

reachablePurls, err := r.atomReader.ReachablePurls(ctx, reachablesRes)
if err != nil {
return fmt.Errorf("could not get reachable purls: %w", err)
}

logger = logger.With(slog.Int("num_reachable_purls", len(reachablePurls)))
logger.Debug("successfully checked for reachable purls!")
logger.Debug("preparing to create a new searcher...")

searcher, err := search.NewSearcher(reachablesRes.Reachables, reachablePurls)
if err != nil {
return fmt.Errorf("could not create searcher: %w", err)
}

logger.Debug("successfully created a new searcher!")
logger.Debug("preparing to check for reachable targets...")

for _, taggedEntry := range taggedRes {
var (
enrichedIssues []*v1.EnrichedIssue
issues = taggedEntry.GetIssues()
)

logger := logger.With(
slog.String("tool_name", taggedEntry.GetToolName()),
slog.String("scan_target", taggedEntry.GetToolName()),
slog.Any("scan_info", taggedEntry.GetScanInfo()),
slog.Int("num_issues", len(issues)),
)

logger.Debug("preparing to enrich issues in target...")

for _, issue := range issues {
// Search.
ok, err := searcher.Search(issue.Target)
if err != nil {
logger.Error(
"could not search target. Continuing...",
slog.String("target", issue.Target),
slog.String("err", err.Error()),
)
continue
Expand All @@ -96,14 +129,22 @@ func (r *enricher) Enrich(ctx context.Context) error {
})
}

logger = logger.With(slog.Int("num_enriched_issues", len(enrichedIssues)))

var numReachable int
for _, ei := range enrichedIssues {
v, ok := ei.Annotations["reachable"]
if ok && v == "true" {
_ = v
numReachable++
}
}

logger = logger.With(slog.Int("num_reachable_issues", numReachable))
logger.Debug("successfully enriched issues in target!")

// Write results.
logger.Debug("preparing to write enriched results for tagged entry...")
if err := r.readWriter.WriteEnrichedResults(taggedEntry, enrichedIssues); err != nil {
logger.Error(
"could not write enriched results. Continuing...",
Expand All @@ -112,14 +153,19 @@ func (r *enricher) Enrich(ctx context.Context) error {
continue
}

logger.Debug("successfully wrote enriched results for tagged entry!")
logger.Debug("preparing to write raw results for tagged entry...")
if err := r.readWriter.WriteRawResults(taggedEntry); err != nil {
logger.Error(
"could not write raw results. Continuing...",
slog.String("err", err.Error()),
)
continue
}

logger.Debug("successfully wrote raw results for tagged entry!")
}

logger.Debug("completed enrichment step!")
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const ctxLoggerKey = loggerKey("logging")
// NewLogger returns a new structured logger.
func NewLogger() *slog.Logger {
return slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
AddSource: true,
Level: slog.LevelDebug,
}))
}

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
)

const (
baseTestdataPath = "../test/testdata"
baseTestdataPath = "./test/testdata"

banditRawFileName = "bandit.raw.pb"
banditEnrichedFileName = "bandit.reachability.enriched.pb"
Expand Down
53 changes: 37 additions & 16 deletions components/enrichers/reachability/task.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,62 @@ metadata:
v1.dracon.ocurity.com/component: enricher
spec:
description: Performs a reachability check on a supplied repository using AppThreat/atom.
params:
- name: enricher-reachability-programming-language
type: string
volumes:
- name: scratch
emptyDir: {}
workspaces:
- name: output
description: The workspace containing the source-code to scan.
steps:
- name: run-cdxgen
imagePullPolicy: IfNotPresent
image: node:lts-alpine3.20@sha256:2d07db07a2df6830718ae2a47db6fedce6745f5bcd174c398f2acdda90a11c03
image: ghcr.io/cyclonedx/cdxgen:v10.9.5
command:
- /bin/sh
- -c
- |
npm install -g @cyclonedx/cdxgen --omit=optional
cdxgen -t python --deep -o bom.json .
- node
args:
- /opt/cdxgen/bin/cdxgen.js
- -t
- $(params.enricher-reachability-programming-language)
- --deep
- -r
- -p
- -o
- $(workspaces.output.path)/source-code/bom.json
- $(workspaces.output.path)/source-code
- --spec-version
- "1.5"
volumeMounts:
- mountPath: /scratch
name: scratch
- name: run-atom
imagePullPolicy: IfNotPresent
image: ghcr.io/appthreat/atom:v2.0.18@sha256:893ed9ede9eea19540027faf72aa618e2b488192378f590fd2a1277b77712c1a
command:
- /bin/sh
- -c
- |
atom \
reachables \
-o app.atom \
-s reachables.json \
-l python \
.
-o $(workspaces.output.path)/source-code/app.atom \
-s /scratch/reachables.json \
-l $(params.enricher-reachability-programming-language) \
$(workspaces.output.path)/source-code
volumeMounts:
- mountPath: /scratch
name: scratch
- name: run-enricher
imagePullPolicy: IfNotPresent
imagePullPolicy: Always
image: '{{ default "ghcr.io/ocurity/dracon" .Values.image.registry }}/components/enrichers/reachability:{{ .Chart.AppVersion }}'
command: ["/app/components/enrichers/reachability/reachability"]
volumeMounts:
- mountPath: /scratch
name: scratch
env:
- name: READ_PATH
value: $(workspaces.output.path)/.dracon/enrichers/reachability
value: $(workspaces.output.path)/.dracon/producers
- name: WRITE_PATH
value: $(workspaces.output.path)/.dracon/enrichers/reachability
- name: ATOM_FILE_PATH
value: $(workspaces.output.path)/.dracon/enrichers/reachables.json
value: /scratch/reachables.json
4 changes: 2 additions & 2 deletions deploy/dracon/values/dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ kibana:
tlsEnabled: false

mongodb:
enabled: true
enabled: false
auth:
enabled: true
usernames: ["consumer-mongodb"]
passwords: ["consumer-mongodb"]
databases: ["consumer-mongodb"]

arangodb:
enabled: true
enabled: false
version: 3.7.10
ingress:
className: nginx
Expand Down
13 changes: 13 additions & 0 deletions examples/pipelines/reachability-project/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
nameSuffix: -reachability-project
components:
- pkg:helm/dracon-oss-components/base
- pkg:helm/dracon-oss-components/git-clone
- pkg:helm/dracon-oss-components/producer-python-bandit
- pkg:helm/dracon-oss-components/producer-python-pip-safety
- pkg:helm/dracon-oss-components/producer-aggregator
- pkg:helm/dracon-oss-components/enrichers/reachability
- pkg:helm/dracon-oss-components/enricher-codeowners
- pkg:helm/dracon-oss-components/enricher-aggregator
24 changes: 24 additions & 0 deletions examples/pipelines/reachability-project/pipelinerun.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: reachability-project-
namespace: dracon
spec:
pipelineRef:
name: dracon-reachability-project
params:
- name: git-clone-url
value: https://github.com/fportantier/vulpy.git
- name: enricher-reachability-programming-language
value: python
workspaces:
- name: output
subPath: source-code
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi

0 comments on commit 5f78135

Please sign in to comment.