Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions internal/platform/platform_common_maven.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package platform

import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/AikidoSec/safechain-internals/internal/utils"
)

func installMavenRcOverride(mavenrcPath, startMarker, endMarker, contentLine string, filePerm os.FileMode) error {
filename := filepath.Base(mavenrcPath)

content := ""
if data, err := os.ReadFile(mavenrcPath); err == nil {
Comment on lines +15 to +16
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential file inclusion attack via reading file - high severity
If an attacker can control the input leading into the ReadFile function, they might be able to read sensitive files and launch further attacks with that information.

Show Fix

Aikido AutoFix Patch Suggestion - medium confidence
This patch mitigates potential file inclusion attacks by implementing input validation for the ReadFile function.

This will fix the Potential file inclusion attack via reading file issue detected on line: 16.

Suggested change
content := ""
if data, err := os.ReadFile(mavenrcPath); err == nil {
if strings.Contains(mavenrcPath, "../") || strings.Contains(mavenrcPath, "..\\") {
return fmt.Errorf("invalid file path")
}
content := ""
if data, err := os.ReadFile(mavenrcPath); err == nil {

View details in Aikido Security

content = string(data)
} else if !os.IsNotExist(err) {
return fmt.Errorf("failed to read %s: %w", filename, err)
}

if strings.Contains(content, startMarker) {
if !strings.Contains(content, endMarker) {
return fmt.Errorf("found start marker in %s but not end marker - corrupt configuration", filename)
}
return nil
}

lineEnding := "\n"
if strings.Contains(content, "\r\n") {
lineEnding = "\r\n"
}

if content != "" && !strings.HasSuffix(content, "\n") && !strings.HasSuffix(content, "\r\n") {
content += lineEnding
}

block := strings.Join([]string{startMarker, contentLine, endMarker}, lineEnding) + lineEnding
return os.WriteFile(mavenrcPath, []byte(content+block), filePerm)
}

func uninstallMavenRcOverride(mavenrcPath, startMarker, endMarker string, filePerm os.FileMode) error {
filename := filepath.Base(mavenrcPath)

data, err := os.ReadFile(mavenrcPath)
Copy link
Copy Markdown
Contributor

@aikido-pr-checks aikido-pr-checks Bot Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential file inclusion attack via reading file - high severity
If an attacker can control the input leading into the ReadFile function, they might be able to read sensitive files and launch further attacks with that information.

Show Fix

Aikido AutoFix Patch Suggestion - medium confidence
This patch mitigates potential file inclusion attacks by implementing input validation for the ReadFile function.

This will fix the Potential file inclusion attack via reading file issue detected on line: 45.

Suggested change
data, err := os.ReadFile(mavenrcPath)
if strings.Contains(mavenrcPath, "../") || strings.Contains(mavenrcPath, "..\\") {
return fmt.Errorf("invalid file path")
}
data, err := os.ReadFile(mavenrcPath)

View details in Aikido Security

if err != nil {
if os.IsNotExist(err) {
return nil
}
return fmt.Errorf("failed to read %s: %w", filename, err)
}

newContent, removed, err := utils.RemoveMarkedBlock(string(data), startMarker, endMarker)
if err != nil {
return err
}
if !removed {
return nil
}

return os.WriteFile(mavenrcPath, []byte(newContent), filePerm)
}
67 changes: 21 additions & 46 deletions internal/platform/platform_darwin_maven.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,65 +3,40 @@
package platform

import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/AikidoSec/safechain-internals/internal/utils"
)

const (
mavenRcMarkerStart = "# aikido-safe-chain-start"
mavenRcMarkerEnd = "# aikido-safe-chain-end"
mavenRcBlock = mavenRcMarkerStart + "\n" +
`export MAVEN_OPTS="$MAVEN_OPTS -Daikido.safechain.mavenopts=true -Djavax.net.ssl.trustStoreType=KeychainStore -Djavax.net.ssl.trustStore=NONE"` + "\n" +
mavenRcMarkerEnd + "\n"
mavenRcFilePerm = 0o644
mavenRcFilePerm = 0o644
mavenRcFilename = ".mavenrc"
mavenRcLine = `export MAVEN_OPTS="$MAVEN_OPTS -Daikido.safechain.mavenopts=true -Djavax.net.ssl.trustStoreType=KeychainStore -Djavax.net.ssl.trustStore=NONE"`
)

func InstallMavenOptsOverride(homeDir string) error {
mavenrcPath := filepath.Join(homeDir, ".mavenrc")

content := ""
if data, err := os.ReadFile(mavenrcPath); err == nil {
content = string(data)
} else if !os.IsNotExist(err) {
return fmt.Errorf("failed to read .mavenrc: %w", err)
}

if strings.Contains(content, mavenRcMarkerStart) {
if !strings.Contains(content, mavenRcMarkerEnd) {
return fmt.Errorf("found start marker in .mavenrc but not end marker - corrupt configuration")
}
return nil
}

if content != "" && !strings.HasSuffix(content, "\n") {
content += "\n"
}

return os.WriteFile(mavenrcPath, []byte(content+mavenRcBlock), mavenRcFilePerm)
mavenrcPath := filepath.Join(homeDir, mavenRcFilename)
return installMavenRcOverride(mavenrcPath,
mavenRcMarkerStart,
mavenRcMarkerEnd,
mavenRcLine,
mavenRcFilePerm,
)
}

func UninstallMavenOptsOverride(homeDir string) error {
mavenrcPath := filepath.Join(homeDir, ".mavenrc")

data, err := os.ReadFile(mavenrcPath)
if err != nil {
if os.IsNotExist(err) {
return nil
}
return fmt.Errorf("failed to read .mavenrc: %w", err)
}
mavenrcPath := filepath.Join(homeDir, mavenRcFilename)
return uninstallMavenRcOverride(mavenrcPath,
mavenRcMarkerStart,
mavenRcMarkerEnd,
mavenRcFilePerm,
)
}

newContent, removed, err := utils.RemoveMarkedBlock(string(data), mavenRcMarkerStart, mavenRcMarkerEnd)
if err != nil {
return err
}
if !removed {
return nil
func GetMavenHomeDir() (string, error) {
if config.HomeDir != "" {
return config.HomeDir, nil
}

return os.WriteFile(mavenrcPath, []byte(newContent), mavenRcFilePerm)
return os.UserHomeDir()
}
9 changes: 9 additions & 0 deletions internal/platform/platform_other_maven.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

package platform

import "os"

func InstallMavenOptsOverride(_ string) error { return nil }

func UninstallMavenOptsOverride(_ string) error { return nil }

func GetMavenHomeDir() (string, error) {
if config.HomeDir != "" {
return config.HomeDir, nil
}
return os.UserHomeDir()
}
33 changes: 31 additions & 2 deletions internal/platform/platform_windows_maven.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,35 @@

package platform

func InstallMavenOptsOverride(_ string) error { return nil }
import "path/filepath"

func UninstallMavenOptsOverride(_ string) error { return nil }
const (
mavenRcMarkerStart = "REM aikido-safe-chain-start"
mavenRcMarkerEnd = "REM aikido-safe-chain-end"
mavenRcFilePerm = 0o644
mavenRcFilename = "mavenrc_pre.cmd"
mavenRcLine = `set "MAVEN_OPTS=%MAVEN_OPTS% -Daikido.safechain.mavenopts=true -Djavax.net.ssl.trustStoreType=Windows-ROOT -Djavax.net.ssl.trustStore=NONE"`
)

func InstallMavenOptsOverride(homeDir string) error {
return installMavenRcOverride(
filepath.Join(homeDir, mavenRcFilename),
mavenRcMarkerStart,
mavenRcMarkerEnd,
mavenRcLine,
mavenRcFilePerm,
)
}

func UninstallMavenOptsOverride(homeDir string) error {
return uninstallMavenRcOverride(
filepath.Join(homeDir, mavenRcFilename),
mavenRcMarkerStart,
mavenRcMarkerEnd,
mavenRcFilePerm,
)
}

func GetMavenHomeDir() (string, error) {
return GetActiveUserHomeDir()
}
12 changes: 9 additions & 3 deletions internal/setup/steps/02_configure_maven/step.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,17 @@ func (s *Step) Install(ctx context.Context) error {
return fmt.Errorf("invalid proxy URL: missing host or port (got host=%q, port=%q)", host, port)
}

homeDir := platform.GetConfig().HomeDir
homeDir, err := platform.GetMavenHomeDir()
if err != nil {
return fmt.Errorf("failed to resolve user home directory: %v", err)
}

// Configure Maven proxy settings
if err := installMavenProxySetting(homeDir, host, port); err != nil {
log.Printf("Warning: failed to configure Maven proxy settings: %v", err)
}

// Configure MAVEN_OPTS to use system truststore on macOS
// Configure MAVEN_OPTS to use the OS truststore
if err := platform.InstallMavenOptsOverride(homeDir); err != nil {
log.Printf("Warning: failed to persist MAVEN_OPTS truststore override: %v", err)
}
Expand All @@ -65,7 +68,10 @@ func (s *Step) Install(ctx context.Context) error {
}

func (s *Step) Uninstall(ctx context.Context) error {
homeDir := platform.GetConfig().HomeDir
homeDir, err := platform.GetMavenHomeDir()
if err != nil {
return fmt.Errorf("failed to resolve user home directory: %v", err)
}

if err := uninstallMavenProxySetting(homeDir); err != nil {
log.Printf("Warning: failed to remove Maven proxy settings: %v", err)
Expand Down