mirror of
https://github.com/tiennm99/coolify.git
synced 2026-08-23 16:23:53 +00:00
fix: improve application URL handling
This commit is contained in:
@@ -130,6 +130,69 @@ describe('deployment job path field validation', function () {
|
||||
});
|
||||
|
||||
describe('API validation rules for path fields', function () {
|
||||
test('domains validation rejects command injection payloads', function (string $payload) {
|
||||
$rules = sharedDataApplications();
|
||||
|
||||
$validator = validator(
|
||||
['domains' => $payload],
|
||||
['domains' => $rules['domains']]
|
||||
);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
})->with([
|
||||
'host command substitution' => 'http://$(whoami).example.com',
|
||||
'path command substitution' => 'http://example.com/$(whoami)',
|
||||
'query command substitution' => 'http://example.com/path?next=$(id)',
|
||||
'host backtick substitution' => 'http://`whoami`.example.com',
|
||||
'path backtick substitution' => 'http://example.com/`whoami`',
|
||||
'semicolon command separator' => 'http://example.com/path;id',
|
||||
'newline injection' => "http://example.com\nwhoami",
|
||||
'carriage return injection' => "http://example.com\rwhoami",
|
||||
'pipe injection' => 'http://example.com/path|id',
|
||||
]);
|
||||
|
||||
test('domains validation rejects non http schemes', function () {
|
||||
$rules = sharedDataApplications();
|
||||
|
||||
$validator = validator(
|
||||
['domains' => 'ftp://example.com'],
|
||||
['domains' => $rules['domains']]
|
||||
);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
});
|
||||
|
||||
test('domains validation allows comma separated http and https urls', function () {
|
||||
$rules = sharedDataApplications();
|
||||
|
||||
$validator = validator(
|
||||
['domains' => 'https://app.example.com,http://api.example.com/path'],
|
||||
['domains' => $rules['domains']]
|
||||
);
|
||||
|
||||
expect($validator->fails())->toBeFalse();
|
||||
});
|
||||
|
||||
test('docker compose service domains validation rejects command injection payloads', function () {
|
||||
$rules = [
|
||||
'docker_compose_domains' => 'array|nullable',
|
||||
'docker_compose_domains.*' => 'array:name,domain',
|
||||
'docker_compose_domains.*.name' => 'string|required',
|
||||
'docker_compose_domains.*.domain' => ValidationPatterns::applicationDomainRules(),
|
||||
];
|
||||
|
||||
$validator = validator(
|
||||
[
|
||||
'docker_compose_domains' => [
|
||||
['name' => 'app', 'domain' => 'https://app.example.com/$(whoami)'],
|
||||
],
|
||||
],
|
||||
$rules
|
||||
);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
});
|
||||
|
||||
test('git_branch validation rejects shell metacharacters', function (string $branch) {
|
||||
$rules = sharedDataApplications();
|
||||
|
||||
@@ -276,7 +339,45 @@ describe('deployment git command escaping', function () {
|
||||
|
||||
expect($coolifyVariables->getValue($instance))
|
||||
->toContain("COOLIFY_BRANCH='main`id`' ")
|
||||
->toContain('COOLIFY_RESOURCE_UUID=app-uuid ');
|
||||
->toContain("COOLIFY_RESOURCE_UUID='app-uuid' ");
|
||||
});
|
||||
|
||||
test('coolify url and fqdn shell assignments are quoted', function () {
|
||||
$job = new ReflectionClass(ApplicationDeploymentJob::class);
|
||||
$instance = $job->newInstanceWithoutConstructor();
|
||||
|
||||
$application = new Application;
|
||||
$application->uuid = 'app-uuid';
|
||||
$application->git_branch = 'main';
|
||||
$application->fqdn = 'https://app.example.com/path';
|
||||
$application->compose_parsing_version = '3';
|
||||
|
||||
$settings = new ApplicationSetting;
|
||||
$settings->include_source_commit_in_build = true;
|
||||
$application->setRelation('settings', $settings);
|
||||
|
||||
foreach ([
|
||||
'application' => $application,
|
||||
'commit' => 'HEAD$(id)',
|
||||
'pull_request_id' => 0,
|
||||
] as $property => $value) {
|
||||
$reflectionProperty = $job->getProperty($property);
|
||||
$reflectionProperty->setAccessible(true);
|
||||
$reflectionProperty->setValue($instance, $value);
|
||||
}
|
||||
|
||||
$method = $job->getMethod('set_coolify_variables');
|
||||
$method->setAccessible(true);
|
||||
$method->invoke($instance);
|
||||
|
||||
$coolifyVariables = $job->getProperty('coolify_variables');
|
||||
$coolifyVariables->setAccessible(true);
|
||||
|
||||
expect($coolifyVariables->getValue($instance))
|
||||
->toContain("SOURCE_COMMIT='HEAD$(id)' ")
|
||||
->toContain("COOLIFY_URL='https://app.example.com/path' ")
|
||||
->toContain("COOLIFY_FQDN='app.example.com' ")
|
||||
->toContain("COOLIFY_RESOURCE_UUID='app-uuid' ");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user