You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CLAUDE.md
+55-8Lines changed: 55 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,11 +8,13 @@ CloudTranscode is bFAN's distributed media transcoding pipeline. It's a set of P
8
8
9
9
-**Language**: PHP 7+ (legacy codebase, but clean)
10
10
-**Container**: Docker (ECS deployment)
11
-
-**FFmpeg**: 4.2 (video/image processing)
11
+
-**FFmpeg**: 4.2 (video/image processing) — **EOL, from 2019. See Security Findings.**
12
12
-**ImageMagick**: convert commands for image transcoding
13
13
-**AWS Services**: Step Functions (SFN), S3, ECS, EC2, IAM
14
+
-**Orchestration**: AWS Step Functions state machines (see `state_machines/`)
14
15
-**SDK**: CloudProcessingEngine-SDK (bFAN fork) for activity polling and lifecycle
15
16
-**Dependencies**: AWS SDK for PHP 3.x, JSON Schema validation
17
+
-**Monitoring**: None configured — no CloudWatch alarms, dashboards, or custom metrics. See Security Findings.
16
18
17
19
## Quick Start
18
20
@@ -81,11 +83,12 @@ Pass custom client class to activity workers via `-C <client class path>` option
81
83
82
84
## Key Patterns
83
85
86
+
-**Step Functions orchestration**: Workflow is defined in `state_machines/` JSON. SFN distributes tasks to activity workers, handles retries and failure routing. This is the control plane — workers are the data plane.
84
87
-**Activity polling**: Workers use long-polling to fetch tasks from AWS SFN
85
-
-**Sequential output processing**: One TranscodeAssetActivity worker processes all outputs in the `output_assets` array sequentially, not in parallel. To parallelize, split the workflow.
88
+
-**Sequential output processing**: One TranscodeAssetActivity worker processes all outputs in the `output_assets` array sequentially, not in parallel. This is a **performance bottleneck** — a 10-output job ties up one worker for the full duration. To parallelize, split the workflow into separate SFN executions or use Map states.
86
89
-**Stateless workers**: Workers are horizontally scalable Docker containers. State lives in S3 and SFN.
87
90
-**Preset-based transcoding**: FFmpeg commands can be templated using presets (e.g., `360p-4.3-generic`)
88
-
-**Custom FFmpeg commands**: JSON input supports raw FFmpeg command strings for advanced use cases
91
+
-**Custom FFmpeg commands**: JSON input supports raw FFmpeg command strings for advanced use cases. **WARNING: command injection risk — see Security Findings.**
89
92
-**Watermarking**: Overlay images on video with custom position, opacity, size
90
93
-**HTTP input**: Workers can pull source files from HTTP/S URLs instead of S3
91
94
@@ -107,9 +110,10 @@ Pass custom client class to activity workers via `-C <client class path>` option
107
110
## Deployment
108
111
109
112
**Current setup:**
110
-
- Docker image built from `Dockerfile` and pushed to ECR: `501431420968.dkr.ecr.eu-west-1.amazonaws.com/sportarc/cloudtranscode:4.2`
113
+
- Docker image built from `Dockerfile` and pushed to ECR (eu-west-1)
111
114
- ECS cluster runs workers as tasks
112
115
- Each worker polls a specific SFN activity ARN
116
+
-**Note**: AWS account ID `501431420968` is hardcoded in the Dockerfile/configs. Use an environment variable or SSM parameter instead.
@@ -129,16 +133,59 @@ Pass custom client class to activity workers via `-C <client class path>` option
129
133
- Check S3 output buckets for transcoded files
130
134
- Review CloudWatch Logs for worker output
131
135
136
+
## Security Findings
137
+
138
+
> AI audit — 2026-02-17. These findings should be tracked as issues and resolved.
139
+
140
+
### CRITICAL — Command Injection via FFmpeg/ImageMagick
141
+
142
+
The transcoder code passes user-supplied JSON parameters (codec, size, preset names, custom command strings) into FFmpeg and ImageMagick shell commands **without escaping or sanitization**. A crafted `output_assets` payload could inject arbitrary shell commands.
143
+
144
+
**Affected files**: `src/activities/transcoders/` — anywhere parameters are interpolated into shell commands.
145
+
146
+
**Fix**: Use `escapeshellarg()` on every user-supplied parameter before interpolation. Better: build argument arrays and use `proc_open()` instead of `exec()`/`shell_exec()` with string concatenation. Validate inputs against an allowlist of known codecs, presets, and sizes.
147
+
148
+
### HIGH — No Rate Limiting
149
+
150
+
There is no throttling on Step Functions task submission. A misconfigured client or runaway automation can flood the pipeline with jobs, exhausting ECS capacity and S3 write throughput.
151
+
152
+
**Fix**: Add SFN execution concurrency limits, or use an SQS queue with a controlled consumer rate in front of the pipeline.
153
+
154
+
### MEDIUM — Hardcoded AWS Account ID
155
+
156
+
AWS account ID `501431420968` appears in ECR URIs and potentially in SFN ARNs throughout the codebase. This leaks infrastructure details and makes multi-account deployment impossible.
157
+
158
+
**Fix**: Replace with environment variables, SSM parameters, or CDK/CloudFormation references.
159
+
160
+
### MEDIUM — FFmpeg 4.2 (2019) — End of Life
161
+
162
+
FFmpeg 4.2 is from August 2019 and no longer receives security patches. Known CVEs in older FFmpeg versions include heap overflows in demuxers and decoders that can be triggered by malformed input media.
163
+
164
+
**Fix**: Upgrade the `sportarc/ffmpeg` and `sportarc/cloudtranscode-base` Docker images to FFmpeg 6.x or 7.x. Test transcoding presets for compatibility.
165
+
166
+
### MEDIUM — No Temp File Encryption
167
+
168
+
Transcoding temp files (downloaded source, intermediate outputs) are stored on local ECS disk unencrypted. If the disk is an EBS volume, data at rest is exposed unless the volume itself has encryption enabled.
169
+
170
+
**Fix**: Ensure ECS instances use encrypted EBS volumes. For sensitive media, consider encrypting temp files at the application level or using instance store with dm-crypt.
171
+
172
+
### LOW — No CloudWatch Monitoring
173
+
174
+
No CloudWatch alarms, custom metrics, or dashboards are configured. Worker failures, SFN execution errors, and S3 throughput issues are invisible without manual console checks.
175
+
176
+
**Fix**: Add CloudWatch alarms for SFN execution failures, ECS task stopped events, and worker heartbeat gaps. Publish custom metrics for transcode duration, queue depth, and error rates.
177
+
132
178
## Gotchas
133
179
134
-
-**Sequential processing**: TranscodeAssetActivity processes all outputs sequentially. For parallel transcoding of multiple outputs, you must split the workflow or run multiple workers with separate SFN tasks.
180
+
-**Sequential processing bottleneck**: TranscodeAssetActivity processes all outputs sequentially. A single job with many outputs blocks the worker. Split into parallel SFN branches or use Map states.
135
181
-**Docker base image dependency**: This repo depends on two SportArchive Docker images (`sportarc/ffmpeg`, `sportarc/cloudtranscode-base`). If those images are updated, rebuild this image.
136
-
-**FFmpeg version**: Locked to 4.2. Upgrading FFmpeg requires updating the base image.
182
+
-**FFmpeg version**: Locked to 4.2 (2019, EOL). Upgrading FFmpeg requires updating the base image and retesting all presets.
137
183
-**Client interface requirement**: For production use, you MUST implement a custom client interface class and extend the Dockerfile to include it. Without it, workers run but don't notify client apps of progress/completion.
138
184
-**AWS SFN long polling**: Workers block on GetActivityTask calls (long polling). If AWS SFN is unavailable, workers will hang until timeout.
139
-
-**Temp disk space**: Transcoding uses local disk for temporary files. Ensure ECS instances or Docker volumes have sufficient space for large video files.
185
+
-**Temp disk space**: Transcoding uses local disk for temporary files. Ensure ECS instances or Docker volumes have sufficient space for large video files. Temp files are **not encrypted** at the application level.
140
186
-**Presets location**: The `presets/` directory in this repo may be deprecated. Check if CloudTranscode-FFMpeg-presets is the canonical source.
187
+
-**Hardcoded account ID**: `501431420968` is baked into ECR URIs and possibly SFN ARNs. Must be parameterized for multi-account use.
141
188
142
189
<!-- Ask: What happens if a worker crashes mid-transcode? Does SFN retry, or is the task lost? Are there heartbeat intervals configured? -->
143
190
<!-- Ask: How are FFmpeg presets loaded — from this repo's presets/ dir, or from CloudTranscode-FFMpeg-presets? -->
144
-
<!-- Ask: What's the relationship between this repo and CloudTranscode-Lambda? When is Lambda used vs ECS workers? -->
191
+
<!-- Ask: What's the relationship between this repo and CloudTranscode-Lambda? When is Lambda used vs ECS workers? -->
0 commit comments