diff --git a/.github/workflows/static-code-analysis.yml b/.github/workflows/static-code-analysis.yml index 3ce78e7e8447c..3728510001c85 100644 --- a/.github/workflows/static-code-analysis.yml +++ b/.github/workflows/static-code-analysis.yml @@ -108,7 +108,14 @@ jobs: run: composer i - name: Psalm taint analysis - run: composer run psalm:security -- --threads=1 --monochrome --no-progress --output-format=github --update-baseline --report=results.sarif + run: composer run psalm:security -- --threads=1 --monochrome --no-progress --output-format=github --update-baseline --report=results.sarif --report-show-info=false + + # Psalm exits 0 on taint findings when a report file is generated + - name: Fail on taint analysis findings + run: | + count=$(jq '[.runs[].results[]] | length' results.sarif) + echo "Taint analysis findings: $count" + test "$count" -eq 0 - name: Show potential changes in Psalm baseline if: always() diff --git a/apps/workflowengine/lib/Manager.php b/apps/workflowengine/lib/Manager.php index fdbc8c705b5cb..184712ef0d08a 100644 --- a/apps/workflowengine/lib/Manager.php +++ b/apps/workflowengine/lib/Manager.php @@ -611,7 +611,8 @@ public function deleteOperation(int $id, ScopeContext $scopeContext): bool { * @param array $events */ protected function validateEvents(string $entity, array $events, IOperation $operation): void { - /** @psalm-suppress TaintedCallable newInstance is not called */ + /** @psalm-taint-escape callable */ + $entity = $entity; $reflection = new \ReflectionClass($entity); if ($entity !== IEntity::class && !in_array(IEntity::class, $reflection->getInterfaceNames(), true)) { throw new \UnexpectedValueException($this->l->t('Entity %s is invalid', [$entity])); @@ -653,7 +654,8 @@ public function validateOperation(string $class, string $name, array $checks, st throw new \UnexpectedValueException($this->l->t('The provided operation data is too long')); } - /** @psalm-suppress TaintedCallable newInstance is not called */ + /** @psalm-taint-escape callable */ + $class = $class; $reflection = new \ReflectionClass($class); if ($class !== IOperation::class && !in_array(IOperation::class, $reflection->getInterfaceNames(), true)) { throw new \UnexpectedValueException($this->l->t('Operation %s is invalid', [$class]) . join(', ', $reflection->getInterfaceNames())); @@ -687,14 +689,16 @@ public function validateOperation(string $class, string $name, array $checks, st throw new \UnexpectedValueException($this->l->t('The provided check value is too long')); } - $reflection = new \ReflectionClass($check['class']); - if ($check['class'] !== ICheck::class && !in_array(ICheck::class, $reflection->getInterfaceNames(), true)) { + /** @psalm-taint-escape callable */ + $checkClass = $check['class']; + $reflection = new \ReflectionClass($checkClass); + if ($checkClass !== ICheck::class && !in_array(ICheck::class, $reflection->getInterfaceNames(), true)) { throw new \UnexpectedValueException($this->l->t('Check %s is invalid', [$class])); } try { /** @var ICheck $instance */ - $instance = $this->container->get($check['class']); + $instance = $this->container->get($checkClass); } catch (ContainerExceptionInterface) { throw new \UnexpectedValueException($this->l->t('Check %s does not exist', [$class])); } diff --git a/lib/private/Mail/Mailer.php b/lib/private/Mail/Mailer.php index da61abb7dd4d5..cbfced3328571 100644 --- a/lib/private/Mail/Mailer.php +++ b/lib/private/Mail/Mailer.php @@ -212,7 +212,7 @@ public function send(IMessage $message): array { try { $mailer->send($message->getSymfonyEmail()); } catch (TransportExceptionInterface $e) { - $logMessage = sprintf('Sending mail to "%s" with subject "%s" failed', print_r($message->getTo(), true), $message->getSubject()); + $logMessage = sprintf('Sending mail to "%s" with subject "%s" failed', json_encode($message->getTo()), $message->getSubject()); $this->logger->error($logMessage, ['app' => 'core', 'exception' => $e]); if ($debugMode) { $this->logger->debug($e->getDebug(), ['app' => 'core']); @@ -232,7 +232,7 @@ public function send(IMessage $message): array { } // Debugging logging - $logMessage = sprintf('Sent mail to "%s" with subject "%s"', print_r($message->getTo(), true), $message->getSubject()); + $logMessage = sprintf('Sent mail to "%s" with subject "%s"', json_encode($message->getTo()), $message->getSubject()); $this->logger->debug($logMessage, ['app' => 'core']); return [];