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
5 changes: 5 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Require review for CI/CD and security-sensitive files
.github/ @Corgea/engineering
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

added a new team here https://github.com/orgs/Corgea/teams/engineering/ with visibility with "visible" but somehow still not publicly visible. need to check back on this later

Cargo.toml @Corgea/engineering
Cargo.lock @Corgea/engineering
pyproject.toml @Corgea/engineering
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "weekly"
6 changes: 3 additions & 3 deletions .github/workflows/release-binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ inputs.tag || github.ref }}

Expand Down Expand Up @@ -72,7 +72,7 @@ jobs:

- name: Upload to GitHub Release (tags)
if: startsWith(github.ref, 'refs/tags/') || inputs.tag != ''
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2
with:
tag_name: ${{ inputs.tag || github.ref_name }}
files: "corgea-${{ matrix.target }}.zip"
Expand All @@ -81,7 +81,7 @@ jobs:

- name: Upload as Artifact (branches)
if: ${{ !startsWith(github.ref, 'refs/tags/') && inputs.tag == '' }}
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: binaries-${{ matrix.target }}
path: "corgea-${{ matrix.target }}.zip"
38 changes: 19 additions & 19 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ on:

permissions:
contents: read
id-token: write

Comment on lines 18 to 21
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

id-token: write is set at the workflow level, which grants OIDC token minting capability to all jobs in this workflow. To follow least-privilege, move id-token: write to the publish/release job only (and keep other jobs at contents: read).

Copilot uses AI. Check for mistakes.
jobs:
linux-x86:
Expand All @@ -30,9 +31,9 @@ jobs:
target: x86

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Build wheels
uses: PyO3/maturin-action@v1
uses: PyO3/maturin-action@04ac600d27cdf7a9a280dadf7147097c42b757ad # v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist
Expand All @@ -46,7 +47,7 @@ jobs:
apt update -y && apt-get install -y libssl-dev openssl pkg-config musl-tools
fi
- name: Upload wheels
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: wheels-linux-${{ matrix.platform.target }}
path: dist
Expand All @@ -61,14 +62,14 @@ jobs:
- runner: windows-latest
target: x86
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Build wheels
uses: PyO3/maturin-action@v1
uses: PyO3/maturin-action@04ac600d27cdf7a9a280dadf7147097c42b757ad # v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist
- name: Upload wheels
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: wheels-windows-${{ matrix.platform.target }}
path: dist
Expand All @@ -83,29 +84,29 @@ jobs:
- runner: macos-14
target: aarch64
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Build wheels
uses: PyO3/maturin-action@v1
uses: PyO3/maturin-action@04ac600d27cdf7a9a280dadf7147097c42b757ad # v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist
- name: Upload wheels
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: wheels-macos-${{ matrix.platform.target }}
path: dist

sdist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Build sdist
uses: PyO3/maturin-action@v1
uses: PyO3/maturin-action@04ac600d27cdf7a9a280dadf7147097c42b757ad # v1
with:
command: sdist
args: --out dist
- name: Upload sdist
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: wheels-sdist
path: dist
Expand All @@ -115,12 +116,11 @@ jobs:
runs-on: ubuntu-latest
if: "startsWith(github.ref, 'refs/tags/')"
needs: [linux-x86, windows, macos, sdist]
environment: pypi
steps:
- uses: actions/download-artifact@v4
- name: Publish to PyPI
uses: PyO3/maturin-action@v1
env:
MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
command: upload
args: --non-interactive --skip-existing wheels-*/*
path: dist
merge-multiple: true
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
23 changes: 23 additions & 0 deletions .github/workflows/security-audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Security Audit

on:
pull_request:
push:
branches:
- main
- master
schedule:
- cron: "0 0 * * 1"

permissions:
contents: read

jobs:
cargo-audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Install cargo-audit
run: cargo install cargo-audit
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

cargo install cargo-audit installs the latest crate on every run, which is slow and not reproducible (and can unexpectedly break CI if a new release is published). Consider pinning a specific version and using --locked (and optionally caching ~/.cargo/bin) to make the audit job deterministic.

Suggested change
run: cargo install cargo-audit
run: cargo install cargo-audit --version 0.20.0 --locked

Copilot uses AI. Check for mistakes.
- name: Run cargo audit
run: cargo audit
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,10 @@
*.zip
node_modules/
/packages/*/vendor/

.env*
*.pem
*.key
scan.json
test.json
src/test_data.swift
15 changes: 10 additions & 5 deletions src/scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,16 +147,16 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:

