Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable30] fix(logger): Prevent infinite recursion with log.condition => users or matches #50031

Merged
merged 1 commit into from
Jan 3, 2025
Merged
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
39 changes: 39 additions & 0 deletions build/integration/features/log-condition.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: AGPL-3.0-or-later
Feature: log-condition

Background:
Given invoking occ with "config:system:set log.condition matches 0 users 0 --value admin"
Then the command was successful

Scenario: Accessing /status.php with log.condition
When requesting "/status.php" with "GET"
Then the HTTP status code should be "200"

Scenario: Accessing /index.php with log.condition
When requesting "/index.php" with "GET"
Then the HTTP status code should be "200"

Scenario: Accessing /remote.php/webdav with log.condition
When requesting "/remote.php/webdav" with "GET"
Then the HTTP status code should be "401"

Scenario: Accessing /remote.php/dav with log.condition
When requesting "/remote.php/dav" with "GET"
Then the HTTP status code should be "401"

Scenario: Accessing /ocs/v1.php with log.condition
When requesting "/ocs/v1.php" with "GET"
Then the HTTP status code should be "200"

Scenario: Accessing /ocs/v2.php with log.condition
When requesting "/ocs/v2.php" with "GET"
Then the HTTP status code should be "404"

Scenario: Accessing /public.php/webdav with log.condition
When requesting "/public.php/webdav" with "GET"
Then the HTTP status code should be "401"

Scenario: Accessing /public.php/dav with log.condition
When requesting "/public.php/dav" with "GET"
Then the HTTP status code should be "503"
12 changes: 12 additions & 0 deletions lib/private/Log.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
class Log implements ILogger, IDataLogger {
private ?bool $logConditionSatisfied = null;
private ?IEventDispatcher $eventDispatcher = null;
private int $nestingLevel = 0;

public function __construct(
private IWriter $logger,
Expand Down Expand Up @@ -196,6 +197,11 @@ public function log(int $level, string $message, array $context = []): void {
}

public function getLogLevel(array $context, string $message): int {
if ($this->nestingLevel > 1) {
return ILogger::WARN;
}

$this->nestingLevel++;
/**
* @psalm-var array{
* shared_secret?: string,
Expand Down Expand Up @@ -246,6 +252,7 @@ public function getLogLevel(array $context, string $message): int {

// if log condition is satisfied change the required log level to DEBUG
if ($this->logConditionSatisfied) {
$this->nestingLevel--;
return ILogger::DEBUG;
}

Expand All @@ -260,6 +267,7 @@ public function getLogLevel(array $context, string $message): int {
* once this is met -> change the required log level to debug
*/
if (in_array($context['app'], $logCondition['apps'] ?? [], true)) {
$this->nestingLevel--;
return ILogger::DEBUG;
}
}
Expand All @@ -272,6 +280,7 @@ public function getLogLevel(array $context, string $message): int {

// Invalid configuration, warn the user and fall back to default level of WARN
error_log('Nextcloud configuration: "loglevel" is not a valid integer');
$this->nestingLevel--;
return ILogger::WARN;
}

Expand All @@ -285,12 +294,15 @@ public function getLogLevel(array $context, string $message): int {
if (!isset($option['apps']) && !isset($option['loglevel']) && !isset($option['message'])) {
/* Only user and/or secret are listed as conditions, we can cache the result for the rest of the request */
$this->logConditionSatisfied = true;
$this->nestingLevel--;
return ILogger::DEBUG;
}
$this->nestingLevel--;
return $option['loglevel'] ?? ILogger::DEBUG;
}
}

$this->nestingLevel--;
return ILogger::WARN;
}

Expand Down
Loading