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
6 changes: 6 additions & 0 deletions cmd/eos/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,12 @@ static int cmd_clean(const CliArgs *args) {
return 0;
}

/* Validate build_dir to prevent command injection */
if (strpbrk(build_dir, ";|&><$()\"'")) {
EOS_ERROR("Invalid build directory path: %s (contains special characters)", build_dir);
return 1;
}

char cmd[1024];
#ifdef _WIN32
snprintf(cmd, sizeof(cmd), "if exist \"%s\" rmdir /s /q \"%s\"", build_dir, build_dir);
Expand Down
20 changes: 20 additions & 0 deletions pkg/src/fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,18 @@ static int is_tarball(const char *url) {
strstr(url, ".zip") != NULL);
}

static int is_url_safe(const char *url) {
if (!url) return 0;
/* Basic check for common shell metacharacters */
if (strpbrk(url, ";|><$()`'")) return 0;
return 1;
}

static EosResult fetch_git(const char *url, const char *dest) {
if (!is_url_safe(url)) {
EOS_ERROR("Potentially unsafe git URL detected: %s", url);
return EOS_ERR_FETCH;
}
char cmd[2048];
snprintf(cmd, sizeof(cmd), "git clone --depth 1 \"%s\" \"%s\"", url, dest);
EOS_INFO("Fetching (git): %s", url);
Expand All @@ -142,6 +153,10 @@ static EosResult fetch_git(const char *url, const char *dest) {
}

static EosResult fetch_tarball(const char *url, const char *dest) {
if (!is_url_safe(url)) {
EOS_ERROR("Potentially unsafe source URL detected: %s", url);
return EOS_ERR_FETCH;
}
MKDIR(dest);

char archive[EOS_MAX_PATH];
Expand Down Expand Up @@ -189,6 +204,11 @@ EosResult eos_fetch_source(const char *url, const char *dest_dir,
return EOS_OK;
}

if (!is_url_safe(url)) {
EOS_ERROR("Potentially unsafe source URL detected: %s", url);
return EOS_ERR_FETCH;
}

/* Determine archive path for checksum verification */
char archive_path[EOS_MAX_PATH] = {0};
if (is_tarball(url)) {
Expand Down
12 changes: 12 additions & 0 deletions services/linux/src/linux_security.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,16 @@ int eos_selinux_set_policy(EosSelinux *se, const char *policy_dir,
return -1;
}

static int is_path_safe(const char *path) {
if (!path) return 1;
if (strpbrk(path, ";|&><$()\"'")) return 0;
return 1;
}

int eos_selinux_install_to_rootfs(const EosSelinux *se, const char *rootfs_dir) {
if (!is_path_safe(se->policy_dir) || !is_path_safe(se->policy_name)) {
return -1;
}
char path[1024];

/* Create /etc/selinux directory */
Expand Down Expand Up @@ -78,6 +87,9 @@ int eos_selinux_install_to_rootfs(const EosSelinux *se, const char *rootfs_dir)

int eos_selinux_label_rootfs(const EosSelinux *se, const char *rootfs_dir) {
if (se->mode == EOS_SELINUX_DISABLED) return 0;
if (!is_path_safe(rootfs_dir) || !is_path_safe(se->file_contexts)) {
return -1;
}
#ifndef _WIN32
char cmd[2048];
if (se->file_contexts[0]) {
Expand Down
14 changes: 14 additions & 0 deletions services/os/src/os_services.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,17 @@ int eos_ota_set_source(EosOtaUpdate *ota, const char *url,
return 0;
}

static int is_url_safe(const char *url) {
if (!url) return 0;
if (strpbrk(url, ";|><$()`'")) return 0;
return 1;
}

int eos_ota_download(EosOtaUpdate *ota) {
if (!is_url_safe(ota->url)) {
ota->state = EOS_OTA_FAILED;
return -1;
}
ota->state = EOS_OTA_DOWNLOADING;
char cmd[2048];
#ifdef _WIN32
Expand Down Expand Up @@ -114,6 +124,10 @@ int eos_ota_verify(EosOtaUpdate *ota) {
}

int eos_ota_install(EosOtaUpdate *ota, const char *target_path) {
if (target_path && strpbrk(target_path, ";|&><$()\"'")) {
ota->state = EOS_OTA_FAILED;
return -1;
}
ota->state = EOS_OTA_INSTALLING;
char cmd[2048];
#ifdef _WIN32
Expand Down
Loading