Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/transbank-webpay-plus-rest/load-autoloader.php
+++ b/transbank-webpay-plus-rest/load-autoloader.php
@@ -10,11 +10,6 @@
return;
}
- $runtimePrefixes = tbkLoadScopedRuntimePrefixes($pluginRoot);
- if ($runtimePrefixes !== []) {
- tbkRegisterScopedAutoloader($pluginRoot . 'vendor-prefixed/', $runtimePrefixes);
- }
-
$scoperAutoload = $pluginRoot . 'vendor-prefixed/scoper-autoload.php';
if (file_exists($scoperAutoload)) {
require_once $scoperAutoload;
@@ -22,36 +17,3 @@
require_once $prefixedAutoload;
}
-
-function tbkLoadScopedRuntimePrefixes(string $pluginRoot): array
-{
- $scopeConfigPath = $pluginRoot . 'scoper-namespaces.php';
- if (!file_exists($scopeConfigPath)) {
- return [];
- }
-
- $scopeConfig = require_once $scopeConfigPath;
- $runtimePrefixes = $scopeConfig['runtime_psr4'] ?? [];
-
- return is_array($runtimePrefixes) ? $runtimePrefixes : [];
-}
-
-function tbkRegisterScopedAutoloader(string $prefixedRoot, array $runtimePrefixes): void
-{
- spl_autoload_register(static function ($class) use ($prefixedRoot, $runtimePrefixes) {
- foreach ($runtimePrefixes as $prefix => $relativeBaseDir) {
- if (strncmp($class, $prefix, strlen($prefix)) !== 0) {
- continue;
- }
-
- $relativeClass = substr($class, strlen($prefix));
- $file = $prefixedRoot . $relativeBaseDir . str_replace('\', '/', $relativeClass) . '.php';
-
- if (file_exists($file)) {
- require_once $file;
- }
-
- return;
- }
- }, true, true);
-}
--- a/transbank-webpay-plus-rest/shared/Helpers/PluginLogger.php
+++ b/transbank-webpay-plus-rest/shared/Helpers/PluginLogger.php
@@ -10,8 +10,8 @@
final class PluginLogger
{
-
const CACHE_LOG_NAME = 'transbank_log_file_name';
+ private const MAX_LOG_DEPTH = 10;
private $logger;
private $config;
@@ -92,6 +92,38 @@
$this->logger->error($msg, $context);
}
+ public static function sanitizeContextForLogs(array $context): array
+ {
+ $sanitizedContext = [];
+
+ foreach ($context as $key => $value) {
+ $sanitizedContext[$key] = self::sanitizeLogValue($value);
+ }
+
+ return $sanitizedContext;
+ }
+
+ private static function sanitizeLogValue(mixed $value, int $depth = 0): mixed
+ {
+ if ($depth > self::MAX_LOG_DEPTH) {
+ return '[array too deep]';
+ }
+
+ $sanitizedValue = null;
+
+ if (is_array($value)) {
+ $sanitizedValue = array_map(function ($nestedValue) use ($depth) {
+ return self::sanitizeLogValue($nestedValue, $depth + 1);
+ }, $value);
+ } elseif (is_null($value) || is_bool($value) || is_int($value) || is_float($value)) {
+ $sanitizedValue = $value;
+ } else {
+ $sanitizedValue = sanitize_text_field(wp_strip_all_tags((string) $value));
+ }
+
+ return $sanitizedValue;
+ }
+
public function getInfo()
{
$files = glob($this->config->getLogDir() . '/*.log');
--- a/transbank-webpay-plus-rest/src/Controllers/CommitWebpayController.php
+++ b/transbank-webpay-plus-rest/src/Controllers/CommitWebpayController.php
@@ -4,6 +4,7 @@
use TransbankWooCommerceWebpayRestServicesWebpayService;
use TransbankPluginHelpersPluginLogger;
+use TransbankWooCommerceWebpayRestHelpersRequestInputHelper;
use TransbankPluginHelpersTbkConstants;
use TransbankPluginExceptionsEcommerceException;
use TransbankVendorTransbankWebpayWebpayPlusResponsesTransactionCommitResponse;
@@ -55,12 +56,25 @@
public function process(): void
{
try {
- $requestMethod = $_SERVER['REQUEST_METHOD'];
- $request = $requestMethod === 'POST' ? $_POST : $_GET;
+ $requestMethod = RequestInputHelper::resolveRequestMethod($_SERVER);
+ $rawRequest = $requestMethod === 'POST' ? $_POST : $_GET;
+ $request = RequestInputHelper::sanitizeExpectedFields($rawRequest, [
+ 'token_ws',
+ 'TBK_TOKEN',
+ 'TBK_ID_SESION',
+ 'TBK_ORDEN_COMPRA',
+ ]);
+ $webpayFlow = $this->getWebpayFlow($request);
$this->log->logInfo('Procesando retorno desde formulario de Webpay.');
- $this->log->logInfo("Request method: {$requestMethod}");
- $this->log->logInfo("Request payload", $request);
- $this->handleFormReturn($request);
+ $this->log->logInfo('Resumen de retorno de Webpay', PluginLogger::sanitizeContextForLogs([
+ 'method' => $requestMethod,
+ 'flow' => $webpayFlow,
+ 'token_ws' => $request['token_ws'] ?? null,
+ 'TBK_TOKEN' => $request['TBK_TOKEN'] ?? null,
+ 'TBK_ID_SESION' => $request['TBK_ID_SESION'] ?? null,
+ 'TBK_ORDEN_COMPRA' => $request['TBK_ORDEN_COMPRA'] ?? null,
+ ]));
+ $this->handleFormReturn($request, $webpayFlow);
} catch (Exception | Error $e) {
$this->log->logError('Error en el proceso de validación de pago', ['error' => $e->getMessage()]);
$this->setPaymentErrorPage(self::WEBPAY_EXCEPTION_FLOW_MESSAGE);
@@ -75,23 +89,27 @@
* @throws EcommerceException If the payment flow is not recognized.
* @return void
*/
- protected function handleFormReturn(array $request): void
+ protected function handleFormReturn(array $request, ?string $webpayFlow = null): void
{
- $webpayFlow = $this->getWebpayFlow($request);
+ $webpayFlow = $webpayFlow ?? $this->getWebpayFlow($request);
if ($webpayFlow == self::WEBPAY_NORMAL_FLOW) {
+ RequestInputHelper::assertValidIdentifier($request['token_ws'], 'token_ws');
$this->handleNormalFlow($request['token_ws']);
}
if ($webpayFlow == self::WEBPAY_TIMEOUT_FLOW) {
+ RequestInputHelper::assertValidIdentifier($request['TBK_ORDEN_COMPRA'], 'TBK_ORDEN_COMPRA');
$this->handleFlowTimeout($request['TBK_ORDEN_COMPRA']);
}
if ($webpayFlow == self::WEBPAY_ABORTED_FLOW) {
+ RequestInputHelper::assertValidIdentifier($request['TBK_TOKEN'], 'TBK_TOKEN');
$this->handleFlowAborted($request['TBK_TOKEN']);
}
if ($webpayFlow == self::WEBPAY_ERROR_FLOW) {
+ RequestInputHelper::assertValidIdentifier($request['token_ws'], 'token_ws');
$this->handleFlowError($request['token_ws']);
}
@@ -113,19 +131,31 @@
$tbkIdSession = $request['TBK_ID_SESION'] ?? null;
$webpayFlow = self::WEBPAY_INVALID_FLOW;
- if (isset($tokenWs) && isset($tbkToken)) {
+ if (RequestInputHelper::hasValue($tokenWs) && RequestInputHelper::hasValue($tbkToken)) {
return self::WEBPAY_ERROR_FLOW;
}
- if (isset($tbkIdSession) && isset($tbkToken) && !isset($tokenWs)) {
+ if (
+ RequestInputHelper::hasValue($tbkIdSession)
+ && RequestInputHelper::hasValue($tbkToken)
+ && !RequestInputHelper::hasValue($tokenWs)
+ ) {
$webpayFlow = self::WEBPAY_ABORTED_FLOW;
}
- if (isset($tbkIdSession) && !isset($tbkToken) && !isset($tokenWs)) {
+ if (
+ RequestInputHelper::hasValue($tbkIdSession)
+ && !RequestInputHelper::hasValue($tbkToken)
+ && !RequestInputHelper::hasValue($tokenWs)
+ ) {
$webpayFlow = self::WEBPAY_TIMEOUT_FLOW;
}
- if (isset($tokenWs) && !isset($tbkToken) && !isset($tbkIdSession)) {
+ if (
+ RequestInputHelper::hasValue($tokenWs)
+ && !RequestInputHelper::hasValue($tbkToken)
+ && !RequestInputHelper::hasValue($tbkIdSession)
+ ) {
$webpayFlow = self::WEBPAY_NORMAL_FLOW;
}
@@ -140,7 +170,10 @@
*/
protected function handleNormalFlow(string $token): void
{
- $this->log->logInfo("Procesando transacción por flujo Normal", ['token' => $token]);
+ $this->log->logInfo(
+ "Procesando transacción por flujo Normal",
+ PluginLogger::sanitizeContextForLogs(['token' => $token])
+ );
if ($this->transactionService->checkIsAlreadyProcessed($token)) {
$this->handleTransactionAlreadyProcessed($token);
@@ -148,9 +181,25 @@
}
$webpayTransaction = $this->transactionService->findFirstByToken($token);
+
+ if (!$webpayTransaction) {
+ $message = "No se encontró la transacción para el token proporcionado.";
+ $this->log->logError(
+ $message,
+ PluginLogger::sanitizeContextForLogs(['token' => $token])
+ );
+ throw new EcommerceException($message);
+ }
+
$wooCommerceOrder = $this->ecommerceService->getOrderById($webpayTransaction->order_id);
$commitResponse = $this->webpayService->commitTransaction($token);
+ if ($commitResponse->getStatus() === null || $commitResponse->getResponseCode() === null) {
+ $message = "La respuesta de confirmación de Transbank es inválida.";
+ $this->log->logError($message, PluginLogger::sanitizeContextForLogs(['token' => $token]));
+ throw new EcommerceException($message);
+ }
+
if ($commitResponse->isApproved()) {
$this->handleAuthorizedTransaction(
$wooCommerceOrder,
@@ -170,7 +219,7 @@
*/
protected function handleFlowTimeout(string $buyOrder): void
{
- $this->log->logInfo("Procesando transacción por flujo timeout", ['buyOrder' => $buyOrder]);
+ $this->log->logInfo("Procesando transacción por flujo timeout");
$webpayTransaction = $this->transactionService->getByBuyOrder($buyOrder);
@@ -195,9 +244,17 @@
*/
protected function handleFlowAborted(string $token): void
{
- $this->log->logInfo("Procesando transacción por flujo de pago abortado", ['token' => $token]);
+ $this->log->logInfo(
+ "Procesando transacción por flujo de pago abortado",
+ PluginLogger::sanitizeContextForLogs(['token' => $token])
+ );
$webpayTransaction = $this->transactionService->findFirstByToken($token);
+ if (!$webpayTransaction) {
+ $message = 'No se encontró la transacción abortada para el token proporcionado.';
+ $this->log->logError($message, PluginLogger::sanitizeContextForLogs(['token' => $token]));
+ throw new EcommerceException($message);
+ }
if ($this->checkTransactionIsAlreadyProcessedByStatus($webpayTransaction->status)) {
$this->handleTransactionAlreadyProcessed($token);
@@ -222,10 +279,15 @@
{
$this->log->logInfo(
"Procesando transacción por flujo de error en formulario de pago",
- ['token' => $token]
+ PluginLogger::sanitizeContextForLogs(['token' => $token])
);
$webpayTransaction = $this->transactionService->findFirstByToken($token);
+ if (!$webpayTransaction) {
+ $message = 'No se encontró la transacción con error para el token proporcionado.';
+ $this->log->logError($message, PluginLogger::sanitizeContextForLogs(['token' => $token]));
+ throw new EcommerceException($message);
+ }
if ($this->transactionService->checkIsAlreadyProcessed($token)) {
$this->handleTransactionAlreadyProcessed($token);
@@ -256,10 +318,10 @@
$commitResponse
): void {
$token = $webpayTransaction->token;
- $this->log->logInfo("Transacción autorizada por Transbank", [
+ $this->log->logInfo("Transacción autorizada por Transbank", PluginLogger::sanitizeContextForLogs([
+ 'buyOrder' => $commitResponse->getBuyOrder(),
'token' => $token,
- 'buyOrder' => $commitResponse->getBuyOrder()
- ]);
+ ]));
$this->transactionService->update(
$webpayTransaction->id,
@@ -291,8 +353,10 @@
$webpayTransaction,
TransactionCommitResponse $commitResponse
): void {
- $token = $webpayTransaction->token;
- $this->log->logInfo("Transacción rechazada por Transbank", ['token' => $token, 'status' => $commitResponse->getStatus()]);
+ $this->log->logInfo("Transacción rechazada por Transbank", PluginLogger::sanitizeContextForLogs([
+ 'status' => $commitResponse->getStatus(),
+ 'token' => $webpayTransaction->token,
+ ]));
$wooCommerceOrder = $this->ecommerceService->getOrderById($webpayTransaction->order_id);
$this->ecommerceService->setWebpayOrderAsFailed($wooCommerceOrder, $webpayTransaction, $commitResponse);
@@ -315,9 +379,15 @@
*/
protected function handleTransactionAlreadyProcessed(string $token): void
{
- $this->log->logInfo("Transacción ya se encontraba procesada", ['token' => $token]);
+ $this->log->logInfo(
+ "Transacción ya se encontraba procesada",
+ PluginLogger::sanitizeContextForLogs(['token' => $token])
+ );
$webpayTransaction = $this->transactionService->findFirstByToken($token);
+ if (!$webpayTransaction) {
+ throw new EcommerceException('No se encontró la transacción previamente procesada para el token proporcionado.');
+ }
$status = $webpayTransaction->status;
$errorCode = self::WEBPAY_EXCEPTION_FLOW_MESSAGE;
@@ -364,7 +434,7 @@
): void {
$this->log->logInfo(
"Error al procesar transacción por Transbank",
- ['Token' => $webpayTransaction->token]
+ PluginLogger::sanitizeContextForLogs(['token' => $webpayTransaction->token])
);
$data = [
--- a/transbank-webpay-plus-rest/src/Controllers/FinishOneclickController.php
+++ b/transbank-webpay-plus-rest/src/Controllers/FinishOneclickController.php
@@ -5,6 +5,7 @@
use Exception;
use Throwable;
use TransbankPluginHelpersTbkConstants;
+use TransbankWooCommerceWebpayRestHelpersRequestInputHelper;
use TransbankWooCommerceWebpayRestHelpersTbkFactory;
use TransbankWooCommerceWebpayRestHelpersBlocksHelper;
use TransbankWooCommerceWebpayRestServicesInscriptionService;
@@ -43,17 +44,31 @@
{
try {
$this->log->logInfo('Procesando retorno desde formulario Oneclick');
- $method = $_SERVER['REQUEST_METHOD'];
- $data = $method === 'GET' ? $_GET : $_POST;
+ $method = RequestInputHelper::resolveRequestMethod($_SERVER);
+ $rawData = $method === 'GET' ? $_GET : $_POST;
+ $data = RequestInputHelper::sanitizeExpectedFields($rawData, [
+ 'TBK_TOKEN',
+ 'TBK_ID_SESION',
+ 'TBK_ORDEN_COMPRA',
+ ]);
$oneclickFlow = $this->getOneclickFlow($data);
+ $this->log->logInfo('Resumen de retorno de Oneclick', PluginLogger::sanitizeContextForLogs([
+ 'method' => $method,
+ 'flow' => $oneclickFlow,
+ 'TBK_TOKEN' => $data['TBK_TOKEN'] ?? null,
+ 'TBK_ID_SESION' => $data['TBK_ID_SESION'] ?? null,
+ 'TBK_ORDEN_COMPRA' => $data['TBK_ORDEN_COMPRA'] ?? null,
+ ]));
$this->log->logInfo('Flujo de inscripción Oneclick:', [
'flow' => $oneclickFlow
]);
if ($oneclickFlow === self::ONECLICK_ABORTED_FLOW) {
+ RequestInputHelper::assertValidIdentifier($data['TBK_TOKEN'], 'TBK_TOKEN');
$this->handleAbortedFlow($data['TBK_TOKEN']);
}
if ($oneclickFlow === self::ONECLICK_NORMAL_FLOW) {
+ RequestInputHelper::assertValidIdentifier($data['TBK_TOKEN'], 'TBK_TOKEN');
$this->handleNormalFlow($data['TBK_TOKEN']);
}
if ($oneclickFlow === self::ONECLICK_ERROR_FLOW) {
@@ -75,15 +90,9 @@
*/
protected function getOneclickFlow(array $requestData): string
{
- $token = isset($requestData["TBK_TOKEN"]);
- $tbkSessionId = isset($requestData['TBK_ID_SESION']);
- $tbkOrdenCompra = isset($requestData['TBK_ORDEN_COMPRA']);
-
- $this->log->logInfo('Datos recibidos desde formulario Oneclick', [
- 'token' => $token ? $requestData["TBK_TOKEN"] : null,
- 'tbkSessionId' => $tbkSessionId ? $requestData['TBK_ID_SESION'] : null,
- 'tbkOrdenCompra' => $tbkOrdenCompra ? $requestData['TBK_ORDEN_COMPRA'] : null,
- ]);
+ $token = RequestInputHelper::hasValue($requestData["TBK_TOKEN"] ?? null);
+ $tbkSessionId = RequestInputHelper::hasValue($requestData['TBK_ID_SESION'] ?? null);
+ $tbkOrdenCompra = RequestInputHelper::hasValue($requestData['TBK_ORDEN_COMPRA'] ?? null);
if ($token && !$tbkSessionId && !$tbkOrdenCompra) {
return self::ONECLICK_NORMAL_FLOW;
@@ -103,10 +112,14 @@
*/
protected function handleAbortedFlow(string $token): void
{
- $this->log->logInfo('Inscripcion abortada por el usuario desde el formulario Oneclick', [
- 'token' => $token
- ]);
+ $this->log->logInfo(
+ 'Inscripcion abortada por el usuario desde el formulario Oneclick',
+ PluginLogger::sanitizeContextForLogs(['token' => $token])
+ );
$ins = $this->inscriptionService->findByToken($token);
+ if (!$ins) {
+ throw new EcommerceException('No se encontró la inscripción para el token proporcionado.');
+ }
BlocksHelper::addLegacyNotices('Inscripción abortada desde el formulario. Puedes reintentar la inscripción. ', 'warning');
$this->inscriptionService->update($ins->id, [
'status' => TbkConstants::INSCRIPTIONS_STATUS_FAILED
@@ -125,13 +138,18 @@
*/
private function handleNormalFlow(string $token)
{
+ $ins = null;
+
try {
$ins = $this->inscriptionService->getByToken($token);
- $this->log->logInfo('Finalizando inscripción', [
- 'token' => $token,
+ if (!$ins) {
+ throw new EcommerceException('No se encontró la inscripción para el token proporcionado.');
+ }
+ $this->log->logInfo('Finalizando inscripción', PluginLogger::sanitizeContextForLogs([
'userName' => $ins->username,
- 'email' => $ins->email
- ]);
+ 'email' => $ins->email,
+ 'token' => $token,
+ ]));
$resp = $this->oneclickInscriptionService->finishInscription(
$token
);
@@ -167,15 +185,22 @@
$this->log->logInfo('Inscripción finalizada correctamente', ['user' => $ins->user_id]);
$this->redirectUser($from, BlocksHelper::ONECLICK_SUCCESSFULL_INSCRIPTION);
} catch (Exception $e) {
- $this->log->logError('Error al confirmar la inscripción', [
+ $errorContext = [
'token' => $token,
- 'userName' => $ins->username,
- 'email' => $ins->email,
'error' => $e->getMessage(),
- ]);
+ ];
+
+ if ($ins) {
+ $errorContext['userName'] = $ins->username;
+ $errorContext['email'] = $ins->email;
+ }
+
+ $this->log->logError('Error al confirmar la inscripción', PluginLogger::sanitizeContextForLogs($errorContext));
BlocksHelper::addLegacyNotices($e->getMessage(), 'error');
- $this->inscriptionService->updateWithFinishResponseError($ins->id, 'error', $e->getMessage());
- $this->redirectUser($ins->from, BlocksHelper::ONECLICK_FINISH_ERROR);
+ if ($ins) {
+ $this->inscriptionService->updateWithFinishResponseError($ins->id, 'error', $e->getMessage());
+ }
+ $this->redirectUser($ins ? $ins->from : null, BlocksHelper::ONECLICK_FINISH_ERROR);
}
}
--- a/transbank-webpay-plus-rest/src/Helpers/RequestInputHelper.php
+++ b/transbank-webpay-plus-rest/src/Helpers/RequestInputHelper.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace TransbankWooCommerceWebpayRestHelpers;
+
+use TransbankPluginExceptionsEcommerceException;
+
+final class RequestInputHelper
+{
+ private const IDENTIFIER_PATTERN = '/^[A-Za-z0-9:_-]+$/';
+ private const MAX_IDENTIFIER_LENGTH = 255;
+
+ public static function resolveRequestMethod(array $server): string
+ {
+ $requestMethod = sanitize_text_field($server['REQUEST_METHOD'] ?? '');
+
+ if ($requestMethod === '') {
+ return 'GET';
+ }
+
+ return $requestMethod;
+ }
+
+ public static function sanitizeExpectedFields(array $request, array $fields): array
+ {
+ $sanitized = [];
+
+ foreach ($fields as $field) {
+ $sanitized[$field] = sanitize_text_field((string) ($request[$field] ?? ''));
+ }
+
+ return $sanitized;
+ }
+
+ public static function hasValue(?string $value): bool
+ {
+ return is_string($value) && trim($value) !== '';
+ }
+
+ public static function assertValidIdentifier(?string $value, string $fieldName): void
+ {
+ if (!self::hasValue($value)) {
+ throw new EcommerceException("Parámetro inválido recibido: {$fieldName}");
+ }
+
+ if (strlen($value) > self::MAX_IDENTIFIER_LENGTH || !preg_match(self::IDENTIFIER_PATTERN, $value)) {
+ throw new EcommerceException("Formato inválido recibido para: {$fieldName}");
+ }
+ }
+}
--- a/transbank-webpay-plus-rest/templates/admin/log.php
+++ b/transbank-webpay-plus-rest/templates/admin/log.php
@@ -5,20 +5,21 @@
$logDirectoryTitle = "Carpeta en el servidor en donde se guardan los archivos" .
" con la información de cada compra mediante Webpay";
$lineCountTitle = "Cantidad de líneas que posee el último archivo de registro creado";
+$selectedFilename = isset($lastLog['filename']) ? basename((string) $lastLog['filename']) : '';
?>
<div class="tbk-box" id="logs-container">
<h3 class="tbk_title_h3">Información de Registros</h3>
<div class="tbk-plugin-info-container">
<div class="info-column">
- <div title="<?= $logDirectoryTitle ?>" class="label label-info">?</div>
+ <div title="<?= esc_attr($logDirectoryTitle) ?>" class="label label-info">?</div>
</div>
<div class="info-column">
<span class="highlight-text"> Directorio de registros: </span>
</div>
<div class="info-column">
<span class="label">
- <?= $resume['dir'] ?>
+ <?= esc_html((string) ($resume['dir'] ?? '-')) ?>
</span>
</div>
</div>
@@ -35,24 +36,22 @@
<input type="hidden" name="page" value="transbank_webpay_plus_rest">
<input type="hidden" name="tbk_tab" value="logs">
- <select class="select label" name="log_file" id="log_file" <?= !$folderHasLogs ? "disabled" : '' ?>>
+ <select class="select label" name="log_file" id="log_file" <?= !$folderHasLogs ? 'disabled' : '' ?>>
<?php
- $options = '';
-
if (!$folderHasLogs) {
- $options = "<option value='' selected>No hay archivos log</option>";
+ ?>
+ <option value="" selected>No hay archivos log</option>
+ <?php
}
-
- foreach ($resume['logs'] as $index) {
- if($index['filename'] == basename($lastLog['filename'])) {
- $options .= "<option value='{$index['filename']}' selected>{$index['filename']}</option>";
- continue;
- }
- $options .= "<option value='{$index['filename']}'>{$index['filename']}</option>";
+ foreach ($resume['logs'] as $index) {
+ $filename = (string) ($index['filename'] ?? '');
+ ?>
+ <option value="<?= esc_attr($filename) ?>" <?= selected($filename, $selectedFilename, false) ?>>
+ <?= esc_html($filename) ?>
+ </option>
+ <?php
}
-
- echo $options;
?>
</select>
<input type="submit" class="button button-primary tbk-button-primary"
@@ -75,20 +74,20 @@
</div>
<div class="info-column-plugin">
<span class="label">
- <?= $lastLog['size'] ?? '-'; ?>
+ <?= esc_html((string) ($lastLog['size'] ?? '-')) ?>
</span>
</div>
</div>
<div class="tbk-plugin-info-container">
<div class="info-column">
- <div title="<?= $lineCountTitle ?>" class="label label-info">?</div>
+ <div title="<?= esc_attr($lineCountTitle) ?>" class="label label-info">?</div>
</div>
<div class="info-column-plugin">
<span class="highlight-text"> Cantidad de Líneas: </span>
</div>
<div class="info-column-plugin">
<span class="label">
- <?= $lastLog['lines'] ?? '-'; ?>
+ <?= esc_html((string) ($lastLog['lines'] ?? '-')) ?>
</span>
</div>
</div>
@@ -96,25 +95,27 @@
<?php
if (isset($lastLog['content'])) {
- $logContent = '<div class="log-container">';
-
+ ?>
+ <div class="log-container">
+ <?php
$logLines = explode("n", $lastLog['content']);
foreach ($logLines as $line) {
$chunks = explode(' > ', $line);
- $date = $chunks[0];
+ $date = $chunks[0] ?? null;
$level = $chunks[1] ?? null;
$message = $chunks[2] ?? null;
if (!is_null($date) && !is_null($level) && !is_null($message)) {
- $logContent .= '<pre class="log-line">' . $date . ' > ' .
- '<span class="log-' . strtolower($level) . '">' . $level . '</span> > ' . $message .
- '</pre>';
+ ?>
+ <pre class="log-line"><?= esc_html($date) ?> > <span class="<?= esc_attr('log-' . strtolower($level)) ?>"><?= esc_html($level) ?></span> > <?= esc_html($message) ?></pre>
+ <?php
}
}
- $logContent .= '</div>';
- echo $logContent;
+ ?>
+ </div>
+ <?php
}
?>
</div>
--- a/transbank-webpay-plus-rest/vendor-prefixed/composer/autoload_psr4.php
+++ b/transbank-webpay-plus-rest/vendor-prefixed/composer/autoload_psr4.php
@@ -5,4 +5,4 @@
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
-return array('TransbankWooCommerceWebpayRest\' => array($baseDir . '/src'), 'TransbankPlugin\' => array($baseDir . '/shared'), 'TransbankVendor\Transbank\' => array($vendorDir . '/transbank/transbank-sdk/src'), 'PsrLog\' => array($vendorDir . '/psr/log/src'), 'PsrHttpMessage\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'), 'PsrHttpClient\' => array($vendorDir . '/psr/http-client/src'), 'TransbankVendor\Monolog\' => array($vendorDir . '/monolog/monolog/src/Monolog'), 'GuzzleHttpPsr7\' => array($vendorDir . '/guzzlehttp/psr7/src'), 'GuzzleHttpPromise\' => array($vendorDir . '/guzzlehttp/promises/src'), 'TransbankVendor\GuzzleHttp\' => array($vendorDir . '/guzzlehttp/guzzle/src'));
+return array('TransbankWooCommerceWebpayRest\' => array($baseDir . '/src'), 'TransbankPlugin\' => array($baseDir . '/shared'), 'TransbankVendor\Transbank\' => array($vendorDir . '/transbank/transbank-sdk/src'), 'TransbankVendorPsrLog\' => array($vendorDir . '/psr/log/src'), 'TransbankVendorPsrHttpMessage\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'), 'TransbankVendorPsrHttpClient\' => array($vendorDir . '/psr/http-client/src'), 'TransbankVendor\Monolog\' => array($vendorDir . '/monolog/monolog/src/Monolog'), 'TransbankVendorGuzzleHttpPsr7\' => array($vendorDir . '/guzzlehttp/psr7/src'), 'TransbankVendorGuzzleHttpPromise\' => array($vendorDir . '/guzzlehttp/promises/src'), 'TransbankVendor\GuzzleHttp\' => array($vendorDir . '/guzzlehttp/guzzle/src'));
--- a/transbank-webpay-plus-rest/vendor-prefixed/composer/autoload_static.php
+++ b/transbank-webpay-plus-rest/vendor-prefixed/composer/autoload_static.php
@@ -6,8 +6,8 @@
class ComposerStaticInitf6e1557513b25646ab1b95c528dcf2b9
{
public static $files = array('7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php');
- public static $prefixLengthsPsr4 = array('T' => array('TransbankWooCommerceWebpayRest\' => 33, 'TransbankPlugin\' => 17, 'TransbankVendor\Transbank\' => 10), 'P' => array('PsrLog\' => 8, 'PsrHttpMessage\' => 17, 'PsrHttpClient\' => 16), 'M' => array('TransbankVendor\Monolog\' => 8), 'G' => array('GuzzleHttpPsr7\' => 16, 'GuzzleHttpPromise\' => 19, 'TransbankVendor\GuzzleHttp\' => 11));
- public static $prefixDirsPsr4 = array('TransbankWooCommerceWebpayRest\' => array(0 => __DIR__ . '/../..' . '/src'), 'TransbankPlugin\' => array(0 => __DIR__ . '/../..' . '/shared'), 'TransbankVendor\Transbank\' => array(0 => __DIR__ . '/..' . '/transbank/transbank-sdk/src'), 'PsrLog\' => array(0 => __DIR__ . '/..' . '/psr/log/src'), 'PsrHttpMessage\' => array(0 => __DIR__ . '/..' . '/psr/http-factory/src', 1 => __DIR__ . '/..' . '/psr/http-message/src'), 'PsrHttpClient\' => array(0 => __DIR__ . '/..' . '/psr/http-client/src'), 'TransbankVendor\Monolog\' => array(0 => __DIR__ . '/..' . '/monolog/monolog/src/Monolog'), 'GuzzleHttpPsr7\' => array(0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src'), 'GuzzleHttpPromise\' => array(0 => __DIR__ . '/..' . '/guzzlehttp/promises/src'), 'TransbankVendor\GuzzleHttp\' => array(0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src'));
+ public static $prefixLengthsPsr4 = array('T' => array('TransbankWooCommerceWebpayRest\' => 33, 'TransbankPlugin\' => 17, 'TransbankVendor\Transbank\' => 10), 'P' => array('TransbankVendorPsrLog\' => 8, 'TransbankVendorPsrHttpMessage\' => 17, 'TransbankVendorPsrHttpClient\' => 16), 'M' => array('TransbankVendor\Monolog\' => 8), 'G' => array('TransbankVendorGuzzleHttpPsr7\' => 16, 'TransbankVendorGuzzleHttpPromise\' => 19, 'TransbankVendor\GuzzleHttp\' => 11));
+ public static $prefixDirsPsr4 = array('TransbankWooCommerceWebpayRest\' => array(0 => __DIR__ . '/../..' . '/src'), 'TransbankPlugin\' => array(0 => __DIR__ . '/../..' . '/shared'), 'TransbankVendor\Transbank\' => array(0 => __DIR__ . '/..' . '/transbank/transbank-sdk/src'), 'TransbankVendorPsrLog\' => array(0 => __DIR__ . '/..' . '/psr/log/src'), 'TransbankVendorPsrHttpMessage\' => array(0 => __DIR__ . '/..' . '/psr/http-factory/src', 1 => __DIR__ . '/..' . '/psr/http-message/src'), 'TransbankVendorPsrHttpClient\' => array(0 => __DIR__ . '/..' . '/psr/http-client/src'), 'TransbankVendor\Monolog\' => array(0 => __DIR__ . '/..' . '/monolog/monolog/src/Monolog'), 'TransbankVendorGuzzleHttpPsr7\' => array(0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src'), 'TransbankVendorGuzzleHttpPromise\' => array(0 => __DIR__ . '/..' . '/guzzlehttp/promises/src'), 'TransbankVendor\GuzzleHttp\' => array(0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src'));
public static $classMap = array('ComposerInstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php');
public static function getInitializer(ComposerAutoloadClassLoader $loader)
{
--- a/transbank-webpay-plus-rest/vendor-prefixed/composer/installed.php
+++ b/transbank-webpay-plus-rest/vendor-prefixed/composer/installed.php
@@ -2,4 +2,4 @@
namespace TransbankVendor;
-return array('root' => array('name' => 'transbank/woocommerce-plugin', 'pretty_version' => '1.13.0', 'version' => '1.13.0.0', 'reference' => 'f4149eea61cbc518c64f988d70fe55b8bd0e7629', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => false), 'versions' => array('guzzlehttp/guzzle' => array('pretty_version' => '7.10.0', 'version' => '7.10.0.0', 'reference' => 'b51ac707cfa420b7bfd4e4d5e510ba8008e822b4', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/guzzle', 'aliases' => array(), 'dev_requirement' => false), 'guzzlehttp/promises' => array('pretty_version' => '2.3.0', 'version' => '2.3.0.0', 'reference' => '481557b130ef3790cf82b713667b43030dc9c957', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/promises', 'aliases' => array(), 'dev_requirement' => false), 'guzzlehttp/psr7' => array('pretty_version' => '2.9.0', 'version' => '2.9.0.0', 'reference' => '7d0ed42f28e42d61352a7a79de682e5e67fec884', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/psr7', 'aliases' => array(), 'dev_requirement' => false), 'monolog/monolog' => array('pretty_version' => '3.10.0', 'version' => '3.10.0.0', 'reference' => 'b321dd6749f0bf7189444158a3ce785cc16d69b0', 'type' => 'library', 'install_path' => __DIR__ . '/../monolog/monolog', 'aliases' => array(), 'dev_requirement' => false), 'psr/http-client' => array('pretty_version' => '1.0.3', 'version' => '1.0.3.0', 'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-client', 'aliases' => array(), 'dev_requirement' => false), 'psr/http-client-implementation' => array('dev_requirement' => false, 'provided' => array(0 => '1.0')), 'psr/http-factory' => array('pretty_version' => '1.1.0', 'version' => '1.1.0.0', 'reference' => '2b4765fddfe3b508ac62f829e852b1501d3f6e8a', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-factory', 'aliases' => array(), 'dev_requirement' => false), 'psr/http-factory-implementation' => array('dev_requirement' => false, 'provided' => array(0 => '1.0')), 'psr/http-message' => array('pretty_version' => '2.0', 'version' => '2.0.0.0', 'reference' => '402d35bcb92c70c026d1a6a9883f06b2ead23d71', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-message', 'aliases' => array(), 'dev_requirement' => false), 'psr/http-message-implementation' => array('dev_requirement' => false, 'provided' => array(0 => '1.0')), 'psr/log' => array('pretty_version' => '3.0.2', 'version' => '3.0.2.0', 'reference' => 'f16e1d5863e37f8d8c2a01719f5b34baa2b714d3', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/log', 'aliases' => array(), 'dev_requirement' => false), 'psr/log-implementation' => array('dev_requirement' => false, 'provided' => array(0 => '3.0.0')), 'ralouphie/getallheaders' => array('pretty_version' => '3.0.3', 'version' => '3.0.3.0', 'reference' => '120b605dfeb996808c31b6477290a714d356e822', 'type' => 'library', 'install_path' => __DIR__ . '/../ralouphie/getallheaders', 'aliases' => array(), 'dev_requirement' => false), 'symfony/deprecation-contracts' => array('pretty_version' => 'v3.6.0', 'version' => '3.6.0.0', 'reference' => '63afe740e99a13ba87ec199bb07bbdee937a5b62', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', 'aliases' => array(), 'dev_requirement' => false), 'transbank/transbank-sdk' => array('pretty_version' => '5.1.0', 'version' => '5.1.0.0', 'reference' => '4e17ccb419c69311731028f9fb7f7d42575e9745', 'type' => 'library', 'install_path' => __DIR__ . '/../transbank/transbank-sdk', 'aliases' => array(), 'dev_requirement' => false), 'transbank/woocommerce-plugin' => array('pretty_version' => '1.13.0', 'version' => '1.13.0.0', 'reference' => 'f4149eea61cbc518c64f988d70fe55b8bd0e7629', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => false)));
+return array('root' => array('name' => 'transbank/woocommerce-plugin', 'pretty_version' => '1.14.0', 'version' => '1.14.0.0', 'reference' => '0edd0b3f772e3f226fe413dcf95dd1cd82a81072', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => false), 'versions' => array('guzzlehttp/guzzle' => array('pretty_version' => '7.10.0', 'version' => '7.10.0.0', 'reference' => 'b51ac707cfa420b7bfd4e4d5e510ba8008e822b4', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/guzzle', 'aliases' => array(), 'dev_requirement' => false), 'guzzlehttp/promises' => array('pretty_version' => '2.3.0', 'version' => '2.3.0.0', 'reference' => '481557b130ef3790cf82b713667b43030dc9c957', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/promises', 'aliases' => array(), 'dev_requirement' => false), 'guzzlehttp/psr7' => array('pretty_version' => '2.9.0', 'version' => '2.9.0.0', 'reference' => '7d0ed42f28e42d61352a7a79de682e5e67fec884', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/psr7', 'aliases' => array(), 'dev_requirement' => false), 'monolog/monolog' => array('pretty_version' => '3.10.0', 'version' => '3.10.0.0', 'reference' => 'b321dd6749f0bf7189444158a3ce785cc16d69b0', 'type' => 'library', 'install_path' => __DIR__ . '/../monolog/monolog', 'aliases' => array(), 'dev_requirement' => false), 'psr/http-client' => array('pretty_version' => '1.0.3', 'version' => '1.0.3.0', 'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-client', 'aliases' => array(), 'dev_requirement' => false), 'psr/http-client-implementation' => array('dev_requirement' => false, 'provided' => array(0 => '1.0')), 'psr/http-factory' => array('pretty_version' => '1.1.0', 'version' => '1.1.0.0', 'reference' => '2b4765fddfe3b508ac62f829e852b1501d3f6e8a', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-factory', 'aliases' => array(), 'dev_requirement' => false), 'psr/http-factory-implementation' => array('dev_requirement' => false, 'provided' => array(0 => '1.0')), 'psr/http-message' => array('pretty_version' => '2.0', 'version' => '2.0.0.0', 'reference' => '402d35bcb92c70c026d1a6a9883f06b2ead23d71', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-message', 'aliases' => array(), 'dev_requirement' => false), 'psr/http-message-implementation' => array('dev_requirement' => false, 'provided' => array(0 => '1.0')), 'psr/log' => array('pretty_version' => '3.0.2', 'version' => '3.0.2.0', 'reference' => 'f16e1d5863e37f8d8c2a01719f5b34baa2b714d3', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/log', 'aliases' => array(), 'dev_requirement' => false), 'psr/log-implementation' => array('dev_requirement' => false, 'provided' => array(0 => '3.0.0')), 'ralouphie/getallheaders' => array('pretty_version' => '3.0.3', 'version' => '3.0.3.0', 'reference' => '120b605dfeb996808c31b6477290a714d356e822', 'type' => 'library', 'install_path' => __DIR__ . '/../ralouphie/getallheaders', 'aliases' => array(), 'dev_requirement' => false), 'symfony/deprecation-contracts' => array('pretty_version' => 'v3.6.0', 'version' => '3.6.0.0', 'reference' => '63afe740e99a13ba87ec199bb07bbdee937a5b62', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', 'aliases' => array(), 'dev_requirement' => false), 'transbank/transbank-sdk' => array('pretty_version' => '5.1.0', 'version' => '5.1.0.0', 'reference' => '4e17ccb419c69311731028f9fb7f7d42575e9745', 'type' => 'library', 'install_path' => __DIR__ . '/../transbank/transbank-sdk', 'aliases' => array(), 'dev_requirement' => false), 'transbank/woocommerce-plugin' => array('pretty_version' => '1.14.0', 'version' => '1.14.0.0', 'reference' => '0edd0b3f772e3f226fe413dcf95dd1cd82a81072', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => false)));
--- a/transbank-webpay-plus-rest/webpay-rest.php
+++ b/transbank-webpay-plus-rest/webpay-rest.php
@@ -38,7 +38,7 @@
* Plugin Name: Transbank Webpay
* Plugin URI: https://www.transbankdevelopers.cl/plugin/woocommerce/webpay
* Description: Recibe pagos en línea con Tarjetas de Crédito y Redcompra en tu WooCommerce a través de Webpay Plus y Webpay Oneclick.
- * Version: 1.13.0
+ * Version: 1.14.0
* Requires Plugins: woocommerce
* Author: TransbankDevelopers
* Author URI: https://www.transbank.cl