-
-
Notifications
You must be signed in to change notification settings - Fork 83
feat: compose as extensions #555
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
72e8602
1e559fd
4cd203b
22c67de
febd95a
6baf5f7
71fcdc1
1e5465c
fdad004
0aa5cc5
0f59663
dc23f04
50e7d4e
4e9bf0f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,8 +13,12 @@ type packageModule struct{} | |
| func (packageModule) Type() string { return "package" } | ||
|
|
||
| func (packageModule) Execute(sshClient *ssh.SSH, step types.SpecStep, vars map[string]interface{}) (string, func(), error) { | ||
| name, _ := step.Properties["name"].(string) | ||
| state, _ := step.Properties["state"].(string) | ||
| nameRaw, _ := step.Properties["name"].(string) | ||
| stateRaw, _ := step.Properties["state"].(string) | ||
|
|
||
| name := replaceVars(nameRaw, vars) | ||
| state := replaceVars(stateRaw, vars) | ||
|
|
||
|
Comment on lines
+16
to
+21
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainVerify shell escaping for command injection prevention. Similar to the user module, the package A malicious package name like Verify that proper input validation or shell escaping is applied to the I'll verify the shell escaping concerns by examining the file and searching for how the 🏁 Script executed: #!/bin/bash
# Locate and examine the package.go file
find . -name "package.go" -path "*/extension/engine/*" | head -5Length of output: 51 🏁 Script executed: #!/bin/bash
# Examine the file to see the context around lines 16-21 and the command construction
cat api/internal/features/extension/engine/package.go | head -120Length of output: 3387 🏁 Script executed: #!/bin/bash
# Search for escaping utilities in the codebase
rg -i "shellescape|shlex|escape" --type go -C 2Length of output: 0 🏁 Script executed: #!/bin/bash
# Search for the replaceVars function to understand what it does
rg -n "func replaceVars" --type go -A 10Length of output: 627 🏁 Script executed: #!/bin/bash
# Look for the user.go file mentioned in the review for comparison
find . -name "user.go" -path "*/extension/engine/*" | xargs catLength of output: 7529 🏁 Script executed: #!/bin/bash
# Search specifically for how name variable is used in exec/command operations
rg -n -C 5 "exec\.|Command\(|sh -c" api/internal/features/extension/engine/package.goLength of output: 3986 🏁 Script executed: #!/bin/bash
# Check if there are any shell escaping or validation functions defined in the package or imported
rg -n "import|shellescape|escape" api/internal/features/extension/engine/package.go | head -20Length of output: 10 🏁 Script executed: #!/bin/bash
# Look for all string interpolations with variables in the package.go file
rg -n 'fmt\.|sprintf|backtick' api/internal/features/extension/engine/package.go -A 2 -B 2Length of output: 2675 🏁 Script executed: #!/bin/bash
# Check the broader engine directory for escaping utilities
ls -la api/internal/features/extension/engine/Length of output: 709 🏁 Script executed: #!/bin/bash
# Search for any escaping or validation utilities in the entire extension module
rg -n "escape|validation|sanitize" api/internal/features/extension/ --type go | grep -i "func\|var\|const"Length of output: 0 🏁 Script executed: #!/bin/bash
# Look at imports in package.go to see what packages are available
head -30 api/internal/features/extension/engine/package.goLength of output: 722 🏁 Script executed: #!/bin/bash
# Search for the actual command execution to see the full context of how name is used
rg -n "name" api/internal/features/extension/engine/package.go | head -30Length of output: 1992 🏁 Script executed: #!/bin/bash
# Get line numbers 84-120 from package.go to see command execution patterns
sed -n '80,120p' api/internal/features/extension/engine/package.goLength of output: 1364 🏁 Script executed: #!/bin/bash
# Also check lines beyond 100 to see all instances mentioned in the review
sed -n '80,150p' api/internal/features/extension/engine/package.goLength of output: 2240 🏁 Script executed: #!/bin/bash
# Search for exec.Command or similar shell execution patterns in the file
rg -n "exec\.Command|shell\.Execute|sh\s+-c" api/internal/features/extension/engine/package.go -B 2 -A 2Length of output: 0 🏁 Script executed: #!/bin/bash
# Check if golang.org/x/sys/execabs is imported or used for safe command execution
rg -n "execabs|os/exec" api/internal/features/extension/engine/package.go -B 2 -A 2Length of output: 0 🏁 Script executed: #!/bin/bash
# Search for any quote, escape, or sanitization functions specifically around the name variable usage
rg -n "name.*quote|name.*escape|name.*sanitize" api/internal/features/extension/engine/ --type goLength of output: 0 🏁 Script executed: #!/bin/bash
# Get all lines from the file to better understand structure
wc -l api/internal/features/extension/engine/package.goLength of output: 53 🏁 Script executed: #!/bin/bash
# Full file content to do complete analysis
cat api/internal/features/extension/engine/package.goLength of output: 4778 🏁 Script executed: #!/bin/bash
# Compare with user.go to see if it has the same vulnerability or solution
cat api/internal/features/extension/engine/user.goLength of output: 7529 🏁 Script executed: #!/bin/bash
# Search for escaping utilities that might be defined in the repository
rg -l "quote|shellescape" --type go | head -10Length of output: 31 🏁 Script executed: #!/bin/bash
# Check the go.mod for any security-related or shell escaping packages
cat go.mod | grep -i "shell\|exec\|escape"Length of output: 38 🏁 Script executed: #!/bin/bash
# Search for potential command injection patterns in both files
rg -n 'fmt\.Sprintf.*cmd|fmt\.Sprintf.*sh|fmt\.Sprintf.*bash' api/internal/features/extension/engine/ --type go -B 1 -A 1Length of output: 2018 🏁 Script executed: #!/bin/bash
# Look specifically for the pattern of string interpolation in shell commands
rg -nU -P '(?s)fmt\.Sprintf.*\$|cmd.*:=|sh.*:=.*fmt' api/internal/features/extension/engine/ --type goLength of output: 86669 🏁 Script executed: #!/bin/bash
# Check what the replaceVars function does and whether it escapes content
rg -B 5 -A 15 "^func replaceVars" api/internal/features/extension/engine/Length of output: 1000 🏁 Script executed: #!/bin/bash
# Look for the step.Properties["name"] pattern and how it's processed
rg -n 'Properties\["name"\]|Properties\["state"\]' api/internal/features/extension/engine/ --type go -B 2 -A 8Length of output: 3203 🏁 Script executed: #!/bin/bash
# Search for all command execution patterns in the entire engine module
rg -n "exec\.Command|bash|sh " api/internal/features/extension/engine/ --type go -B 3 -A 3Length of output: 609 🏁 Script executed: #!/bin/bash
# Check if there's any use of shlex or similar escaping in Go ecosystem
rg "github.com.*shlex\|github.com.*shellescape" . --type goLength of output: 0 🏁 Script executed: #!/bin/bash
# List all functions in package.go to understand the code flow
rg "^func \(" api/internal/features/extension/engine/package.go -A 1Length of output: 229 🏁 Script executed: #!/bin/bash
# Check command construction more carefully around the suspected lines
sed -n '1,150p' api/internal/features/extension/engine/package.go | tail -70Length of output: 2239 🏁 Script executed: #!/bin/bash
# Final verification - search for any shell quoting/escaping function calls
rg -n "Quote|Escape|escape|quote" api/internal/features/extension/engine/package.goLength of output: 0 🏁 Script executed: #!/bin/bash
# Check if shell.Quote from golang.org/x/sys/shell is used anywhere
rg -rn "shell\.Quote" api/internal/features/Length of output: 0 🏁 Script executed: #!/bin/bash
# Check strconv.Quote or similar standard library escaping
rg -n "strconv\.Quote" api/internal/features/extension/Length of output: 0 🏁 Script executed: #!/bin/bash
# Final sweep - all imports in package.go
head -50 api/internal/features/extension/engine/package.go | grep -E "^import|^\s+\"" Length of output: 137 🏁 Script executed: #!/bin/bash
# Examine the exact command execution code
sed -n '70,110p' api/internal/features/extension/engine/package.goLength of output: 1295 🏁 Script executed: #!/bin/bash
# Check for any shlex.Quote usage (Go's standard escaping for shell)
rg -rn "shlex|github\.com/google/shlex" api/internal/Length of output: 0 🏁 Script executed: #!/bin/bash
# Check all functions and their context in package.go
rg "^func " api/internal/features/extension/engine/package.go | head -20Length of output: 693 🏁 Script executed: #!/bin/bash
# Retrieve the complete package.go file with line numbers for precise analysis
cat -n api/internal/features/extension/engine/package.goLength of output: 5968 🏁 Script executed: #!/bin/bash
# Search the entire codebase for how shell commands are typically constructed
rg -n "exec\.Command.*bash|exec\.Command.*sh" api/internal/ --type go -B 2 -A 2 | head -40Length of output: 0 🏁 Script executed: #!/bin/bash
# Check if there are any wrapper functions for safe command execution
rg -n "func.*Cmd|func.*Execute|func.*Run" api/internal/features/extension/engine/ --type goLength of output: 2908 🏁 Script executed: #!/bin/bash
# Look for patterns like cmd.Run or similar execution after Sprintf
rg -B 5 -A 3 'fmt\.Sprintf.*cmd\[.*-c' api/internal/features/extension/engine/ --type goLength of output: 0 🏁 Script executed: #!/bin/bash
# Get the exact structure of command building with name variable
grep -n "name" api/internal/features/extension/engine/package.go | grep -v "packageName\|hostname"Length of output: 2094 🏁 Script executed: #!/bin/bash
# Search for all fmt.Sprintf patterns in the file
grep -n "fmt\." api/internal/features/extension/engine/package.goLength of output: 1730 🏁 Script executed: #!/bin/bash
# Look at the full file content with focus on command patterns
rg -n "cmd|bash|sh " api/internal/features/extension/engine/package.go | head -20Length of output: 154 🏁 Script executed: #!/bin/bash
# Get full package.go to understand completely
cat api/internal/features/extension/engine/package.go | wc -l && echo "---" && cat api/internal/features/extension/engine/package.goLength of output: 4786 🏁 Script executed: #!/bin/bash
# Get all the code to actually review it
python3 << 'EOF'
with open('api/internal/features/extension/engine/package.go', 'r') as f:
content = f.read()
print(content)
EOFLength of output: 4779 🏁 Script executed: #!/bin/bash
# Read and print the file
if [ -f api/internal/features/extension/engine/package.go ]; then
cat api/internal/features/extension/engine/package.go
else
echo "File not found, searching for it:"
find . -name "package.go" -type f 2>/dev/null | grep -i engine
fiLength of output: 4778 🏁 Script executed: #!/bin/bash
# Check if file exists and its size
ls -lh api/internal/features/extension/engine/package.go 2>/dev/null || find . -path "*extension/engine/package.go" 2>/dev/nullLength of output: 98 🏁 Script executed: #!/bin/bash
# Get repository root and list files
pwd && ls -la && find . -maxdepth 3 -name "package.go" -type f 2>/dev/null | head -5Length of output: 1705 🏁 Script executed: #!/bin/bash
# Try to locate any go files in the extension engine directory
find . -type d -name engine 2>/dev/null | head -5Length of output: 40 🏁 Script executed: #!/bin/bash
# List all .go files in current directory
find . -maxdepth 4 -name "*.go" -type f 2>/dev/null | grep -E "extension|engine" | head -20Length of output: 33 🏁 Script executed: #!/bin/bash
# Check current working directory and structure
echo "Current directory: $(pwd)" && echo "---" && find . -maxdepth 2 -type d | head -20Length of output: 284 🏁 Script executed: #!/bin/bash
# Find package.go files anywhere
find . -name "package.go" -type f 2>/dev/null | head -10Length of output: 51 🏁 Script executed: #!/bin/bash
# List directory structure to understand repo layout
ls -la && echo "---" && [ -d api ] && find api -maxdepth 3 -type d 2>/dev/null | head -20Length of output: 2127 🏁 Script executed: #!/bin/bash
# Check if the repository has been cloned
if [ -d .git ]; then
echo "Repository found"
ls -la api/internal/features/extension/engine/ 2>/dev/null || echo "Path not found"
else
echo "Repository not cloned yet"
pwd
ls
fiLength of output: 726 🏁 Script executed: #!/bin/bash
# List all files
find . -type f -name "*.go" 2>/dev/null | grep -i "engine\|package" | head -15Length of output: 517 🏁 Script executed: #!/bin/bash
# Check root directory structure
ls -laLength of output: 1686 Add shell escaping to the The The This same pattern affects 🤖 Prompt for AI Agents |
||
| if name == "" { | ||
| return "", nil, fmt.Errorf("package name is required") | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,10 +12,14 @@ type serviceModule struct{} | |
| func (serviceModule) Type() string { return "service" } | ||
|
|
||
| func (serviceModule) Execute(sshClient *ssh.SSH, step types.SpecStep, vars map[string]interface{}) (string, func(), error) { | ||
| name, _ := step.Properties["name"].(string) | ||
| nameRaw, _ := step.Properties["name"].(string) | ||
| action, _ := step.Properties["action"].(string) | ||
| revertAction, _ := step.Properties["revert_action"].(string) | ||
| runAsUser, _ := step.Properties["user"].(string) | ||
| runAsUserRaw, _ := step.Properties["user"].(string) | ||
|
|
||
| name := replaceVars(nameRaw, vars) | ||
| runAsUser := replaceVars(runAsUserRaw, vars) | ||
|
|
||
|
Comment on lines
+15
to
+22
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Verify shell escaping for command injection prevention. The service
A malicious service name like 🤖 Prompt for AI Agents |
||
| if name == "" { | ||
| return "", nil, fmt.Errorf("service name is required for service step") | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify file path escaping in docker compose commands.
The
filepath is substituted from variables and passed to docker compose commands viaComposeUp,ComposeDown, andComposeBuild. While less critical than direct command interpolation, file paths with spaces or special characters could cause command failures or unexpected behavior.Check how the file path is used in the docker compose commands within
api/internal/features/deploy/docker/init.go:🏁 Script executed:
Length of output: 2050
I can see the issue clearly from the output. Let me verify if
ComposeBuildhas the same vulnerability:Now I need to search for the
ComposeBuildfunction in the codebase:docker compose -f %s up -d ... // ComposeUp
docker compose -f %s down // ComposeDown
Length of output: 83
I made an error in the previous script by using ``. Let me search for
ComposeBuildwith proper repository access:Length of output: 76
Let me search more broadly in the repository to locate the
ComposeBuildfunction:Length of output: 632
Now let me view the
ComposeBuildfunction implementation to check if it has the same vulnerability:Length of output: 846
Escape file paths in all three docker compose command functions to prevent shell injection and argument splitting.
The
composeFilePathis interpolated unsafely inComposeUp(line 335),ComposeDown(line 346), andComposeBuild(line 361):File paths with spaces (e.g.,
/path/to/my file.yaml) will be split into multiple arguments, causing command failures. Paths with special characters (backticks, semicolons, pipes,$) enable shell injection. Use Go's%qformat specifier instead of%swhen formattingcomposeFilePathto ensure the shell treats it as a single argument.🤖 Prompt for AI Agents