-
Notifications
You must be signed in to change notification settings - Fork 1
Smart contract development editor with AI #15
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
base: main
Are you sure you want to change the base?
Conversation
- Added the `github.com/sashabaranov/go-openai` dependency to `go.mod` for integrating OpenAI functionalities. - Updated `sqlc.yaml` to include an additional SQL queries file for development queries, improving database operations. - Introduced new SQL queries in `dev-queries.sql` for managing projects, including listing, creating, and deleting projects. - Enhanced the database model in `models.go` to include new structures for conversations and tool calls, supporting additional functionalities. - Refactored the `querier.go` interface to include new methods for managing conversations and tool calls, ensuring better separation of concerns. These changes improve the overall functionality and maintainability of the application, providing better tools for project management and database interactions. Signed-off-by: David VIEJO <dviejo@kungfusoftware.es>
return errors.New("dir is required") | ||
} | ||
base := filepath.Join(project, dir) | ||
return os.MkdirAll(base, 0755) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 2 days ago
To fix the issue, the dir
parameter must be validated before constructing the file path. Validation should ensure that:
- The
dir
parameter does not contain path traversal sequences (..
) or path separators (/
or\
). - The resolved path remains within the intended directory scope.
The best approach is to:
- Normalize the
dir
parameter usingfilepath.Clean
. - Check for invalid characters or sequences (
..
,/
,\
) in the cleaned path. - Ensure the resolved path is within the
project
directory usingfilepath.Abs
andstrings.HasPrefix
.
Changes are required in the CreateDir
method in pkg/scai/dirs/dirs.go
.
-
Copy modified lines R56-R67
@@ -55,4 +55,14 @@ | ||
} | ||
base := filepath.Join(project, dir) | ||
return os.MkdirAll(base, 0755) | ||
// Normalize and validate the directory name | ||
cleanDir := filepath.Clean(dir) | ||
if strings.Contains(cleanDir, "..") || strings.Contains(cleanDir, "/") || strings.Contains(cleanDir, "\\") { | ||
return errors.New("invalid directory name") | ||
} | ||
// Ensure the resolved path is within the project directory | ||
base := filepath.Join(project, cleanDir) | ||
absBase, err := filepath.Abs(base) | ||
if err != nil || !strings.HasPrefix(absBase, filepath.Clean(project)) { | ||
return errors.New("directory path is outside the project scope") | ||
} | ||
return os.MkdirAll(absBase, 0755) | ||
} |
return errors.New("dir is required") | ||
} | ||
base := filepath.Join(project, dir) | ||
return os.RemoveAll(base) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 2 days ago
To fix the issue, the dir
parameter must be validated before constructing file paths. Validation should ensure that:
- The
dir
parameter does not contain path traversal sequences (..
) or path separators (/
or\
). - The resolved path remains within the intended project directory.
The best approach is to:
- Normalize the path using
filepath.Abs
and ensure it is within theproject
directory. - Reject any input containing invalid characters or sequences.
Changes are required in the DeleteDir
, ListDirs
, CreateDir
, and ListEntries
methods in pkg/scai/dirs/dirs.go
.
-
Copy modified lines R35-R38 -
Copy modified lines R59-R62 -
Copy modified lines R73-R76 -
Copy modified lines R88-R91
@@ -34,3 +34,6 @@ | ||
// Scope to project root | ||
base := filepath.Join(project, dir) | ||
base, err := filepath.Abs(filepath.Join(project, dir)) | ||
if err != nil || !strings.HasPrefix(base, filepath.Clean(project)+string(os.PathSeparator)) { | ||
return nil, errors.New("invalid directory path") | ||
} | ||
entries, err := os.ReadDir(base) | ||
@@ -55,3 +58,6 @@ | ||
} | ||
base := filepath.Join(project, dir) | ||
base, err := filepath.Abs(filepath.Join(project, dir)) | ||
if err != nil || !strings.HasPrefix(base, filepath.Clean(project)+string(os.PathSeparator)) { | ||
return errors.New("invalid directory path") | ||
} | ||
return os.MkdirAll(base, 0755) | ||
@@ -66,3 +72,6 @@ | ||
} | ||
base := filepath.Join(project, dir) | ||
base, err := filepath.Abs(filepath.Join(project, dir)) | ||
if err != nil || !strings.HasPrefix(base, filepath.Clean(project)+string(os.PathSeparator)) { | ||
return errors.New("invalid directory path") | ||
} | ||
return os.RemoveAll(base) | ||
@@ -78,3 +87,6 @@ | ||
} | ||
base := filepath.Join(project, dir) | ||
base, err := filepath.Abs(filepath.Join(project, dir)) | ||
if err != nil || !strings.HasPrefix(base, filepath.Clean(project)+string(os.PathSeparator)) { | ||
return nil, nil, nil, errors.New("invalid directory path") | ||
} | ||
entries, err := os.ReadDir(base) |
dir = "." | ||
} | ||
base := filepath.Join(project, dir) | ||
entries, err := os.ReadDir(base) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix the issue, the dir
parameter must be validated to ensure it does not contain path traversal sequences (..
) or absolute paths. Additionally, the resolved path should be checked to ensure it remains within the intended project directory.
Steps to implement the fix:
- Add validation logic to check for invalid characters or sequences in the
dir
parameter (e.g.,..
,/
,\
). - Resolve the full path using
filepath.Abs
and verify that it is within theproject
root directory. - Reject the request with an appropriate error message if validation fails.
-
Copy modified lines R79-R82 -
Copy modified lines R84-R88
@@ -78,4 +78,12 @@ | ||
} | ||
// Validate the `dir` parameter to prevent path traversal | ||
if strings.Contains(dir, "..") || strings.Contains(dir, "/") || strings.Contains(dir, "\\") { | ||
return nil, nil, nil, errors.New("invalid directory path") | ||
} | ||
base := filepath.Join(project, dir) | ||
entries, err := os.ReadDir(base) | ||
absBase, err := filepath.Abs(base) | ||
if err != nil || !strings.HasPrefix(absBase, filepath.Clean(project)) { | ||
return nil, nil, nil, errors.New("directory path is outside the project root") | ||
} | ||
entries, err := os.ReadDir(absBase) | ||
if err != nil { |
-
Copy modified lines R196-R201
@@ -195,2 +195,8 @@ | ||
} | ||
// Validate the `dir` parameter to prevent path traversal | ||
if strings.Contains(dir, "..") || strings.Contains(dir, "/") || strings.Contains(dir, "\\") { | ||
return errors.NewValidationError("invalid directory path", map[string]interface{}{ | ||
"error": "path traversal detected", | ||
}) | ||
} | ||
projectRoot, err := h.getProjectRoot(r) |
continue | ||
} | ||
dirPath := filepath.Join(base, name) | ||
dirEntries, err := os.ReadDir(dirPath) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix the issue, the user-provided dir
parameter must be validated before being used in path construction. Validation should ensure that:
- The
dir
parameter does not contain path traversal sequences (..
) or path separators (/
or\
). - The resolved path remains within the intended directory scope.
The best approach is to:
- Normalize the
dir
parameter usingfilepath.Clean
. - Check that the resolved path is within the
project
root directory usingfilepath.Abs
andstrings.HasPrefix
.
Changes will be made to the ListEntries
, ListDirs
, CreateDir
, and DeleteDir
methods in pkg/scai/dirs/dirs.go
to validate the dir
parameter.
-
Copy modified line R34 -
Copy modified lines R36-R40 -
Copy modified line R60 -
Copy modified lines R62-R66 -
Copy modified line R76 -
Copy modified lines R78-R82 -
Copy modified line R93 -
Copy modified lines R95-R99
@@ -33,5 +33,9 @@ | ||
} | ||
// Scope to project root | ||
dir = filepath.Clean(dir) | ||
base := filepath.Join(project, dir) | ||
entries, err := os.ReadDir(base) | ||
absBase, err := filepath.Abs(base) | ||
if err != nil || !strings.HasPrefix(absBase, project) { | ||
return nil, errors.New("invalid directory path") | ||
} | ||
entries, err := os.ReadDir(absBase) | ||
if err != nil { | ||
@@ -55,4 +59,9 @@ | ||
} | ||
dir = filepath.Clean(dir) | ||
base := filepath.Join(project, dir) | ||
return os.MkdirAll(base, 0755) | ||
absBase, err := filepath.Abs(base) | ||
if err != nil || !strings.HasPrefix(absBase, project) { | ||
return errors.New("invalid directory path") | ||
} | ||
return os.MkdirAll(absBase, 0755) | ||
} | ||
@@ -66,4 +75,9 @@ | ||
} | ||
dir = filepath.Clean(dir) | ||
base := filepath.Join(project, dir) | ||
return os.RemoveAll(base) | ||
absBase, err := filepath.Abs(base) | ||
if err != nil || !strings.HasPrefix(absBase, project) { | ||
return errors.New("invalid directory path") | ||
} | ||
return os.RemoveAll(absBase) | ||
} | ||
@@ -78,4 +92,9 @@ | ||
} | ||
dir = filepath.Clean(dir) | ||
base := filepath.Join(project, dir) | ||
entries, err := os.ReadDir(base) | ||
absBase, err := filepath.Abs(base) | ||
if err != nil || !strings.HasPrefix(absBase, project) { | ||
return nil, nil, nil, errors.New("invalid directory path") | ||
} | ||
entries, err := os.ReadDir(absBase) | ||
if err != nil { |
dir = "." | ||
} | ||
base := filepath.Join(project, dir) | ||
entries, err := ioutil.ReadDir(base) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 2 days ago
To fix the issue, we need to validate the dir
parameter before using it to construct a file path. The validation should ensure that:
- The
dir
parameter does not contain any path traversal sequences (..
) or path separators (/
or\
). - The resolved path remains within the intended directory (
project
).
The best approach is to:
- Use
filepath.Abs
to resolve the absolute path of the constructedbase
directory. - Check that the resolved path starts with the
project
directory usingstrings.HasPrefix
.
Changes are required in the ListFiles
method in pkg/scai/files/files.go
.
-
Copy modified lines R34-R38
@@ -33,3 +33,7 @@ | ||
base := filepath.Join(project, dir) | ||
entries, err := ioutil.ReadDir(base) | ||
absBase, err := filepath.Abs(base) | ||
if err != nil || !strings.HasPrefix(absBase, filepath.Clean(project)+string(os.PathSeparator)) { | ||
return nil, errors.New("invalid directory path") | ||
} | ||
entries, err := ioutil.ReadDir(absBase) | ||
if err != nil { |
return errors.New("path is required") | ||
} | ||
base := filepath.Join(project, path) | ||
return os.Remove(base) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 2 days ago
To fix the issue, the path
parameter must be validated before constructing the file path and performing the file operation. The validation should ensure:
- The
path
does not contain any../
sequences or absolute paths. - The resolved path remains within the intended directory (
project
).
The best approach is to use filepath.Abs
to resolve the absolute path and verify that it starts with the project
directory. If the validation fails, the method should return an error.
Changes are required in the DeleteFile
method in pkg/scai/files/files.go
.
-
Copy modified line R76 -
Copy modified lines R78-R82
@@ -75,4 +75,9 @@ | ||
} | ||
// Resolve the absolute path and validate it | ||
base := filepath.Join(project, path) | ||
return os.Remove(base) | ||
absPath, err := filepath.Abs(base) | ||
if err != nil || !strings.HasPrefix(absPath, filepath.Clean(project)+string(os.PathSeparator)) { | ||
return errors.New("invalid path") | ||
} | ||
return os.Remove(absPath) | ||
} |
} | ||
// Ensure git repository is initialized before committing | ||
gitDir := filepath.Join(projectDst, ".git") | ||
if _, err := os.Stat(gitDir); os.IsNotExist(err) { |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix the issue, we need to validate the name
input to ensure it does not contain any path traversal sequences or invalid characters. Additionally, we should verify that the constructed paths (projectDir
and gitDir
) remain within the intended base directory (s.ProjectsDir
). This can be achieved by resolving the absolute path and checking that it starts with the base directory.
- Add validation to ensure that
name
does not contain invalid characters such as/
,\
, or..
. - After constructing
projectDir
andgitDir
, resolve their absolute paths and verify that they are withins.ProjectsDir
. - If any validation fails, return an appropriate error.
-
Copy modified lines R144-R148 -
Copy modified lines R169-R175 -
Copy modified line R181 -
Copy modified line R184
@@ -143,2 +143,7 @@ | ||
func (s *ProjectsService) CreateProject(ctx context.Context, name, description, boilerplate string, networkID *int64) (Project, error) { | ||
// Validate the name to prevent invalid or malicious input | ||
if strings.Contains(name, "/") || strings.Contains(name, "\\") || strings.Contains(name, "..") { | ||
return Project{}, fmt.Errorf("invalid project name: %s", name) | ||
} | ||
|
||
slug, err := generateSlug(name, s.Queries, ctx) | ||
@@ -163,3 +168,9 @@ | ||
projectDir := filepath.Join(s.ProjectsDir, slug) | ||
if err := s.BoilerplateService.DownloadBoilerplate(ctx, boilerplate, projectDir); err != nil { | ||
// Ensure projectDir is within s.ProjectsDir | ||
absProjectDir, err := filepath.Abs(projectDir) | ||
if err != nil || !strings.HasPrefix(absProjectDir, filepath.Clean(s.ProjectsDir)+string(os.PathSeparator)) { | ||
return Project{}, fmt.Errorf("invalid project directory: %s", projectDir) | ||
} | ||
|
||
if err := s.BoilerplateService.DownloadBoilerplate(ctx, boilerplate, absProjectDir); err != nil { | ||
zap.L().Error("failed to download boilerplate", zap.String("boilerplate", boilerplate), zap.Error(err)) | ||
@@ -169,6 +180,6 @@ | ||
// Ensure git repository is initialized before committing | ||
gitDir := filepath.Join(projectDir, ".git") | ||
gitDir := filepath.Join(absProjectDir, ".git") | ||
if _, err := os.Stat(gitDir); os.IsNotExist(err) { | ||
// Initialize the repo using go-git | ||
_, err := versionmanagement.InitRepo(projectDir) | ||
_, err := versionmanagement.InitRepo(absProjectDir) | ||
if err != nil { |
- Updated `.gitignore` to include `projects-data-node1`, improving project cleanliness. - Added new dependencies `github.com/google/go-github/v45` and `github.com/google/go-querystring` to `go.mod` for enhanced API functionalities. - Updated Swagger documentation to reflect changes in API endpoints, including versioning and improved descriptions for better clarity. - Enhanced SQL queries in `dev-queries.sql` to include `network_id` in project creation, ensuring better data management. These changes improve the overall organization and usability of the application, providing clearer documentation and enhanced functionality for users. Signed-off-by: David VIEJO <dviejo@kungfusoftware.es>
} | ||
|
||
// Create the target directory if it doesn't exist | ||
if err := os.MkdirAll(targetDir, 0755); err != nil { |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix the issue, we need to validate and sanitize the targetDir
parameter before using it in file system operations. The best approach is to ensure that the resolved path is within a predefined safe directory. This involves:
- Defining a safe base directory (e.g.,
ProjectsDir
). - Resolving the
targetDir
relative to the safe base directory usingfilepath.Abs
. - Verifying that the resolved path starts with the safe base directory to prevent path traversal attacks.
Changes are required in pkg/scai/projects/service.go
and pkg/scai/boilerplates/boilerplates.go
to implement this validation.
-
Copy modified lines R176-R180
@@ -175,3 +175,7 @@ | ||
// Create the target directory if it doesn't exist | ||
if err := os.MkdirAll(targetDir, 0755); err != nil { | ||
absTargetDir, err := filepath.Abs(targetDir) | ||
if err != nil || !strings.HasPrefix(absTargetDir, filepath.Clean(safeBaseDir)+string(os.PathSeparator)) { | ||
return fmt.Errorf("invalid target directory: %s", targetDir) | ||
} | ||
if err := os.MkdirAll(absTargetDir, 0755); err != nil { | ||
return fmt.Errorf("failed to create target directory: %w", err) |
-
Copy modified lines R164-R169
@@ -163,3 +163,8 @@ | ||
projectDir := filepath.Join(s.ProjectsDir, slug) | ||
if err := s.BoilerplateService.DownloadBoilerplate(ctx, boilerplate, projectDir); err != nil { | ||
absProjectDir, err := filepath.Abs(projectDir) | ||
if err != nil || !strings.HasPrefix(absProjectDir, filepath.Clean(s.ProjectsDir)+string(os.PathSeparator)) { | ||
zap.L().Error("invalid project directory", zap.String("projectDir", projectDir), zap.Error(err)) | ||
return Project{}, fmt.Errorf("invalid project directory: %s", projectDir) | ||
} | ||
if err := s.BoilerplateService.DownloadBoilerplate(ctx, boilerplate, absProjectDir); err != nil { | ||
zap.L().Error("failed to download boilerplate", zap.String("boilerplate", boilerplate), zap.Error(err)) |
|
||
// Extract the tarball | ||
for { | ||
header, err := tr.Next() |
Check failure
Code scanning / CodeQL
Arbitrary file access during archive extraction ("Zip Slip") High
file system operation
Unsanitized archive entry, which may contain '..', is used in a
file system operation
Unsanitized archive entry, which may contain '..', is used in a
file system operation
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix the issue, we need to validate the header.Name
field to ensure it does not contain directory traversal elements (..
) and that the constructed targetPath
remains within the intended targetDir
. This can be achieved by:
- Using
filepath.Clean
to normalize the path and remove any traversal elements. - Verifying that the resulting
targetPath
is within thetargetDir
usingfilepath.HasPrefix
or equivalent logic. - Rejecting any paths that fail these checks before proceeding with file system operations.
The fix will involve modifying the code where targetPath
is constructed and adding validation logic.
-
Copy modified lines R231-R236
@@ -230,2 +230,8 @@ | ||
|
||
// Sanitize and validate the target path | ||
cleanTargetPath := filepath.Clean(targetPath) | ||
if !strings.HasPrefix(cleanTargetPath, targetDir) { | ||
return fmt.Errorf("invalid file path: %s", header.Name) | ||
} | ||
|
||
switch header.Typeflag { |
switch header.Typeflag { | ||
case tar.TypeDir: | ||
// Create directory | ||
if err := os.MkdirAll(targetPath, 0755); err != nil { |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix the issue, the user-controlled input (targetDir
and targetPath
) must be validated to ensure it does not contain malicious components such as ../
or absolute paths. The best approach is to:
- Resolve the absolute path of
targetPath
usingfilepath.Abs
. - Check that the resolved path is within a predefined safe directory (
targetDir
). - Reject the input if it fails validation.
This ensures that the file system operations are restricted to a safe directory and prevents directory traversal attacks.
-
Copy modified lines R231-R236 -
Copy modified lines R240-R241 -
Copy modified lines R245-R246 -
Copy modified line R250 -
Copy modified line R252 -
Copy modified line R258
@@ -230,2 +230,8 @@ | ||
|
||
// Validate that targetPath is within targetDir | ||
absTargetPath, err := filepath.Abs(targetPath) | ||
if err != nil || !strings.HasPrefix(absTargetPath, targetDir) { | ||
return fmt.Errorf("invalid file path: %s", targetPath) | ||
} | ||
|
||
switch header.Typeflag { | ||
@@ -233,4 +239,4 @@ | ||
// Create directory | ||
if err := os.MkdirAll(targetPath, 0755); err != nil { | ||
return fmt.Errorf("failed to create directory %s: %w", targetPath, err) | ||
if err := os.MkdirAll(absTargetPath, 0755); err != nil { | ||
return fmt.Errorf("failed to create directory %s: %w", absTargetPath, err) | ||
} | ||
@@ -238,4 +244,4 @@ | ||
// Create parent directories | ||
if err := os.MkdirAll(filepath.Dir(targetPath), 0755); err != nil { | ||
return fmt.Errorf("failed to create parent directory for %s: %w", targetPath, err) | ||
if err := os.MkdirAll(filepath.Dir(absTargetPath), 0755); err != nil { | ||
return fmt.Errorf("failed to create parent directory for %s: %w", absTargetPath, err) | ||
} | ||
@@ -243,5 +249,5 @@ | ||
// Create the file | ||
file, err := os.OpenFile(targetPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(header.Mode)) | ||
file, err := os.OpenFile(absTargetPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(header.Mode)) | ||
if err != nil { | ||
return fmt.Errorf("failed to create file %s: %w", targetPath, err) | ||
return fmt.Errorf("failed to create file %s: %w", absTargetPath, err) | ||
} | ||
@@ -251,3 +257,3 @@ | ||
file.Close() | ||
return fmt.Errorf("failed to write file %s: %w", targetPath, err) | ||
return fmt.Errorf("failed to write file %s: %w", absTargetPath, err) | ||
} |
} | ||
case tar.TypeReg: | ||
// Create parent directories | ||
if err := os.MkdirAll(filepath.Dir(targetPath), 0755); err != nil { |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix the issue, we need to validate and sanitize the targetPath
to ensure it does not allow directory traversal. Specifically:
- Use
filepath.Abs
to resolve the absolute path oftargetPath
. - Verify that the resolved
targetPath
is within the intendedtargetDir
by checking that it has the correct prefix. - Reject any paths that do not meet these criteria with an appropriate error message.
This fix ensures that even if the user provides malicious input, the code will not allow access to unintended parts of the file system.
-
Copy modified lines R231-R236
@@ -230,2 +230,8 @@ | ||
|
||
// Validate that targetPath is within targetDir | ||
absTargetPath, err := filepath.Abs(targetPath) | ||
if err != nil || !strings.HasPrefix(absTargetPath, filepath.Clean(targetDir)+string(os.PathSeparator)) { | ||
return fmt.Errorf("invalid file path: %s", targetPath) | ||
} | ||
|
||
switch header.Typeflag { |
} | ||
|
||
// Create the file | ||
file, err := os.OpenFile(targetPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(header.Mode)) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix the issue, we need to validate and sanitize the targetDir
and targetPath
to ensure they are safe before using them in file system operations. Specifically:
- Ensure that
targetDir
is resolved to an absolute path and verify that it is within a predefined safe directory. - Validate
targetPath
to ensure it does not contain malicious path components like..
or absolute paths. - Reject or sanitize any input that does not meet these criteria.
The changes will be made in pkg/scai/boilerplates/boilerplates.go
within the DownloadBoilerplate
function. We will introduce validation logic for targetDir
and targetPath
.
-
Copy modified lines R175-R184 -
Copy modified line R186 -
Copy modified lines R239-R247
@@ -174,4 +174,14 @@ | ||
|
||
// Resolve and validate the target directory | ||
absTargetDir, err := filepath.Abs(targetDir) | ||
if err != nil { | ||
return fmt.Errorf("failed to resolve target directory: %w", err) | ||
} | ||
const safeBaseDir = "/safe/base/directory" // Replace with your actual safe directory | ||
if !strings.HasPrefix(absTargetDir, safeBaseDir) { | ||
return fmt.Errorf("target directory is outside the allowed base directory") | ||
} | ||
|
||
// Create the target directory if it doesn't exist | ||
if err := os.MkdirAll(targetDir, 0755); err != nil { | ||
if err := os.MkdirAll(absTargetDir, 0755); err != nil { | ||
return fmt.Errorf("failed to create target directory: %w", err) | ||
@@ -228,3 +238,11 @@ | ||
targetPath := strings.TrimPrefix(header.Name, fmt.Sprintf("%s-main/", config.RepoName)) | ||
targetPath = filepath.Join(targetDir, targetPath) | ||
targetPath = filepath.Join(absTargetDir, targetPath) | ||
// Validate the resolved target path | ||
absTargetPath, err := filepath.Abs(targetPath) | ||
if err != nil { | ||
return fmt.Errorf("failed to resolve target path: %w", err) | ||
} | ||
if !strings.HasPrefix(absTargetPath, absTargetDir) { | ||
return fmt.Errorf("target path is outside the allowed target directory") | ||
} | ||
|
} | ||
vm := versionmanagement.NewDefaultManager() | ||
cwd, _ := os.Getwd() | ||
if err := os.Chdir(projectDir); err == nil { |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix the issue, the name
parameter should be validated before it is used to construct the slug
and subsequently the projectDir
. Validation should ensure that the name
does not contain any path traversal sequences (../
) or path separators (/
or \
). Additionally, the constructed projectDir
should be verified to ensure it remains within the intended ProjectsDir
directory.
Steps to implement the fix:
- Add validation logic to check the
name
parameter for forbidden characters or sequences. - Ensure that the
projectDir
path is resolved and verified to be within theProjectsDir
directory before any file system operations are performed. - Update the
CreateProject
method inpkg/scai/projects/service.go
to include these validations.
-
Copy modified lines R144-R148 -
Copy modified lines R169-R175 -
Copy modified line R181 -
Copy modified line R184 -
Copy modified line R191
@@ -143,2 +143,7 @@ | ||
func (s *ProjectsService) CreateProject(ctx context.Context, name, description, boilerplate string, networkID *int64) (Project, error) { | ||
// Validate name to prevent path traversal | ||
if strings.Contains(name, "/") || strings.Contains(name, "\\") || strings.Contains(name, "..") { | ||
return Project{}, errors.New("invalid project name") | ||
} | ||
|
||
slug, err := generateSlug(name, s.Queries, ctx) | ||
@@ -163,3 +168,9 @@ | ||
projectDir := filepath.Join(s.ProjectsDir, slug) | ||
if err := s.BoilerplateService.DownloadBoilerplate(ctx, boilerplate, projectDir); err != nil { | ||
// Ensure projectDir is within ProjectsDir | ||
absProjectDir, err := filepath.Abs(projectDir) | ||
if err != nil || !strings.HasPrefix(absProjectDir, filepath.Clean(s.ProjectsDir)+string(os.PathSeparator)) { | ||
return Project{}, errors.New("invalid project directory") | ||
} | ||
|
||
if err := s.BoilerplateService.DownloadBoilerplate(ctx, boilerplate, absProjectDir); err != nil { | ||
zap.L().Error("failed to download boilerplate", zap.String("boilerplate", boilerplate), zap.Error(err)) | ||
@@ -169,6 +180,6 @@ | ||
// Ensure git repository is initialized before committing | ||
gitDir := filepath.Join(projectDir, ".git") | ||
gitDir := filepath.Join(absProjectDir, ".git") | ||
if _, err := os.Stat(gitDir); os.IsNotExist(err) { | ||
// Initialize the repo using go-git | ||
_, err := versionmanagement.InitRepo(projectDir) | ||
_, err := versionmanagement.InitRepo(absProjectDir) | ||
if err != nil { | ||
@@ -179,3 +190,3 @@ | ||
cwd, _ := os.Getwd() | ||
if err := os.Chdir(projectDir); err == nil { | ||
if err := os.Chdir(absProjectDir); err == nil { | ||
err = vm.CommitChange(ctx, "Initial commit for project "+name) |
- Updated `go.mod` to include new dependencies for AI functionalities, including `github.com/anthropics/anthropic-sdk-go` and `github.com/openai/openai-go`. - Refactored the HTTP server setup to utilize a new command structure, enhancing modularity and organization. - Implemented AI client adapters for both OpenAI and Claude, ensuring compatibility with the new service layer. - Introduced a new database migration management system using embedded SQL migrations, improving database setup processes. - Enhanced project lifecycle management with new platform-specific lifecycle hooks for Fabric, improving project handling. - Removed outdated test files and refactored existing AI tests to align with the new structure. These changes significantly improve the application's architecture, maintainability, and functionality, ensuring a smooth transition from NestJS to Go while preserving existing features. Signed-off-by: David VIEJO <dviejo@kungfusoftware.es>
- Updated the `ProjectsService` to include new dependencies for organization, key management, and network services, improving modularity and functionality. - Refactored the `StartProjectServer` and `StopProjectServer` methods to utilize context for better error handling and lifecycle management. - Enhanced the `FabricLifecycle` implementation to support additional parameters and improve the pre-start and post-start hooks, ensuring better integration with the project lifecycle. - Introduced new methods for managing project lifecycle hooks, allowing for more flexible handling of platform-specific operations. These changes significantly improve the application's architecture and maintainability, ensuring a smoother transition from NestJS to Go while preserving existing features. Signed-off-by: David VIEJO <dviejo@kungfusoftware.es>
Signed-off-by: David VIEJO <dviejo@kungfusoftware.es>
github.com/sashabaranov/go-openai
dependency togo.mod
for integrating OpenAI functionalities.sqlc.yaml
to include an additional SQL queries file for development queries, improving database operations.dev-queries.sql
for managing projects, including listing, creating, and deleting projects.models.go
to include new structures for conversations and tool calls, supporting additional functionalities.querier.go
interface to include new methods for managing conversations and tool calls, ensuring better separation of concerns.These changes improve the overall functionality and maintainability of the application, providing better tools for project management and database interactions.