mirror of
https://github.com/tiennm99/coolify.git
synced 2026-10-14 08:18:08 +00:00
fix(api): hide sensitive fields by default, expose via makeVisible for privileged tokens
Models now declare $hidden for passwords, tokens, db URLs, and compose fields. API controllers flip from makeHidden-on-deny to makeVisible-on- allow (can_read_sensitive=true), fixing fields that were never hidden. Also adds missing fields (mysql/mariadb passwords, logdrain keys, etc.) to privileged disclosure lists. Tests added: Feature/Security/ApiSensitiveFieldsTest and Unit/Models/SensitiveFieldsHiddenTest cover all affected models and controllers.
This commit is contained in:
1 parent
7ab16ad7b5
commit
8b7dbbafb2
19 files changed
+549
-16
No files matched your search
@@ -215,6 +215,24 @@ class Application extends BaseModel
|
||||
|
||||
protected $appends = ['server_status'];
|
||||
|
||||
/**
|
||||
* Sensitive fields hidden by default in serialized output (toArray/toJson).
|
||||
* API controllers should call makeVisible([...]) for callers with the
|
||||
* `read:sensitive` or `root` token ability. Internal serializers (deployment
|
||||
* job, compose generation) must makeVisible explicitly before toArray().
|
||||
*/
|
||||
protected $hidden = [
|
||||
'http_basic_auth_password',
|
||||
'manual_webhook_secret_github',
|
||||
'manual_webhook_secret_gitlab',
|
||||
'manual_webhook_secret_bitbucket',
|
||||
'manual_webhook_secret_gitea',
|
||||
'dockerfile',
|
||||
'docker_compose',
|
||||
'docker_compose_raw',
|
||||
'custom_labels',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
|
||||
@@ -76,9 +76,19 @@ class EnvironmentVariable extends BaseModel
|
||||
|
||||
protected $appends = ['real_value', 'is_shared', 'is_really_required', 'is_nixpacks', 'is_coolify'];
|
||||
|
||||
/**
|
||||
* Sensitive fields hidden by default in serialized output (toArray/toJson).
|
||||
* API controllers should call makeVisible([...]) for callers with the
|
||||
* `read:sensitive` or `root` token ability.
|
||||
*/
|
||||
protected $hidden = [
|
||||
'value',
|
||||
'real_value',
|
||||
];
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::created(function (EnvironmentVariable $environment_variable) {
|
||||
static::created(function (ModelsEnvironmentVariable $environment_variable) {
|
||||
if ($environment_variable->resourceable_type === Application::class && ! $environment_variable->is_preview) {
|
||||
$found = ModelsEnvironmentVariable::where('key', $environment_variable->key)
|
||||
->where('resourceable_type', Application::class)
|
||||
@@ -109,7 +119,7 @@ class EnvironmentVariable extends BaseModel
|
||||
]);
|
||||
});
|
||||
|
||||
static::saving(function (EnvironmentVariable $environmentVariable) {
|
||||
static::saving(function (ModelsEnvironmentVariable $environmentVariable) {
|
||||
$environmentVariable->updateIsShared();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -254,6 +254,16 @@ class Server extends BaseModel
|
||||
'force_disabled' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* Sensitive fields hidden by default in serialized output (toArray/toJson).
|
||||
* API controllers should call makeVisible([...]) for callers with the
|
||||
* `read:sensitive` or `root` token ability.
|
||||
*/
|
||||
protected $hidden = [
|
||||
'logdrain_axiom_api_key',
|
||||
'logdrain_newrelic_license_key',
|
||||
];
|
||||
|
||||
protected $schemalessAttributes = [
|
||||
'proxy',
|
||||
];
|
||||
|
||||
@@ -113,6 +113,20 @@ class ServerSetting extends Model
|
||||
'connection_timeout' => 'integer',
|
||||
];
|
||||
|
||||
/**
|
||||
* Sensitive fields hidden by default in serialized output (toArray/toJson).
|
||||
* API controllers should call makeVisible([...]) for callers with the
|
||||
* `read:sensitive` or `root` token ability.
|
||||
*/
|
||||
protected $hidden = [
|
||||
'sentinel_token',
|
||||
'sentinel_custom_url',
|
||||
'logdrain_newrelic_license_key',
|
||||
'logdrain_axiom_api_key',
|
||||
'logdrain_custom_config',
|
||||
'logdrain_custom_config_parser',
|
||||
];
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::creating(function ($setting) {
|
||||
|
||||
@@ -67,6 +67,17 @@ class Service extends BaseModel
|
||||
|
||||
protected $appends = ['server_status', 'status'];
|
||||
|
||||
/**
|
||||
* Sensitive fields hidden by default in serialized output (toArray/toJson).
|
||||
* API controllers should call makeVisible([...]) for callers with the
|
||||
* `read:sensitive` or `root` token ability. Internal compose generators
|
||||
* must makeVisible explicitly before toArray().
|
||||
*/
|
||||
protected $hidden = [
|
||||
'docker_compose',
|
||||
'docker_compose_raw',
|
||||
];
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::creating(function ($service) {
|
||||
|
||||
@@ -48,6 +48,17 @@ class StandaloneClickhouse extends BaseModel
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status'];
|
||||
|
||||
/**
|
||||
* Sensitive fields hidden by default in serialized output (toArray/toJson).
|
||||
* API controllers should call makeVisible([...]) for callers with the
|
||||
* `read:sensitive` or `root` token ability.
|
||||
*/
|
||||
protected $hidden = [
|
||||
'clickhouse_admin_password',
|
||||
'internal_db_url',
|
||||
'external_db_url',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'clickhouse_admin_password' => 'encrypted',
|
||||
'public_port_timeout' => 'integer',
|
||||
|
||||
@@ -47,6 +47,17 @@ class StandaloneDragonfly extends BaseModel
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status'];
|
||||
|
||||
/**
|
||||
* Sensitive fields hidden by default in serialized output (toArray/toJson).
|
||||
* API controllers should call makeVisible([...]) for callers with the
|
||||
* `read:sensitive` or `root` token ability.
|
||||
*/
|
||||
protected $hidden = [
|
||||
'dragonfly_password',
|
||||
'internal_db_url',
|
||||
'external_db_url',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'dragonfly_password' => 'encrypted',
|
||||
'public_port_timeout' => 'integer',
|
||||
|
||||
@@ -48,6 +48,17 @@ class StandaloneKeydb extends BaseModel
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'server_status'];
|
||||
|
||||
/**
|
||||
* Sensitive fields hidden by default in serialized output (toArray/toJson).
|
||||
* API controllers should call makeVisible([...]) for callers with the
|
||||
* `read:sensitive` or `root` token ability.
|
||||
*/
|
||||
protected $hidden = [
|
||||
'keydb_password',
|
||||
'internal_db_url',
|
||||
'external_db_url',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'keydb_password' => 'encrypted',
|
||||
'public_port_timeout' => 'integer',
|
||||
|
||||
@@ -51,6 +51,18 @@ class StandaloneMariadb extends BaseModel
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status'];
|
||||
|
||||
/**
|
||||
* Sensitive fields hidden by default in serialized output (toArray/toJson).
|
||||
* API controllers should call makeVisible([...]) for callers with the
|
||||
* `read:sensitive` or `root` token ability.
|
||||
*/
|
||||
protected $hidden = [
|
||||
'mariadb_password',
|
||||
'mariadb_root_password',
|
||||
'internal_db_url',
|
||||
'external_db_url',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'mariadb_password' => 'encrypted',
|
||||
'public_port_timeout' => 'integer',
|
||||
|
||||
@@ -51,6 +51,17 @@ class StandaloneMongodb extends BaseModel
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status'];
|
||||
|
||||
/**
|
||||
* Sensitive fields hidden by default in serialized output (toArray/toJson).
|
||||
* API controllers should call makeVisible([...]) for callers with the
|
||||
* `read:sensitive` or `root` token ability.
|
||||
*/
|
||||
protected $hidden = [
|
||||
'mongo_initdb_root_password',
|
||||
'internal_db_url',
|
||||
'external_db_url',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'public_port_timeout' => 'integer',
|
||||
'restart_count' => 'integer',
|
||||
|
||||
@@ -52,6 +52,18 @@ class StandaloneMysql extends BaseModel
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status'];
|
||||
|
||||
/**
|
||||
* Sensitive fields hidden by default in serialized output (toArray/toJson).
|
||||
* API controllers should call makeVisible([...]) for callers with the
|
||||
* `read:sensitive` or `root` token ability.
|
||||
*/
|
||||
protected $hidden = [
|
||||
'mysql_password',
|
||||
'mysql_root_password',
|
||||
'internal_db_url',
|
||||
'external_db_url',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'mysql_password' => 'encrypted',
|
||||
'mysql_root_password' => 'encrypted',
|
||||
|
||||
@@ -54,6 +54,18 @@ class StandalonePostgresql extends BaseModel
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status'];
|
||||
|
||||
/**
|
||||
* Sensitive fields hidden by default in serialized output (toArray/toJson).
|
||||
* API controllers should call makeVisible([...]) for callers with the
|
||||
* `read:sensitive` or `root` token ability.
|
||||
*/
|
||||
protected $hidden = [
|
||||
'postgres_password',
|
||||
'init_scripts',
|
||||
'internal_db_url',
|
||||
'external_db_url',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'init_scripts' => 'array',
|
||||
'postgres_password' => 'encrypted',
|
||||
|
||||
@@ -47,6 +47,17 @@ class StandaloneRedis extends BaseModel
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status'];
|
||||
|
||||
/**
|
||||
* Sensitive fields hidden by default in serialized output (toArray/toJson).
|
||||
* API controllers should call makeVisible([...]) for callers with the
|
||||
* `read:sensitive` or `root` token ability.
|
||||
*/
|
||||
protected $hidden = [
|
||||
'redis_password',
|
||||
'internal_db_url',
|
||||
'external_db_url',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'public_port_timeout' => 'integer',
|
||||
'restart_count' => 'integer',
|
||||
|
||||
Reference in new issue
Block a user