let scan_upload_url = if repo_data.is_empty() {
format!(
"{}/api/cli/scan-upload?token={}&engine={}&run_id={}&project={}&ci={}&ci_platform={}", base_url, token, scanner, run_id, project, in_ci, ci_platform
"{}/api/cli/scan-upload?engine={}&run_id={}&project={}&ci={}&ci_platform={}", base_url, scanner, run_id, project, in_ci, ci_platform
)
} else {
format!(
"{}/api/cli/scan-upload?token={}&engine={}&run_id={}&project={}&ci={}&ci_platform={}&repo_data={}", base_url, token, scanner, run_id, project, in_ci, ci_platform, repo_data
"{}/api/cli/scan-upload?engine={}&run_id={}&project={}&ci={}&ci_platform={}&repo_data={}", base_url, scanner, run_id, project, in_ci, ci_platform, repo_data
)
};

let git_config_upload_url = format!(
"{}/api/cli/git-config-upload?token={}&run_id={}", base_url, token, run_id
"{}/api/cli/git-config-upload?run_id={}", base_url, run_id
);
let client = utils::api::http_client();

Expand All @@ -177,7 +177,7 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:
}

let src_upload_url = format!(
"{}/api/cli/code-upload?token={}&run_id={}&path={}", base_url, token, run_id, path
"{}/api/cli/code-upload?run_id={}&path={}", base_url, run_id, path
);
Comment on lines 179 to 181
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

path is interpolated directly into the query string (...&path={}) without URL-encoding. File paths can contain spaces, &, ?, #, or backslashes (Windows), which can break the request or let a crafted path inject extra query parameters. Consider building the URL with reqwest::Url and .query_pairs_mut().append_pair("path", path) so it is properly encoded.

Copilot uses AI. Check for mistakes.
debug(&format!("Uploading file: {}", path));
let fp = Path::new(&path);
Expand All @@ -192,6 +192,7 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:

debug(&format!("POST: {}", src_upload_url));
let res = client.post(&src_upload_url)
.header("CORGEA-TOKEN", &token)
.multipart(form)
.send();

Expand Down Expand Up @@ -241,6 +242,7 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:
for (index, chunk) in input_bytes.chunks(chunk_size).enumerate() {
debug(&format!("POST: {} (chunk {}/{})", scan_upload_url, index + 1, total_chunks));
let response = client.post(&scan_upload_url)
.header("CORGEA-TOKEN", &token)
.header(header::CONTENT_TYPE, "application/json")
.header("Upload-Offset", offset.to_string())
.header("Upload-Length", input_size.to_string())
Expand All @@ -261,6 +263,7 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:
} else {
debug(&format!("POST: {}", scan_upload_url));
client.post(&scan_upload_url)
.header("CORGEA-TOKEN", &token)
.header(header::CONTENT_TYPE, "application/json")
.body(input.clone())
.send()
Expand Down Expand Up @@ -326,6 +329,7 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:

debug(&format!("POST: {}", git_config_upload_url));
let res = client.post(&git_config_upload_url)
.header("CORGEA-TOKEN", &token)
.multipart(form)
.send();

Expand All @@ -343,7 +347,7 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:

if in_ci {
let ci_data_upload_url = format!(
"{}/api/cli/ci-data-upload?token={}&run_id={}&platform={}", base_url, token, run_id, ci_platform
"{}/api/cli/ci-data-upload?run_id={}&platform={}", base_url, run_id, ci_platform
);

let mut github_env_vars_json = serde_json::Map::new();
Expand All @@ -361,6 +365,7 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:

debug(&format!("POST: {}", ci_data_upload_url));
let _res = client.post(ci_data_upload_url)
.header("CORGEA-TOKEN", &token)
.header(header::CONTENT_TYPE, "application/json")
.body(github_env_vars_json_string)
.send();
Expand Down
2 changes: 1 addition & 1 deletion src/utils/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ pub fn get_sca_issues(

debug(&format!("Sending request to URL: {}", endpoint));
debug(&format!("Query params: {:?}", query_params));
debug(&format!("Token: {}", token));
debug(&format!("Token: ...{}", &token[token.len().saturating_sub(4)..]));
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

&token[token.len().saturating_sub(4)..] slices by byte index and can panic if token contains non-ASCII (not on a UTF-8 char boundary). Since CORGEA_TOKEN comes from env/config and isn't validated, prefer a non-panicking mask (e.g., using token.chars() to take the last 4 chars, or token.get(..) with a safe fallback).

Suggested change
debug(&format!("Token: ...{}", &token[token.len().saturating_sub(4)..]));
let token_suffix: String = token
.chars()
.rev()
.take(4)
.collect::<String>()
.chars()
.rev()
.collect();
debug(&format!("Token: ...{}", token_suffix));

Copilot uses AI. Check for mistakes.

let response = client
.get(&endpoint)
Expand Down
Loading