Weblogs Código

Blog Bitix

Validar documentos JSON con JSON Schema

noviembre 25, 2021 07:00

Los documentos JSON son una forma de intercambiar información entre aplicaciones. Como en cualquier intercambio de información es conveniente validar los datos recibidos antes de realizar ninguna acción. En Java dependiendo de la librería o framework utilizada aunque los datos se transmiten en formato JSON estos son transformados y recibidos como objetos Java en los cuales se realizan validaciones de tipos y conversiones de tipos y restricciones a los valores con Bean Validation o Spring Validation. La especificación JSON Schema permite definir un esquema para los documentos JSON independiente del lenguaje con la que realizar validaciones y realizar las validaciones a través de implementaciones en los diferentes lenguajes de programación incluido Java.

Java

Una tarea fundamental en toda aplicación es validar los datos de entrada. Validar los datos evita errores al procesar los datos, generar datos erróneos como resultado o realizar acciones en base a datos no válidos con consecuencias como realizar acciones no deseadas o crear inconsistencias en la base de datos. También hay que validar los datos por motivos de seguridad.

Los datos de entrada de un programa se proporcionan en función de la naturaleza de la aplicación, en una aplicación web o REST es a través de los datos de la petición, en una aplicación que procesa mensajes de servicios como Kafka o RabbitMQ los datos se incluyen en los datos del mensaje y en una aplicación de procesos batch los datos quizá estén en archivos.

Los formatos más comunes para el intercambio de datos son XML, JSON y CSV. El formato de documentos XML permite comprobar está bien formado en cuanto a balanceo de etiquetas junto a otros requerimientos, los esquemas XML permiten validar además si un documento XML cumple con el esquema incluyendo las etiquetas requeridas. JSON es una especificación que de por si no define ningún esquema, esto hace que los documentos JSON puedan tener cualesquiera datos mientras utilicen una sintaxis correcta o tengan un formato correcto. Sin embargo, en la validación de datos el que un documento JSON tenga una sintaxis correcta no es suficiente que se considere válido. Un esquema permite definir que un documento incluya ciertas propiedades, que estás se ajusten a unos valores predeterminados, que cumplan ciertas reglas de validación como un tipo o rango de valores.

La especificación JSON Schema es el equivalente para los documentos JSON de XML Schema para los documentos XML. JSON Schema permite validar que un documento JSON se ajusta a un esquema conteniendo los datos y valores definidos en el esquema.

Contenido del artículo

La especificación JSON Schema

La especificación de JSON Schema tiene varias definiciones formales y versiones. En la guía de inicio paso a paso se incluye una descripción más sencilla y práctica para un primer inicio.

Un esquema de JSON contiene a qué versión de la especificación se ajusta, el identificador o la ubicación del esquema, un título, una descripción y el tipo de objeto del documento raíz. Además define qué propiedades junto con sus tipos ha de contener el documento JSON al que se aplica, cuáles de esas propiedades son requeridas y las validaciones sobre los datos como restricciones en los valores de los datos o elementos de un array. Además de propiedades un documento permite la anidación de estructuras en las que también se definen que propiedades contienen y cuáles son requeridas. Finalmente, un esquema JSON permite referenciar un esquema JSON externo.

En el siguiente esquema $schema define la versión del esquema que implementa, $id define el identificador del esquema. Las propiedades title, description proporcionan una descripción del esquema y type el tipo de objeto raíz. En la propiedad properties se definen las propiedades del documento JSON y en la propiedad required cuáles de esas propiedades son requeridas. En la propiedad dimensions están las estructuras JSON anidadas. Y con la propiedad $ref se referencia otro esquema JSON.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://example.com/product.schema.json",
    "title": "Product",
    "description": "A product from Acme's catalog",
    "type": "object",
    "properties": {
      "productId": {
        "description": "The unique identifier for a product",
        "type": "integer"
      },
      "productName": {
        "description": "Name of the product",
        "type": "string"
      },
      "price": {
        "description": "The price of the product",
        "type": "number",
        "exclusiveMinimum": 0
      },
      "tags": {
        "description": "Tags for the product",
        "type": "array",
        "items": {
          "type": "string"
        },
        "minItems": 1,
        "uniqueItems": true
      },
      "dimensions": {
        "type": "object",
        "properties": {
          "length": {
            "type": "number"
          },
          "width": {
            "type": "number"
          },
          "height": {
            "type": "number"
          }
        },
        "required": [
          "length",
          "width",
          "height"
        ]
      },
      "warehouseLocation": {
        "description": "Coordinates of the warehouse where the product is located.",
        "$ref": "https://example.com/geographical-location.schema.json"
      }
    },
    "required": [
      "productId",
      "productName",
      "price"
    ]
  }
product.schema.json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
    "$id": "https://example.com/geographical-location.schema.json",
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "Longitude and Latitude",
    "description": "A geographical coordinate on a planet (most commonly Earth).",
    "required": [
      "latitude",
      "longitude"
    ],
    "type": "object",
    "properties": {
      "latitude": {
        "type": "number",
        "minimum": -90,
        "maximum": 90
      },
      "longitude": {
        "type": "number",
        "minimum": -180,
        "maximum": 180
      }
    }
  }
geographical-location.schema.json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{
  "productId": 1,
  "productName": "An ice sculpture",
  "price": 12.5,
  "tags": [
    "cold",
    "ice"
  ],
  "dimensions": {
    "length": 7,
    "width": 12,
    "height": 9.5
  },
  "warehouseLocation": {
    "latitude": -78.75,
    "longitude": 20.4
  }
}
product.json
1
2
{
}
product-invalid.json

Librerías JSON Schema en Java

Hay varias librerías Java que implementan validación de JSON con la especificación de JSON Schema, junto a otras implementaciones en otros lenguajes. De entre las implementaciones Java una de ellas es JSON Schema Validator de networknt en la que los errores que se detectan son devueltos en una estructura de datos en vez de lanzar una excepción en caso de que la validación falle.

Otra de sus funcionalidades es que permite hacer una correspondencia entre los identificadores de los esquemas JSON a recursos locales, útil en caso de que los esquemas no estén publicados en sus direcciones, en aplicaciones en las que no tengan conexión a internet o no se desea que estas realicen conexiones externas.

Hay que tener en cuenta que varias de estas librerías están implementadas por personas sin seguramente el respaldo de una organización, hay que tenerlo en cuenta como criterio de decisión en el caso de añadir como dependencia de un proyecto una de las implementaciones.

Ejemplo con Java de validar un JSON con JSON Schema

Este es un ejemplo que a partir de un documento JSON se valida que cumple el esquema contra el que se valida. En el caso de que el documento JSON no cumpla el esquema se devuelven los errores como resultado del método de validación, en el caso del ejemplo los errores son emitidos a la salida estándar donde se aprecia que en el caso de la validación del JSON inválido faltan las tres propiedades requeridas.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package io.github.picodotdev.blogbitix.jsonschema;

import java.net.URI;
import java.util.Map;
import java.util.Set;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.networknt.schema.JsonSchema;
import com.networknt.schema.JsonSchemaFactory;
import com.networknt.schema.SpecVersion;
import com.networknt.schema.ValidationMessage;

public class Main {

    public static void main(String[] args) throws Exception {
        Map<String, String> urlMappings = Map.of("https://picodotdev.github.io/blog-bitix/misc/json/product.schema.json", "resource:/product.schema.json",
                "https://picodotdev.github.io/blog-bitix/misc/json/geographical-location.schema.json", "resource:/geographical-location.schema.json");
        ObjectMapper mapper = new ObjectMapper();
        JsonSchemaFactory factory = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V201909))
                .objectMapper(mapper)
                .addUriMappings(urlMappings)
                .build();

        JsonSchema schema = factory.getSchema(URI.create("resource:/product.schema.json"));

        {
            JsonNode json = mapper.readTree(Main.class.getResourceAsStream("/product.json"));
            Set<ValidationMessage> errors = schema.validate(json);
            System.out.printf("Valid JSON errors: %d5n", errors.size());
        }

        {
            JsonNode json = mapper.readTree(Main.class.getResourceAsStream("/product-invalid.json"));
            Set<ValidationMessage> errors = schema.validate(json);
            System.out.printf("Valid JSON errors: %d%n", errors.size());
            errors.stream().forEach(it -> {
                System.out.printf("Type: %s%n", it.getType());
                System.out.printf("Message: %s%n", it.getMessage());
            });
        }
    }
}
Main.java
1
2
3
4
5
6
7
8
Valid JSON errors: 0
Invalid JSON errors: 3
Type: required
Message: $.productId: is missing but it is required
Type: required
Message: $.productName: is missing but it is required
Type: required
Message: $.price: is missing but it is required
System.out

La librería de JSON Schema Validator además de su propia dependencia requiere incluir otras en el archivo de construcción, en este caso de Gradle.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
plugins {
    id 'application'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'com.networknt:json-schema-validator:1.0.64'
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.0'
    implementation 'org.slf4j:slf4j-api:1.7.32'
    implementation 'org.apache.commons:commons-lang3:3.12.0'
}

application {
    mainClass = 'io.github.picodotdev.blogbitix.jsonschema.Main'
}
build.gradle

Otras formas de validación con Bean Validation y Spring Validation

Otra forma de validar un JSON es cargarlo en un objeto Java y validar el objeto con Bean Validation o Spring Validation. La diferencia en este caso respeto a JSON Schema es que Bean Validation y Spring Validation es una solución específica de Java, requiere cargar los datos en objetos y más importante no se define ningún esquema sino que el esquema está implícito en las validaciones ya se definan con anotaciones o con validadores personalizados.

Terminal

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando siguiente comando:
./gradlew run

» Leer más, comentarios, etc...

Arragonán

Documental sobre Squads

noviembre 24, 2021 12:00

Squads es un documental de Invision sobre el popularizado término squads, en el que se explica su origen y se muestran unas pinceladas de cómo trabajan algunos equipos que crean productos de digitales.

Mi resumen sobre el término sería algo como tener equipos multidisciplinares donde se mezclan personas con habilidades complementarias que estén alineadas para alcanzar un objetivo común, o como mínimo aspirar a ello.

El documental se centra principalmente en la parte de descubrimiento y diseño de producto (siendo Invision una compañía de diseño tampoco sorprende :)). Aparecen personas de compañías conocidas mundialmente como Atlassian, Airbnb, Youtube… y algunas startups de menor tamaño. Además de Jeff Sutherland, uno de los creadores de Scrum; y Henrik Kniberg, el de los famosos vídeos de Spotify Engineering Culture que tanto se viralizaron y terminaron en el boom del “modelo spotify” que se ha intentado replicar tantas veces, al parecer sin demasiado éxito.

Creo que es un documental interesante para cualquiera que trabaje en el mundo de producto digital, sea cual sea su perfil. Aunque también creo que idealiza y simplifica el conseguir trabajar de ese modo.

Digo esto porque, aunque creo que tener equipos multidisciplinares es la mejor estrategia para construir producto (que los llamen squads, células, scrum teams… es irrelevante), no es algo que ocurra diciéndole a un grupo de personas que tienen que trabajar en lo mismo y eso haga que se alineen mágicamente. Hay que trabajarlo e iterarlo, y aún así puede que nunca se consiga convertir a un grupo de personas en un equipo.

» Leer más, comentarios, etc...

Variable not found

Cómo evitar que entren argumentos nulos en métodos de C#: un recorrido histórico (y lo que nos trae el futuro)

noviembre 23, 2021 11:32

.NET

Estamos muy acostumbrados a comenzar nuestros métodos realizando comprobaciones para evitar que pasen a nuestro código valores nulos que pudieran romper la aplicación.

Desde el principio de los tiempos, estas guardas han presentado el siguiente aspecto:

public class MyService
{
public void MyMethod(object first, object second)
{
if(first == null)
{
throw new ArgumentNullException("first");
}
if(second == null)
{
throw new ArgumentNullException("second");
}
// ...
}
}

¿Todo bien, verdad? El código es aparentemente correcto y fácil de comprender, pero... ¡demasiado extenso! Hemos consumido casi diez líneas de código sólo realizando comprobaciones de "fontanería", y ni siquiera hemos empezado a plantear la funcionalidad real del método.

Afortunadamente, con el tiempo C# ha ido evolucionando y mejorando sucesivamente este escenario tan frecuente.

C# 6: el operador nameof

Aunque no iba en la línea de simplificar el código, el operador nameof, introducido en C# 6, permitió solucionar un pequeño problema que tenían esas comprobaciones, potencial causante de problemas o confusiones. Estábamos creando una sutil y frágil dependencia entre el nombre del parámetro a nivel de código y la cadena que estamos enviando al constructor de la excepción ArgumentNullException:

if(first == null) 
{
throw new ArgumentNullException("first");
}

Esto se puede entender rápidamente si refactorizamos el método para renombrar el parámetro first a one. El código resultante sería el siguiente, donde podemos ver que el valor enviado al instanciar la excepción no se corresponde con el nombre real del parámetro, pues al tratarse de una cadena de texto no se ha visto afectada por el renombrado:

public void MyMethod(object one, object second)
{
if(one == null)
{
throw new ArgumentNullException("first"); // Debería ser "one"!
}
...
}

Si bien no es un error, ciertamente podría despistar al ver la excepción, pues haría referencia a un parámetro inexistente (o, en el peor de los casos, a un parámetro incorrecto):

Unhandled exception. System.ArgumentNullException: Value cannot be null. Parameter name: first

El operador nameof permite obtener en tiempo de ejecución el nombre asignado a nivel de código fuente a cualquier tipo de elemento (variables, parámetros, propiedades, métodos, etc.), de forma que evitamos estas dependencias:

public class MyService
{
public void MyMethod(object first, object second)
{
if(first == null)
{
throw new ArgumentNullException(nameof(first));
}
if(second == null)
{
throw new ArgumentNullException(nameof(second));
}
// ...
}
}

Bueno, hemos mejorado en algo, pero seguimos teniendo que escribir demasiado, ¿verdad? Por suerte, C# 7 no tardó en llegar :)

C# 7: expresiones throw

El compilador de C# 7 comenzó a mirar las instrucciones throw con otros ojos, tratándolas a todos los efectos como si fueran expresiones, gracias a la introducción de las throw expressions.

Recordemos que, en la práctica, esta característica permite introducir un throw en cualquier punto del código donde pueda ir una expresión, como en el siguiente ejemplo:

public static int Divide(int a, int b)
{
return a / (b != 0 ? b: throw new ArgumentOutOfRangeException(nameof(b)));
}

Pues bien, uniendo esto al null coalescing operator (??) introducido años atrás, en los tiempos de C# 2, permite simplificar considerablemente el código de comprobación de nulos:

public class MyService
{
public void MyMethod(object first, object second)
{
first = first ?? throw new ArgumentNullException(nameof(first));
second = second ?? throw new ArgumentNullException(nameof(second));
// ...
}
}

Vamos mejorando, pero aún el lenguaje podía darnos algo más...

C# 8: null coalescing assignment

No soy capaz de traducir el nombre de esta característica, pero intentaré explicar para qué sirve 😁. Suponed un código como el siguiente, que seguro que habéis implementado más de una vez, en el que asignamos una variable sólo si ésta contiene un nulo:

// Usando un if:
if(myObject == null)
{
myObject = new MyClass();
}

// O bien, usando el operador "??":
myObject = myObject ?? new MyClass();

El null coalescing operator permite asignar una variable cuando ésta sea null en un único paso:

myObject ??= new MyClass();

Ahora, si recordamos el punto en el que C# 7 dejó nuestro código de comprobación de argumentos nulos, vemos que la idea puede encajar bastante y ayudarnos a simplificarlo aún más:

public class MyService
{
public void MyMethod(object first, object second)
{
first ??= throw new ArgumentNullException(nameof(first));
second ??= throw new ArgumentNullException(nameof(second));
// ...
}
}

Parece difícilmente mejorable... ¿o no?

.NET 6: empoderando ArgumentNullException

Con .NET 6/C# 10 nos llega un interesante método estático en la clase ArgumentNullException que simplifica aún más el código necesario para lanzar esa excepción si el valor recibido es nulo.

public class MyService
{
public void MyMethod(object first, object second)
{
ArgumentNullException.ThrowIfNull(first);
ArgumentNullException.ThrowIfNull(second);
// ...
}
}

Imposible de mejorar, ¿verdad? Después veremos que no ;)

En cualquier caso, esta mejora es posible gracias al uso de otra novedad de C# 10, el atributo [CallerArgumentExpression]. A esto dedicaremos un post en el futuro, pero de momento basta con saber que es un atributo al estilo de [CallerMemberName], [CallerFilePath] y [CallerLineNumber], introducidos en C# 5, cuyo objetivo es obtener información sobre el consumidor de un método.

Podemos ver su utilización en el código fuente de ArgumentNullException, e intuir cómo funciona:

public class ArgumentNullException : ArgumentException
{
...
public static void ThrowIfNull(
[NotNull] object? argument,
[CallerArgumentExpression("argument")] string? paramName = null)
{
...
}
}

Si realizamos una invocación como ArgumentNullException.ThrowIfNull(first), el valor recibido en argument será el valor de first, mientras que en paramName recibiremos la cadena "first". Esto permitirá mostrar el error exactamente con la expresión utilizada en el punto de la llamada.

.NET 6 / C# 10: doble salto mortal con los global using static

Pues sí, aunque suene un poco a feature abuse, podemos darle una vuelta más al asunto haciendo uso de las directivas globales. Aunque en un post ya vimos cómo usar usings globales para importar espacios de nombres, también podemos utilizarla para facilitar el acceso a miembros estáticos.

En la práctica, podemos añadir el cualquier archivo del proyecto una directiva como la siguiente (aunque también podemos hacerlo en el .csproj):

global using static System.ArgumentNullException

Y de esta forma, podemos reducir aún más nuestro código de partida:

public class MyService
{
public void MyMethod(object first, object second)
{
ThrowIfNull(first);
ThrowIfNull(second);
// ...
}
}

Esto ya sí que no lo mejora nadie. ¿O sí?

C# vNext: simplificando el chequeo de argumentos nulos

Se está cociendo una nueva mejora en el lenguaje que probablemente será el golpe definitivo al código de chequeo de nulos al inicio de nuestros métodos.

Aunque de momento está en desarrollo y las cosas podrían cambiar, las comprobaciones simplificadas de argumentos nulos o Simplified Null Argument Checking, nos permitirán eliminar totalmente estas comprobaciones.

En su lugar, simplemente definiremos los parámetros que queremos comprobar usando una exclamación, de la siguiente forma:

public class MyService
{
public void MyMethod(object first!!, object second!!)
{
// ...
}
}

¡Voila! El único hecho de añadir esas exclamaciones al nombre del parámetro hará que en tiempo de ejecución se comprueben los valores, y se lance de forma automática una excepción ArgumentNullException cuando el valor sea nulo.

Fijaos que las exclamaciones están en el parámetro, no en su tipo: esto es así porque se trata de que el sistema añada una comprobación en tiempo de ejecución, pero no afecta al tipo del parámetro.

Punto extra: recordad que usar "==" no es la mejor forma de comprobar los nulos

Si aún con estas novedades del lenguaje y la plataforma preferís utilizar la clásica sentencia if para comprobar los nulos, es interesante que tengáis en cuenta dos cosas.

En primer lugar, ya hablamos hace tiempo de usar el operador "==" para comparar con valores nulos no era la forma más correcta de hacerlo, pues dicho operador podía ser sobrecargado para otorgarle un comportamiento distinto del esperado.

De hecho, la forma recomendable de comprobar la nulidad de un objeto es utilizar el operador is:

if(myObj is null)
{
...
}

De la misma forma, si queremos comprobar justamente lo contrario, es decir, que un objeto no sea nulo, podemos aprovechar los patrones combinacionales introducidos por C# 9 y hacerlo de esta forma tan elegante:

if(myObj is not null)
{
...
}

¡Y esto es todo! Espero que este recorrido por las diferentes opciones que tenemos y tendremos para evitar la entrada de argumentos nulos en los métodos os haya resultado interesante :)

Publicado en Variable not found.

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 463

noviembre 22, 2021 07:05

Enlaces interesantes

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET Core / .NET

ASP.NET Core / ASP.NET / Blazor

Azure / Cloud

Conceptos / Patrones / Buenas prácticas

Data

Machine learning / IA / Bots

Web / HTML / CSS / Javascript

Visual Studio / Complementos / Herramientas

Xamarin / .NET MAUI

Otros

Publicado en Variable not found.

» Leer más, comentarios, etc...

Variable not found

Generación de rutas con parámetros de query string en Blazor 6

noviembre 16, 2021 07:05

Blazor

Hasta Blazor 6, daba la impresión de que la query string era un ciudadano de segunda clase en el sistema de routing, pues no se ofrecían mecanismos sencillos para la obtención de parámetros suministrados a través de esta vía, ni tampoco para la generación de URI que los utilizaran. De hecho, estas tareas teníamos que solucionarlas manualmente, aunque fuera con ayuda de paquetes externos como Microsoft.AspNetCore.WebUtilities.

Ya con la llegada de esta versión, Blazor incorpora de serie herramientas que nos harán esto más llevadero, como su integración con el binding o, lo que veremos en este post, la posibilidad de generar direcciones que incluyan este tipo de parámetros.

Para generar rutas con parámetros de query string debemos utilizar el servicio NavigationManager que ya conocemos, al que se se han añadido los métodos GetUriWithQueryParameters() y GetUriWithQueryParameter() para tal fin.

El método GetUriWithQueryParameters() genera una URI, incluyendo en su query string los parámetros que le suministremos en forma de diccionario clave-valor. En el siguiente código, por ejemplo, vemos cómo utilizar este método para generar una URI apuntando hacia la misma página actual, estableciéndole valores para tres parámetros de query string Search, Page y PageSize, y luego usando el método NavigateTo() para mover al usuario a ella:

@page "/search"

<ul>
<li>Search: @Search</li>
<li>Page: @Page</li>
<li>PageSize: @PageSize</li>
</ul>
<button @onclick="SearchComputersClick">Search computers</button>

@code {
[Parameter, SupplyParameterFromQuery]
public string? Search { get; set; }

[Parameter, SupplyParameterFromQuery]
public int? Page { get; set; }

[Parameter, SupplyParameterFromQuery]
public int? PageSize { get; set; }

void SearchComputersClick()
{
var dict = new Dictionary<string, object>()
{
{ "search", "computers" },
{ "sage", 1 },
{ "sageSize", 20 },
};
var uri = NavManager.GetUriWithQueryParameters(dict);
NavManager.NavigateTo(uri);
}
}

Observad también el uso de [SupplyParameterFromQuery] para recuperar estos parámetros de forma muy sencilla en las propiedades del componente.

Aunque GetUriWithQueryParameters() por defecto tomará como punto de partida la URI de la página actual (NavigationManager.Uri), es posible indicarle una distinta usando otra de sus sobrecargas, como en el siguiente ejemplo:

var dict = new Dictionary<string, object>()
{
{ "search", "computers" },
... // Otras entradas del diccionario
};

// Podemos usar como base direcciones relativas al sitio:
var uri = NavManager.GetUriWithQueryParameters("/catalog", dict);
// O incluso direcciones absolutas externas:
var uri = NavManager.GetUriWithQueryParameters("https://google.es", dict);
...

Por supuesto, este método lidiará internamente con aspectos como la codificación URL, que se realizará de forma automática:

var dict = new Dictionary<string, object>()
{
{ "search", "Tom & Jerry" },
};
var uri = NavManager.GetUriWithQueryParameters("/catalog", dict);
// Returns: /catalog?search=Tom%20%26%20Jerry

El método GetUriWithParameters() no sólo añade parámetros de query string. También puede modificarlos o eliminarlos cuando partimos de una ruta que ya contenía parámetros de este tipo, aplicando una lógica bastante útil:

  • Si el diccionario añade parámetros que no se encontraban previamente en la URI original, se añaden a la dirección resultante:
var dict = new Dictionary<string, object>()
{
{ "search", "computers" }
};
var initial = "/catalog";
var uri = NavManager.GetUriWithQueryParameters(initial, dict);
// uri => /catalog?search=computers
  • Si la URL original incluye parámetros que no son sobrescritos en el diccionario, se mantienen:
var dict = new Dictionary<string, object>()
{
{ "page", "12" }
};
var initial = "/catalog?search=computers";
var uri = NavManager.GetUriWithQueryParameters(initial, dict);
// uri => /catalog?search=computers&page=12
  • Si la URI original incluye parámetros que son sobrescritos en el diccionario, se machaca el valor:
var dict = new Dictionary<string, object>()
{
{ "search", "computers" },
{ "page", "12" },
};
var initial = "/catalog?search=tv&page=1&pageSize=20";
var uri = NavManager.GetUriWithQueryParameters(initial, dict);
// uri => /catalog?search=computers&page=12&pageSize=20
  • Si la URI original incluye parámetros que son establecidos con valores nulos en el diccionario, se eliminan de la query string:
var dict = new Dictionary<string, object>()
{
{ "page", null },
{ "pageSize", null}
};
var initial = "/catalog?search=computers&page=1&pageSize=20";
var uri = NavManager.GetUriWithQueryParameters(initial, dict);
// uri => /catalog?search=computers

Por último, cabe destacar que, para evitar el uso de un diccionario cuando únicamente queremos modificar uno de los parámetros, podemos utilizar el método GetUriWithQueryParameter():

<button @onclick="IncrementPage">Next page</button>
@code {
[Parameter, SupplyParameterFromQuery]
public int Page { get; set; }

void IncrementPage()
{
Page++;
// Actualizamos solo el parámetro "page", dejando el resto intacto:
var uri = NavManager.GetUriWithQueryParameter("page", Page);

// Y navegamos a la nueva URI:
NavManager.NavigateTo(uri);
}

}

Publicado en Variable not found.

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 462

noviembre 15, 2021 07:05

Enlaces interesantes

Ahí van los enlaces recopilados durante la semana pasada, obviamente muy condicionados por la oleada de lanzamientos de nuevas versiones de casi todo. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET Core / .NET

ASP.NET Core / ASP.NET / Blazor

Azure / Cloud

Conceptos / Patrones / Buenas prácticas

Web / HTML / CSS / Javascript

Visual Studio / Complementos / Herramientas

Xamarin / .NET MAUI

    Publicado en Variable not found.

    » Leer más, comentarios, etc...

    Arragonán

    Píldora. Acceder a variables de entorno desde plantillas Thymeleaf

    noviembre 13, 2021 12:00

    Es una buena práctica depender de variables de entorno para las configuraciones, tanto secretos como cualquier otra configuración que puede cambiar entre los entornos de despliegue de nuestro software. De ese modo tenemos control granular de cada configuración en cada despliegue que hagamos, y en caso de tener que cambiar alguna configuración no es necesario hacer ningún commit en nuestro repositorio.

    A veces es algo que hay que montar un poco más a mano, pero trabajando con Spring Boot es algo que ya está resuelto y da flexibilidad al respecto. A nivel del código de infraestructura en código dependiente de Spring simplemente usando la anotación @Value ya nos inyectará el valor que haya en el application context.

    Lo que hasta hace poco no había tenido que resolver es acceder a esas variables de entorno directamente desde plantillas de Thymeleaf, en este caso para evitar tener hardcoded la configuración de Firebase Authentication.

    Buscando información encontré que, como parte de la integración con Spring, es posible acceder a los beans del application context utilizando @ en las plantillas.

    Así que podemos acceder al bean que representa el Environment, por ejemplo:

    ${@environment.getProperty("FIREBASE_API_KEY")}
    

    » Leer más, comentarios, etc...

    Blog Bitix

    Ejemplo de un potencial ataque informático de phishing, El caso de El Gatico Biever

    noviembre 11, 2021 06:00

    A estas alturas la mayoría de la gente seguramente ya haya recibido a través de un medio u otro algún intento de tipo de ataque informático, ya sea a través del correo electrónico, mensajes SMS con enlaces o a través de aplicaciones de mensajería instantánea. Los ataques informáticos cada vez van a ir a más y serán más peligrosos a medida que más operaciones se realicen a través de internet, surgirán medidas adicionales de seguridad para evitarlos como el segundo factor de autenticación pero también surgirán nuevas formas de ataque, donde el componente humano seguramente siga siendo la parte más débil del sistema de seguridad. Este artículo es el relato de la historia de un potencial ataque informático de phishing.

    Los ataques informáticos ya no se producen solo por descargar de una una fuente no confiable y ejecutar un programa en el ordenador, ni siquiera estos son los más peligrosos. Un virus informático requiere conocimientos avanzados de programación, tiempo para desarrollar un programa con la función maliciosa que no sea bloqueada por las medidas de seguridad del sistema operativo y distribuirla de alguna forma entre las potenciales víctimas para que se lo descarguen, los virus informáticos son una forma muy elaborada de realizar un ataque informático.

    Aparte de los virus hay otras formas de ataque informático mucho más sencillas de desarrollar y de distribuir. Una ataque de phishing simplemente requiere desarrollar una página en la que la víctima introduzca los datos que se deseen robar que van desde información personal hasta credenciales de inicio de sesión en la banca online, servicios como Gmail o PayPal o los datos de la tarjeta de crédito con los que robar el límite de saldo diariamente que la tarjeta permita hasta que el usuario o el banco la bloqueen.

    Una vez está desarrollada la página de phising el siguiente paso es hacer que las víctimas accedan a ella, tan simple como enviar un enlace por algún medio como un mensaje de correo electrónico, mensaje SMS o una aplicación de mensajería instantánea a través del móvil.

    Contenido del artículo

    El caso de El Gatico Biever

    En este artículo comento un potencial caso como ejemplo y una vez leído me puedes comentar si crees que este era un ataque informático. En el que denominaré El caso del Gatico Biever está basado en una conversación real que mantuve por correo electrónico a la que he cambiado el nombre real del contacto y comentado los hechos relevantes del contenido de los mensajes.

    Sin más, os dejo con la narración de El caso del Gatico Biever.

    El contacto

    Tengo un blog con ya casi una década de vida y más de 600 artículos publicados algunos posicionados en las primeras posiciones de las páginas de resultados por algunas combinaciones de palabras clave. El blog tiene casi 2.5K páginas vistas diariamente y unas 65K páginas mensuales.

    Por algún motivo que desconozco pero supongo por el buen posicionamiento de algunas páginas y la autoridad del dominio, me sorprende la buena cantidad de comerciales que me contactan solicitando publicar algún artículo a cambio de una pequeña compensación económica. Quizá no todas las semanas recibo una oferta para publicar un artículo pero si cada uno o dos meses, algunas llegan a buen fin otras simplemente se quedan en el conocimiento de las condiciones.

    El interés de estos comerciales al publicar el artículo es incluir algún enlace en los artículos hacia alguna página o servicio por motivos de SEO, a veces el interés es simplemente insertar un enlace en un artículo ya posicionado. Dar a conocer una página web o servicio desde cero o hacerlo crecer es difícil y requiere tiempo, para reducir este tiempo están dispuestos a pagar a sitios web existentes.

    Uno de estos meses recibí un correo electrónico como remitente el Gatico Biever utilizando una dirección de Gmail precisamente proponiendome una oferta de colaboración para el blog con la intención de publicar hasta seis artículos al mes durante varios meses. Una oferta extraordinaria fuera de lo normal que suele ser exclusivamente de un artículo. El correo electrónico estaba redactado en inglés pero haciendo referencia al dominio de mi blog en el asunto del mensaje y diciendo que era un lector asiduo de mi blog.

    El primer paso en estos contactos comerciales suele ser la negociación de las condiciones.

    La negociación y la propuesta

    Una oferta de seis artículos al mes y durante varios meses parece una oferta muy atractiva. Los primeros puntos a conocer es en qué consiste el acuerdo si en la inserción de enlaces, publicar un artículo ya redactado o que escriba yo un artículo original en función de lo cual se determina el precio ya que cada una me requiere menos o más tiempo.

    Una vez conocida en qué consiste la colaboración está en la aceptación de las condiciones como que la temática de los artículos esté relacionado la programación, tecnología o software libre así como vetar algunas temáticas de artículos como apuestas, juegos de azar y otras temáticas controvertidas. Otras condiciones es que en el caso de los artículos deben ser únicos para evitar penalizaciones por contenido de publicar y ser detectado como un sitio de contenido no deseado. Comprar artículos y enlaces es una actividad que en caso de que Google la detecte la penaliza ya que es una forma de alternar y algoritmo de posicionamiento de una forma no permitida por Google.

    Seis artículos patrocinados al mes son muchos artículos, casi más de los que escribo como contenido del blog. Para limitar el contenido patrocinado le propongo que solo acepto uno o dos artículos al mes.

    Otro asunto importante de la colaboración es llegar a un acuerdo en el tema económico, poner un precio por publicar el artículo. Yo suelo ser claro y aunque puedo dejar ver que oferta me hacen suelo ir directo al tema para acabar negociar este punto sin mucha demora. Casi siempre empiezo con mi propuesta de oferta económica.

    Hecha mi primera oferta económica al Gatito Biever este me responde con que esta le parece demasiado alta diciendo que su artículos son de calidad y la colaboración serán varios, no me indica en qué precio a él le parece bien el acuerdo económico sino que me deja en una pregunta abierta a que le haga otra oferta. Le hago una segunda oferta económica, que también rechaza y me propone su oferta económica que si fuera por un único artículo probablemente no aceptaría.

    Como la colaboración iba a ser de varios artículos acepto su oferta con la condición de que los dos primeros fueran a un precio intermedio entre lo que ambos proponíamos, en los siguientes artículos al precio de lo que él proponía.

    Las sospechas

    Acordados los términos de la colaboración y el precio comienza la colaboración que en este caso es simplemente que el Gatico Biever me proporcione el contenido del artículo, yo lo publique lo cual no suelo tardar más de uno o dos días y procedamos al pago en los términos acordados.

    Pasa casi una semana sin que sepa nada del Gatico Biever con lo que me pongo en contacto con él para ver qué hay del asunto. Me responde al cabo de unos días diciendo que está trabajando en ello y me pide que elimine la página el publicidad en la que detallo que mi blog ofrece la posibilidad de este tipo de colaboraciones, en el correo me incluye la dirección de la página que quiere que elimine con el texto el de la dirección de la página pero el enlace tiene una dirección de un dominio que desconozco, le hago un curl a esa URL y parece simplemente una redirección a la página de mi blog pero a través de un dominio extraño.

    El motivo para solicitar la eliminación de esta página es para evitar penalizaciones por SEO ya que este tipo de colaboraciones no es algo aceptado por Google y seguramente lo penalice en casos extremos. La página de publicidad la tengo desde hace mucho tiempo y no he notado estar penalizado por Google.

    Aquí es donde empiezo a sospechar ya que en sus correos utiliza el típico lenguaje de acción rápida como hazlo lo más pronto posible, respondeme hoy cuando él tarda en contestar varios días. Le insisto en que esa página de publicidad no es ningún problema y que me proporcione el contenido del artículo ya poniéndome un poco borde saludándose con un Hola Gatico y para finalizar su misma urgencia con un ASAP.

    Él tarda nuevamente en responder un par de días. Me pongo de nuevo en contacto con él siendo nuevamente borde con que su actitud no es nada profesional. Si alguien me contesta en los mismos términos en los que yo lo hago inmediatamente termino con la colaboración, pero él no, no cae en la provocación me dice que él es un experto en SEO y que eliminar esa página es un requisito indispensable para su cliente.

    Me doy cuenta que en realidad se poco de el Gatico Biever, me escribe en inglés y el dominio oculto del enlace de redirección parece de UK. Le pregunto que si es de UK y que tal van las cosas por UK con la situación que tienen del Brexit con un tono burlesco porque en un primer momento pienso que es alguien gastando una broma. Nuevamente si alguien se dirige a mi en los mismos términos que yo lo hago yo terminaría la colaboración. Pero él no, él responde con un «Sí, sí, lo has entendido bien» a lo de que él es de UK y que hablaremos más adelante cuando tenga un poco más de tiempo.

    Otro correo me responde con un «Seguro querido», un ¿querido?, me dice que nos centremos en los negocios y que su cliente «Indulgente» está esperando a que elimine la página de publicidad.

    Me doy cuenta de que en realidad se poco de el Gatico Biever, su «sí, sí» parece irónico y condescendiente y el «indulgente» parece muy… no se como definirlo ¿sacro? ¿de practicante, creyente, fiel religioso?, hacer colaboraciones profesionales con una cuenta que como nombre tiene Gatico Biever con una foto de catálogo que se encuentra y he encontrado fácilmente en una búsqueda por imágenes no parece profesional.

    Llega la trampa, mi pequeña trampa.

    La trampa

    No estoy dispuesto a eliminar esa página de publicidad y ya estoy sospechando de que este sea un ataque informático aunque aún no se qué forma tendrá el ataque.

    Me doy cuenta de que en realidad se poco del Gatico Biever, no es una cuenta profesional ni pone de que empresa de consultoría SEO pertenece, simplemente se identifica con un equipo SEO como organización en la despedida del mensaje.

    Preparo un enlace a una página que tiene un enlace similar a la página de publicidad pero algo modificada que si uno no se fija en detalle pasa desapercibido que las páginas son diferentes. Si la página de publicidad es /publicidad le preparo una página /publiciidad que simula un error de página no encontrada como desea el Gatico Biever que haga.

    Le envío en un nuevo correo electrónico el enlace de la página de publicidad trucado esperando que él haga clic en él. Esta es la misma técnica para realizar un ataque de phishing en vez de utilizando otro dominio añadiendo simplemente un caracter de una nueva URL parecida a la original, como el dominio y sus URLs lo controlo yo puedo hacerlo y lo hago.

    ¿Caerá en la trampa? Necesita hacer clic en el enlace que le he enviado yo, si entra directamente a la página para comprobar si he eliminado la página de publicidad no es de mucha utilidad.

    Pues Gatico Biever cae en la trampa hace clic en enlace directamente desde el correo electrónico y como se que ese enlace solo lo tiene él sé que ha sido él, ahora analizo los datos que me proporciona Google Analytics para conocer algo más de el Gatico Biever.

    La exploración

    Los datos de Analytics me permiten ver unos datos básicos anónimos pero algo más de quien es el Gatico Biever como su país de origen, que navegador utiliza y que sistema operativo utiliza. Veo que su país de origen es Pakistan, su sistema operativo es Windows 10 y el navegador web que utiliza es Google Chrome actualizado a la última versión.

    El país de origen me pone en alerta ya que es un país de oriente medio en una zona posiblemente en conflictos armados. Seguramente no tenga muchos visitantes de Pakistan asi que creo un segmento con los visitantes de este país y miro qué páginas ha visitado. No ha visitado muchas páginas pero veo que se ha parado alguna algo más de tiempo en la que hablaba de PayPal, la hemeroteca donde también hablaba de dinero y otra donde mencionaba la aplicación autenticador de Google. Otro dato que veo es que además de visitar la página preparada por mi ha visitado la página de publicidad original después de proporcionarle el enlace, asi que sé que sabe que en realidad no he eliminado la página de publicidad.

    El primer correo ya me debería haber hecho sospechar, por el mismo nombre del remitente, parecer una plantilla, decir que me visita regularmente alguien que habla en inglés. Ahora con estos datos tengo aún más sospechas. Aún no sé de qué forma será el ataque ni qué interés tiene esta yincana de eliminar la página de publicidad en todo ello, igual es un filtro para discriminar a usuarios fáciles de los difíciles o de adoctrinar a la víctima para que haga lo que se le dice.

    El Gatico Biever ignora que en realidad no he eliminado la página de publicidad y me envía el contenido del artículo. Analizó el contenido del artículo que está en buen español, no parece un artículo que esté obteniendo de internet ni esté ya publicado en otro sitio web. Me dice que lo publique cuanto antes porque tiene varios artículos más.

    Le digo que mientras lo publico me conteste de qué forma me va a pagar con una pregunta abierta. Me contesta que me paga con PayPal pero no cuál será el procedimiento, así que le insisto con cual es el procedimiento que suele utilizar para hacer el pago. Me responde con un «querido» y me dice con un tono imperativo en lo que yo haré que su procedimiento es que yo le proporcione mi dirección de PayPal en la que hacerme el pago y que me envía un enlace para que compruebe que me ha hecho el pago.

    Vale ahora tengo claro cual es su forma de ataque si es que es un ataque, un ataque de phishing sobre la página de PayPal. Pobre Gatico Biever que si este es su ataque no sabe que tengo activado el segundo factor de autenticación, no es infalible pero si no lo impide al menos limita el tiempo en el que es posible el ataque, concretamente tienen unos 30 segundos en caso de que sea víctima si su ataque de phishing soporta el segundo factor de autenticación que no creo.

    Le pido más información con la excusa de que por razones legales le tengo que emitir una factura para pagar impuestos, con lo que le pido cierta información como nombre y apellidos, dirección y nombre de la compañía.

    Parece que se ha cansado de esta pequeña yincana que le estoy haciendo y me propone sin yo haber publicado el artículo todavía hacerme el pago por adelantado con lo que me pide mi dirección de correo asociada a PayPal y nuevamente me repite que me proporcionará un enlace que podré usar para comprobar el pago.

    Aquí ya tengo la intención de dejarlo pasar, podría ir más lejos para que me envíe el enlace de la página de phishing, podría inventarme cualquier dirección de correo electrónico como por ejemplo felipin.demaritxalar.yvorvon[at]gmail.com a ver si es capaz de hacer el pago y enviarme el enlace para que lo compruebe que sospecho es de phishing. ¿O será ese nombre demasiado evidente que se de cuenta? Posiblemente para alguien de Pakistan no sea tan evidente. Si le doy una dirección de PayPal, supongo que me insistirá en que me ha hecho el pago y que lo compruebe.

    Como ve que ya no respondo me envía un nuevo correo al cabo de una semana con unos datos para atender a mi petición. Me dice que es de Reino Unido y me da como nombre real Ethan Biever. Busco por el nombre que me da y las primeras referencias son los nombres de dos personajes de un película.

    Llegar hasta el punto de que me de el enlace de phishing tampoco tiene ninguna utilidad, no soy policía, muy posiblemente ni ellos podrían hacer algo aunque fuese víctima del ataque y aunque le denuncie ante Google es seguro que será capaz de crearse una nueva dirección de correo electrónico con la que seguir haciendo ataques.

    El final, ¿tú que crees?

    Bueno, la mayoría sois lectores, otras personas equivalentes a mi serán youtubers, podcasters o streamers pero todavía quedamos algunos bloggers de la vieja escuela, en cualquier caso este es solo un ejemplo, podría llegar en realidad a cualquiera persona ni siquiera estar englobada en ningún colectivo y podría ser de otra forma con alguna excusa que un delincuente tenga su correo electrónico y una forma de contactarte por el ordenador o con teléfono inteligente.

    Los indicios que parecen indicar ser un ataque informático son el nombre de la cuenta, la forma de dirigirse a mí con un «querido», una oferta de colaboración muy atractiva respecto de lo que suele ser lo habitualmente, algunas respuestas que me da condescendientes, ignora mi mala educación y falta de respeto, ignora que no he hecho lo que me ha pedido de eliminar la página de publicidad, su país de origen, utilizar lenguaje imperativo, pedir inmediatez y se ofrece a hacerme el pago por adelantado sin yo haber publicado el artículo.

    El perfil de la persona que me hago del tipo de Gatico Biever es el siguiente. Aceptan tus insultos y faltas de respeto mientras te están esperando a que cometas un error, tus insultos los soportan hasta que cometes el error, disfrutan de tu desorientación como cuando le pregunto si es de UK y me responde con un «si, si». Es como si buscarán duelos o peleas, pero no son duelos cara a cara son duelos de engaño, en los que dan la imagen de ir todo bien, pierde es el que cae en la trampa. Se burlan a su modo, de forma velada con lo de «Indulgente», igual que yo con lo de «froilin» o su propio nombre sacado de una película.

    No se que criterio ha elegido para realizar un ataque, no sé si entenderá algo de español y habrá investigado algo sobre la víctima en este caso yo con lo que he publicado en en blog y mi cuenta de Twitter, posiblemente haya recopilado un conjunto de direcciones de correo electrónico públicas y enviado un mensaje a ver cuantos responden. Porque elegir como víctima de un ataque informático a un usuario que es informático y que usa GNU/Linux no parece la víctima ideal, es como intentar ir a robar la casa de un cerrajero. Qué lo puede intentar pero ambos sabemos mucho más de las técnicas que utilizan los delincuentes para cometer sus delitos y seguramente las medidas de seguridad que tenemos son mucho mejores. El cerrajero utilizando una puerta acorazada, una cerradura que evite las técnicas conocidas de apertura sin forzado, técnicas para detectar si una casa está habitada o un escudo en la cerradura que evite ciertas técnicas de forzado. Yo por mi parte como informático es posible que conozco y conozco el segundo factor de autenticación y tengo las nociones básicas de ataques informáticos.

    Parece un ataque de phishing ¿tu que crees? Porque claro no voy a seguir hasta el final para comprobarlo. Al menos le he hecho perder un poco de tiempo, he marcado sus correos como no deseados o spam y le he denunciado en Gmail como ataque de phishing que no sé si servirá de algo o será suficiente para que Google tome alguna acción.

    Fin.

    Cómo denunciar el intento o ataque informático

    Cómo comentaba en el artículo nociones básicas para detectar un ataque y evitarlo en caso de ser víctima de un ataque conviene denunciarlo. La unidad de delitos informáticos de los diferentes cuerpos de policía y un perito judicial informático seguro que os podría contar cientos de casos, pero seguramente el mejor consejo que den sea evitar ser víctima de un ataque informático. Ellos están para ayudar, proteger, minimizar daños, prevenir nuevos delitos, obtener pruebas y poner a disposición de la justicia a delincuentes pero muchas veces tras haber ocurrido los hechos el grave daño causado ya no es reparable. Y a veces les será muy difícil por estar los delincuentes en otros países. Muchos ataques informáticos como este ejemplo no son difíciles de detectar con las nociones básicas.

    En los términos y condiciones del correo electrónico de Gmail no permite utilizarlo para realizar actividades ilegales incluyendo el phishing y ofrecen herramientas para denunciarlo, desde el propio Gmail y desde páginas específicas. Para denunciar una cuenta de correo que esté siendo utilizada para realizar actividades ilegales es posible tomar dos medidas, una marcar el correo como spam que Gmail tiene en cuenta, si son varios usuarios lo que lo hacen los correos del remitente a los usuarios les llegará a la carpeta de spam en vez de a la bandeja de entrada. La segunda opción es denunciar un mensaje como suplantación de identidad, aunque en realidad el Gatico Biever no me ha enviado el enlace de phishing.

    En caso de recibir el enlace es posible además denunciar la página de phishing para que esta sea incluida en la lista negra de páginas identificadas maliciosas. Supongo una persona que trabaje para Google analizará estas peticiones y en caso de corroborarlo la página será añadida a la lista negra. Esta lista negra es utilizada por los navegadores para mostrar un mensaje de advertencia cuando un usuario intente entrar en ella, poniendo sobre aviso al usuario y aconsejando no entrar.

    Minimizar daños de posibles ataques informáticos

    Nadie está exento de ataques, ni alguien como yo que tiene conocimientos en informática y conozco las nociones básicas de los ataques, que inicialmente me resultó extraño el correo pero que hasta bastante avanzada la conversación con unos cuantos correos electrónicos enviados no empecé a realmente sospechar.

    Por ello conviene tomar una serie de medidas como establecer límites transferencias y tarjeta de crédito más bajos que los que establecen por defecto los bancos que suelen ser muy generosos, activar el segundo factor de autenticación para que aunque roben las credenciales de una cuenta evitar el ataque o permitirlo únicamente durante un breve periodo de tiempo si la página de phishing fuera tan avanzada como para estar preparada para obtener también el segundo factor de autenticación.

    En una de estas situaciones de ataque informático conviene que el atacante sepa lo menos posible de uno, por ello conviene proteger tu privacidad y minimizar la información tuya se puede encontrar con una búsqueda en internet.

    No hay otra opción de que quede impune, si es un delincuente y parece serlo por los varios indicios va a continuar haciendo su actividad y algún usuario más incauto sea su víctima, está claro que si realizan esta actividad es porque obtienen algún beneficio. La conclusión en cualquier caso es, se bueno pero ten un poco de joputismo para conocer a los malos, hay una buena cantidad de joputas malos por ahí.

    » Leer más, comentarios, etc...

    Blog Bitix

    Ejemplo de un potencial ataque de phishing, El caso de El Gatico Biever

    noviembre 11, 2021 06:00

    A estas alturas la mayoría de la gente seguramente ya haya recibido a través de un medio u otro algún intento de tipo de ataque informático, ya sea a través del correo electrónico, mensajes SMS con enlaces o a través de aplicaciones de mensajería instantánea. Los ataques informáticos cada vez van a ir a más y serán más peligrosos a medida que más operaciones se realicen a través de internet, surgirán medidas adicionales de seguridad para evitarlos como el segundo factor de autenticación pero también surgirán nuevas formas de ataque, donde el componente humano seguramente siga siendo la parte más débil del sistema de seguridad. Este artículo es el relato de la historia de un potencial ataque informático de phishing.

    Los ataques informáticos ya no se producen solo por descargar de una una fuente no confiable y ejecutar un programa en el ordenador, ni siquiera estos son los más peligrosos. Un virus informático requiere conocimientos avanzados de programación, tiempo para desarrollar un programa con la función maliciosa que no sea bloqueada por las medidas de seguridad del sistema operativo y distribuirla de alguna forma entre las potenciales víctimas para que se lo descarguen, los virus informáticos son una forma muy elaborada de realizar un ataque informático.

    Aparte de los virus hay otras formas de ataque informático mucho más sencillas de desarrollar y de distribuir. Una ataque de phishing simplemente requiere desarrollar una página en la que la víctima introduzca los datos que se deseen robar que van desde información personal hasta credenciales de inicio de sesión en la banca online, servicios como Gmail o PayPal o los datos de la tarjeta de crédito con los que robar el límite de saldo diariamente que la tarjeta permita hasta que el usuario o el banco la bloqueen.

    Una vez está desarrollada la página de phising el siguiente paso es hacer que las víctimas accedan a ella, tan simple como enviar un enlace por algún medio como un mensaje de correo electrónico, mensaje SMS o una aplicación de mensajería instantánea a través del móvil.

    Contenido del artículo

    El caso de El Gatico Biever

    En este artículo comento un potencial caso como ejemplo y una vez leído me puedes comentar si crees que este era un ataque informático. En el que denominaré El caso del Gatico Biever está basado en una conversación real que mantuve por correo electrónico a la que he cambiado el nombre real del contacto y comentado los hechos relevantes del contenido de los mensajes.

    Sin más, os dejo con la narración de El caso del Gatico Biever.

    El contacto

    Tengo un blog con ya casi una década de vida y más de 600 artículos publicados algunos posicionados en las primeras posiciones de las páginas de resultados por algunas combinaciones de palabras clave. El blog tiene casi 2.5K páginas vistas diariamente y unas 65K páginas mensuales.

    Por algún motivo que desconozco pero supongo por el buen posicionamiento de algunas páginas y la autoridad del dominio, me sorprende la buena cantidad de comerciales que me contactan solicitando publicar algún artículo a cambio de una pequeña compensación económica. Quizá no todas las semanas recibo una oferta para publicar un artículo pero si cada uno o dos meses, algunas llegan a buen fin otras simplemente se quedan en el conocimiento de las condiciones.

    El interés de estos comerciales al publicar el artículo es incluir algún enlace en los artículos hacia alguna página o servicio por motivos de SEO, a veces el interés es simplemente insertar un enlace en un artículo ya posicionado. Dar a conocer una página web o servicio desde cero o hacerlo crecer es difícil y requiere tiempo, para reducir este tiempo están dispuestos a pagar a sitios web existentes.

    Uno de estos meses recibí un correo electrónico como remitente el Gatico Biever utilizando una dirección de Gmail precisamente proponiendome una oferta de colaboración para el blog con la intención de publicar hasta seis artículos al mes durante varios meses. Una oferta extraordinaria fuera de lo normal que suele ser exclusivamente de un artículo. El correo electrónico estaba redactado en inglés pero haciendo referencia al dominio de mi blog en el asunto del mensaje y diciendo que era un lector asiduo de mi blog.

    El primer paso en estos contactos comerciales suele ser la negociación de las condiciones.

    La negociación y la propuesta

    Una oferta de seis artículos al mes y durante varios meses parece una oferta muy atractiva. Los primeros puntos a conocer es en qué consiste el acuerdo si en la inserción de enlaces, publicar un artículo ya redactado o que escriba yo un artículo original en función de lo cual se determina el precio ya que cada una me requiere menos o más tiempo.

    Una vez conocida en qué consiste la colaboración está en la aceptación de las condiciones como que la temática de los artículos esté relacionado la programación, tecnología o software libre así como vetar algunas temáticas de artículos como apuestas, juegos de azar y otras temáticas controvertidas. Otras condiciones es que en el caso de los artículos deben ser únicos para evitar penalizaciones por contenido de publicar y ser detectado como un sitio de contenido no deseado. Comprar artículos y enlaces es una actividad que en caso de que Google la detecte la penaliza ya que es una forma de alternar y algoritmo de posicionamiento de una forma no permitida por Google.

    Seis artículos patrocinados al mes son muchos artículos, casi más de los que escribo como contenido del blog. Para limitar el contenido patrocinado le propongo que solo acepto uno o dos artículos al mes.

    Otro asunto importante de la colaboración es llegar a un acuerdo en el tema económico, poner un precio por publicar el artículo. Yo suelo ser claro y aunque puedo dejar ver que oferta me hacen suelo ir directo al tema para acabar negociar este punto sin mucha demora. Casi siempre empiezo con mi propuesta de oferta económica.

    Hecha mi primera oferta económica al Gatito Biever este me responde con que esta le parece demasiado alta diciendo que su artículos son de calidad y la colaboración serán varios, no me indica en qué precio a él le parece bien el acuerdo económico sino que me deja en una pregunta abierta a que le haga otra oferta. Le hago una segunda oferta económica, que también rechaza y me propone su oferta económica que si fuera por un único artículo probablemente no aceptaría.

    Como la colaboración iba a ser de varios artículos acepto su oferta con la condición de que los dos primeros fueran a un precio intermedio entre lo que ambos proponíamos, en los siguientes artículos al precio de lo que él proponía.

    Las sospechas

    Acordados los términos de la colaboración y el precio comienza la colaboración que en este caso es simplemente que el Gatico Biever me proporcione el contenido del artículo, yo lo publique lo cual no suelo tardar más de uno o dos días y procedamos al pago en los términos acordados.

    Pasa casi una semana sin que sepa nada del Gatico Biever con lo que me pongo en contacto con él para ver qué hay del asunto. Me responde al cabo de unos días diciendo que está trabajando en ello y me pide que elimine la página el publicidad en la que detallo que mi blog ofrece la posibilidad de este tipo de colaboraciones, en el correo me incluye la dirección de la página que quiere que elimine con el texto el de la dirección de la página pero el enlace tiene una dirección de un dominio que desconozco, le hago un curl a esa URL y parece simplemente una redirección a la página de mi blog pero a través de un dominio extraño.

    El motivo para solicitar la eliminación de esta página es para evitar penalizaciones por SEO ya que este tipo de colaboraciones no es algo aceptado por Google y seguramente lo penalice en casos extremos. La página de publicidad la tengo desde hace mucho tiempo y no he notado estar penalizado por Google.

    Aquí es donde empiezo a sospechar ya que en sus correos utiliza el típico lenguaje de acción rápida como hazlo lo más pronto posible, respondeme hoy cuando él tarda en contestar varios días. Le insisto en que esa página de publicidad no es ningún problema y que me proporcione el contenido del artículo ya poniéndome un poco borde saludándose con un Hola Gatico y para finalizar su misma urgencia con un ASAP.

    Él tarda nuevamente en responder un par de días. Me pongo de nuevo en contacto con él siendo nuevamente borde con que su actitud no es nada profesional. Si alguien me contesta en los mismos términos en los que yo lo hago inmediatamente termino con la colaboración, pero él no, no cae en la provocación me dice que él es un experto en SEO y que eliminar esa página es un requisito indispensable para su cliente.

    Me doy cuenta que en realidad se poco de el Gatico Biever, me escribe en inglés y el dominio oculto del enlace de redirección parece de UK. Le pregunto que si es de UK y que tal van las cosas por UK con la situación que tienen del Brexit con un tono burlesco porque en un primer momento pienso que es alguien gastando una broma. Nuevamente si alguien se dirige a mi en los mismos términos que yo lo hago yo terminaría la colaboración. Pero él no, él responde con un «Sí, sí, lo has entendido bien» a lo de que él es de UK y que hablaremos más adelante cuando tenga un poco más de tiempo.

    Otro correo me responde con un «Seguro querido», un ¿querido?, me dice que nos centremos en los negocios y que su cliente «Indulgente» está esperando a que elimine la página de publicidad.

    Me doy cuenta de que en realidad se poco de el Gatico Biever, su «sí, sí» parece irónico y condescendiente y el «indulgente» parece muy… no se como definirlo ¿sacro? ¿de practicante, creyente, fiel religioso?, hacer colaboraciones profesionales con una cuenta que como nombre tiene Gatico Biever con una foto de catálogo que se encuentra y he encontrado fácilmente en una búsqueda por imágenes no parece profesional.

    Llega la trampa, mi pequeña trampa.

    La trampa

    No estoy dispuesto a eliminar esa página de publicidad y ya estoy sospechando de que este sea un ataque informático aunque aún no se qué forma tendrá el ataque.

    Me doy cuenta de que en realidad se poco del Gatico Biever, no es una cuenta profesional ni pone de que empresa de consultoría SEO pertenece, simplemente se identifica con un equipo SEO como organización en la despedida del mensaje.

    Preparo un enlace a una página que tiene un enlace similar a la página de publicidad pero algo modificada que si uno no se fija en detalle pasa desapercibido que las páginas son diferentes. Si la página de publicidad es /publicidad le preparo una página /publiciidad que simula un error de página no encontrada como desea el Gatico Biever que haga.

    Le envío en un nuevo correo electrónico el enlace de la página de publicidad trucado esperando que él haga clic en él. Esta es la misma técnica para realizar un ataque de phishing en vez de utilizando otro dominio añadiendo simplemente un caracter de una nueva URL parecida a la original, como el dominio y sus URLs lo controlo yo puedo hacerlo y lo hago.

    ¿Caerá en la trampa? Necesita hacer clic en el enlace que le he enviado yo, si entra directamente a la página para comprobar si he eliminado la página de publicidad no es de mucha utilidad.

    Pues Gatico Biever cae en la trampa hace clic en enlace directamente desde el correo electrónico y como se que ese enlace solo lo tiene él sé que ha sido él, ahora analizo los datos que me proporciona Google Analytics para conocer algo más de el Gatico Biever.

    La exploración

    Los datos de Analytics me permiten ver unos datos básicos anónimos pero algo más de quien es el Gatico Biever como su país de origen, que navegador utiliza y que sistema operativo utiliza. Veo que su país de origen es Pakistan, su sistema operativo es Windows 10 y el navegador web que utiliza es Google Chrome actualizado a la última versión.

    El país de origen me pone en alerta ya que es un país de oriente medio en una zona posiblemente en conflictos armados. Seguramente no tenga muchos visitantes de Pakistan asi que creo un segmento con los visitantes de este país y miro qué páginas ha visitado. No ha visitado muchas páginas pero veo que se ha parado alguna algo más de tiempo en la que hablaba de PayPal, la hemeroteca donde también hablaba de dinero y otra donde mencionaba la aplicación autenticador de Google. Otro dato que veo es que además de visitar la página preparada por mi ha visitado la página de publicidad original después de proporcionarle el enlace, asi que sé que sabe que en realidad no he eliminado la página de publicidad.

    El primer correo ya me debería haber hecho sospechar, por el mismo nombre del remitente, parecer una plantilla, decir que me visita regularmente alguien que habla en inglés. Ahora con estos datos tengo aún más sospechas. Aún no sé de qué forma será el ataque ni qué interés tiene esta yinkana de eliminar la página de publicidad en todo ello, igual es un filtro para discriminar a usuarios fáciles de los difíciles o de adoctrinar a la víctima para que haga lo que se le dice.

    El Gatico Biever ignora que en realidad no he eliminado la página de publicidad y me envía el contenido del artículo. Analizó el contenido del artículo que está en buen español, no parece un artículo que esté obteniendo de internet ni esté ya publicado en otro sitio web. Me dice que lo publique cuanto antes porque tiene varios artículos más.

    Le digo que mientras lo publico me conteste de qué forma me va a pagar con una pregunta abierta. Me contesta que me paga con PayPal pero no cuál será el procedimiento, así que le insisto con cual es el procedimiento que suele utilizar para hacer el pago. Me responde con un «querido» y me dice con un tono imperativo en lo que yo haré que su procedimiento es que yo le proporcione mi dirección de PayPal en la que hacerme el pago y que me envía un enlace para que compruebe que me ha hecho el pago.

    Vale ahora tengo claro cual es su forma de ataque si es que es un ataque, un ataque de phishing sobre la página de PayPal. Pobre Gatico Biever que si este es su ataque no sabe que tengo activado el segundo factor de autenticación, no es infalible pero si no lo impide al menos limita el tiempo en el que es posible el ataque, concretamente tienen unos 30 segundos en caso de que sea víctima si su ataque de phishing soporta el segundo factor de autenticación que no creo.

    Le pido más información con la excusa de que por razones legales le tengo que emitir una factura para pagar impuestos, con lo que le pido cierta información como nombre y apellidos, dirección y nombre de la compañía.

    Parece que se ha cansado de esta pequeña yinkana que le estoy haciendo y me propone sin yo haber publicado el artículo todavía hacerme el pago por adelantado con lo que me pide mi dirección de correo asociada a PayPal y nuevamente me repite que me proporcionará un enlace que podré usar para comprobar el pago.

    Aquí ya tengo la intención de dejarlo pasar, podría ir más lejos para que me envíe el enlace de la página de phishing, podría inventarme cualquier dirección de correo electrónico como por ejemplo felipin.demaritxalar.yvorvon[at]gmail.com a ver si es capaz de hacer el pago y enviarme el enlace para que lo compruebe que sospecho es de phishing. ¿O será ese nombre demasiado evidente que se de cuenta? Posiblemente para alguien de Pakistan no sea tan evidente. Si le doy una dirección de PayPal, supongo que me insistirá en que me ha hecho el pago y que lo compruebe.

    Como ve que ya no respondo me envía un nuevo correo al cabo de una semana con unos datos para atender a mi petición. Me dice que es de Reino Unido y me da como nombre real Ethan Biever. Busco por el nombre que me da y las primeras referencias son los nombres de dos personajes de un película.

    Llegar hasta el punto de que me de el enlace de phishing tampoco tiene ninguna utilidad, no soy policía, muy posiblemente ni ellos podrían hacer algo aunque fuese víctima del ataque y aunque le denuncie ante Google es seguro que será capaz de crearse una nueva dirección de correo electrónico con la que seguir haciendo ataques.

    El final, ¿tú que crees?

    Bueno, la mayoría sois lectores, otras personas equivalentes a mi serán youtubers, podcasters o streamers pero todavía quedamos algunos bloggers de la vieja escuela, en cualquier caso este es solo un ejemplo, podría llegar en realidad a cualquiera persona ni siquiera estar englobada en ningún colectivo y podría ser de otra forma con alguna excusa que un delincuente tenga su correo electrónico y una forma de contactarte por el ordenador o con teléfono inteligente.

    Los indicios que parecen indicar ser un ataque informático son el nombre de la cuenta, la forma de dirigirse a mí con un «querido», una oferta de colaboración muy atractiva respecto de lo que suele ser lo habitualmente, algunas respuestas que me da condescendientes, ignora mi mala educación y falta de respeto, ignora que no he hecho lo que me ha pedido de eliminar la página de publicidad, su país de origen, utilizar lenguaje imperativo, pedir inmediatez y se ofrece a hacerme el pago por adelantado sin yo haber publicado el artículo.

    El perfil de la persona que me hago del tipo de Gatico Biever es el siguiente. Aceptan tus insultos y faltas de respeto mientras te están esperando a que cometas un error, tus insultos los soportan hasta que cometes el error, disfrutan de tu desorientación como cuando le pregunto si es de UK y me responde con un «si, si». Es como si buscarán duelos o peleas, pero no son duelos cara a cara son duelos de engaño, en los que dan la imagen de ir todo bien, pierde es el que cae en la trampa. Se burlan a su modo, de forma velada con lo de «Indulgente», igual que yo con lo de «froilin» o su propio nombre sacado de una película.

    No se que criterio ha elegido para realizar un ataque, no sé si entenderá algo de español y habrá investigado algo sobre la víctima en este caso yo con lo que he publicado en en blog y mi cuenta de Twitter, posiblemente haya recopilado un conjunto de direcciones de correo electrónico públicas y enviado un mensaje a ver cuantos responden. Porque elegir como víctima de un ataque informático a un usuario que es informático y que usa GNU/Linux no parece la víctima ideal, es como intentar ir a robar la casa de un cerrajero. Qué lo puede intentar pero ambos sabemos mucho más de las técnicas que utilizan los delincuentes para cometer sus delitos y seguramente las medidas de seguridad que tenemos son mucho mejores. El cerrajero utilizando una puerta acorazada, una cerradura que evite las técnicas conocidas de apertura sin forzado, técnicas para detectar si una casa está habitada o un escudo en la cerradura que evite ciertas técnicas de forzado. Yo por mi parte como informático es posible que conozco y conozco el segundo factor de autenticación y tengo las nociones básicas de ataques informáticos.

    Parece un ataque de phishing ¿tu que crees? Porque claro no voy a seguir hasta el final para comprobarlo. Al menos le he hecho perder un poco de tiempo, he marcado sus correos como no deseados o spam y le he denunciado en Gmail como ataque de phishing que no sé si servirá de algo o será suficiente para que Google tome alguna acción.

    Fin.

    Cómo denunciar el intento o ataque informático

    Cómo comentaba en el artículo nociones básicas para detectar un ataque y evitarlo en caso de ser víctima de un ataque conviene denunciarlo. La unidad de delitos informáticos de los diferentes cuerpos de policía y un perito judicial informático seguro que os podría contar cientos de casos, pero seguramente el mejor consejo que den sea evitar ser víctima de un ataque informático. Ellos están para ayudar, proteger, minimizar daños, prevenir nuevos delitos, obtener pruebas y poner a disposición de la justicia a delincuentes pero muchas veces tras haber ocurrido los hechos el grave daño causado ya no es reparable. Y a veces les será muy difícil por estar los delincuentes en otros países. Muchos ataques informáticos como este ejemplo no son difíciles de detectar con las nociones básicas.

    En los términos y condiciones del correo electrónico de Gmail no permite utilizarlo para realizar actividades ilegales incluyendo el phishing y ofrecen herramientas para denunciarlo, desde el propio Gmail y desde páginas específicas. Para denunciar una cuenta de correo que esté siendo utilizada para realizar actividades ilegales es posible tomar dos medidas, una marcar el correo como spam que Gmail tiene en cuenta, si son varios usuarios lo que lo hacen los correos del remitente a los usuarios les llegará a la carpeta de spam en vez de a la bandeja de entrada. La segunda opción es denunciar un mensaje como suplantación de identidad, aunque en realidad el Gatico Biever no me ha enviado el enlace de phishing.

    En caso de recibir el enlace es posible además denunciar la página de phishing para que esta sea incluida en la lista negra de páginas identificadas maliciosas. Supongo una persona que trabaje para Google analizará estas peticiones y en caso de corroborarlo la página será añadida a la lista negra. Esta lista negra es utilizada por los navegadores para mostrar un mensaje de advertencia cuando un usuario intente entrar en ella, poniendo sobre aviso al usuario y aconsejando no entrar.

    Minimizar daños de posibles ataques informáticos

    Nadie está exento de ataques, ni alguien como yo que tiene conocimientos en informática y conozco las nociones básicas de los ataques, que inicialmente me resultó extraño el correo pero que hasta bastante avanzada la conversación con unos cuantos correos electrónicos enviados no empecé a realmente sospechar.

    Por ello conviene tomar una serie de medidas como establecer límites transferencias y tarjeta de crédito más bajos que los que establecen por defecto los bancos que suelen ser muy generosos, activar el segundo factor de autenticación para que aunque roben las credenciales de una cuenta evitar el ataque o permitirlo únicamente durante un breve periodo de tiempo si la página de phishing fuera tan avanzada como para estar preparada para obtener también el segundo factor de autenticación.

    No hay otra opción de que quede impune, si es un delincuente y parece serlo por los varios indicios va a continuar haciendo su actividad y algún usuario más incauto sea su víctima, está claro que si realizan esta actividad es porque obtienen algún beneficio. La conclusión en cualquier caso es, se bueno pero ten un poco de joputismo para conocer a los malos, hay una buena cantidad de joputas malos por ahí.

    » Leer más, comentarios, etc...

    Variable not found

    Enlaces interesantes 461

    noviembre 08, 2021 07:05

    Enlaces interesantes

    Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

    Por si te lo perdiste...

    .NET Core / .NET

    ASP.NET Core / ASP.NET / Blazor

    Azure / Cloud

    Conceptos / Patrones / Buenas prácticas

    Data

    Machine learning / IA / Bots

    Web / HTML / CSS / Javascript

    Visual Studio / Complementos / Herramientas

    Xamarin

    Otros

    Publicado en Variable not found.

    » Leer más, comentarios, etc...

    Blog Bitix

    Por qué proteger tu privacidad y qué información tuya se puede encontrar con una búsqueda en internet

    noviembre 04, 2021 06:00

    La privacidad de las personas es un derecho. Un derecho que con internet y el tratamiento de datos que hacen ya todos los negocios y servicios no es fácil proteger. O aceptas los términos y condiciones de los servicios en los que quieres crear una cuenta o no permiten crearla, algunos servicios permiten cambiar algunas opciones para no recibir comunicaciones comerciales por correo electrónico pero el tratamiento de datos está implícito en la aceptación de las condiciones.

    Un buscador como Google permite encontrar datos de una persona relacionada con ella incluso pasado algún lustro. A través de las redes sociales es posible conocer cualquier cosa que una persona comparta de forma pública.

    Por qué proteger tu privacidad

    Internet ofrece muchas posibilidades pero también tiene otros inconvenientes. Uno de ellos es que es muy fácil perder el control de la privacidad. Una vez algo se ha publicado a través de internet es difícil revocar la información y ejercer el derecho al olvido para que esa información que se desea eliminar lo sea. Una vez publicado algo en internet cualquier persona que tenga acceso lo puede copiar o republicar en cualquier otra ubicación en la que ya no se tiene el control. Lo que en un momento se considera como poco importante publicar más adelante puede desearse que no hubiese sido publicado, el problema es que publicar algo es muy fácil pero eliminar algo publicado es muy difícil.

    Las redes sociales como Facebook, Instagram o Twitter permiten relacionarse con personas en cualquier parte del mundo, conocidas y desconocidas. En estas redes sociales se publica gran cantidad de información personal que alguien interesado en conocerla le permite un acceso sencillo. Con algo tan simple como publicar el nombre y apellidos de una persona ya es posible encontrar mucha otra información utilizando un buscador como Google, cualquier página pública a la que Google tenga acceso la indexa en su buscador, y a partir de aquí a más información en las redes sociales que esté como pública.

    En los términos y condiciones que nadie lee al crear una cuenta en un servicio se detallan las autorizaciones que se otorga a la empresa por el hecho de usar su servicio, en esos términos con una jerga legal dificil de entender y larga para agotar en su lectura se incluyen apartados que suele detallar que el propietario del servicio procesa y compartirá los datos con terceras partes. A partir de compartir estos datos luego uno no sabe porque le llegan llamadas comerciales telefónicas cuando no se ha tenido relación ninguna con esa empresa de la que nos llama el comercial o mensajes SMS al teléfono móvil.

    Algunos ataques informáticos son realizados de forma masiva pero otros son llevados a cabo de forma individualizada más laboriosa pero menos, que alguien que está intentando perpetrar un ataque informático sepa cosas de la víctima le da mayor conocimiento para realizar un ataque de ingeniería social.

    Busca información tuya a través de datos que te identifican

    Es fácil averiguar cuánta información personal de uno mismo hay publicada en internet con una simple búsqueda en Google cualquier dato personal que identifique a una persona. A partir de uno de estos datos personales es posible encontrar mucha información de lo que hace una persona, que piensa a través de lo que dice, fotos suyas, de sus familiares y amigos, su ciudad y lugar de residencia, de vacaciones, lugar de trabajo y profesión, aficiones, …

    Los datos personales a través de los que averiguar la información que haya en internet de una persona son: nombre y un apellido, nombre y dos apellidos, DNI, número de teléfono móvil, dirección de correo electrónico o si utiliza su seudónimo. Si se sabe algo de esa persona como su ciudad de residencia permite descartar coincidencias en caso de obtener varias.

    Pon en Google tu nombre y apellidos, DNI, tu correo electrónico, tu número de móvil que son algunas cosas que te identifican y mira la información que encuentras de ti mismo. Cuando se dice que Google conoce más de ti que tú mismo es cierto en el aspecto de que muy posiblemente hay cosas que tu ya has olvidado pero Google es capaz de encontrar.

    Y Google también es capaz de reconocer texto en las imágenes. Busca también en Google Imágenes ahí también se encuentran fotos a partir de los datos identificativos.

    Conclusión

    Quizá te asustes de lo que puede conocer alguien de ti con interés por información que tú mismo has publicado. En el momento de publicar la información quizá no se le da importancia pero en el futuro en alguna circunstancia quizá se desease eliminar esa información cosa que erá muy difícil o quizá no sea posible.

    Cada uno es libre de hacer con su privacidad lo que mejor le parezca. Yo recomiendo protegerla porque es fácil perderla pero muy difícil recuperarla. La privacidad no involucra solo la de uno mismo sino también la de los demás, si tú no le das importancia a tu privacidad otras personas si se la damos por ello si publicas datos o fotos no publiques ninguna que incluya a ninguna persona de la que no tengas su consentimiento.

    La razón de utilizar un pseudónimo en internet es para utilizar un nombre que no sea el nombre y apellidos reales, esto permite separar en parte el alter ego de la persona real y desecharlo en caso de desearlo.

    Yo suelo decir…

    A mi me encanta LinkedIn, y eso que no tengo cuenta.

    -  picodotdev

    » Leer más, comentarios, etc...

    Header Files

    Introducción a Boost.Log

    noviembre 02, 2021 06:19

    Introducción

    Un sistema de log es de una gran utilidad a la hora de localizar errores en nuestras aplicaciones de una forma rápida. Esto es especialmente cierto en código en producción, en donde normalmente no tenemos acceso a las herramientas habituales de depuración, o donde ni siquiera tenemos acceso al sistema en cuestión sino que dependemos de que el usuario nos diga o mande cosas.

    El objetivo de un log es el de proporcionarnos información persistente sobre el estado del sistema en un punto dado, así como el flujo de ejecución que llevó hasta dicho punto. Adicionalmente, suele ser interesante poder contar con datos adicionales de diagnóstico como la configuración de la aplicación, características del ordenador, etc.

    Cada entrada (o mensaje) del log suele contar con una marca de tiempo (timestamp), lo que nos permitie asociar sucesos entre módulos, además de poder saber con más certeza cuáles mensajes pertenecen a una misma acción y cuáles a otras.

    Otro factor importante a tener en cuenta es que no todos los mensajes del log son siempre útiles: algunos nos dan información sobre configuraciones inválidas o errores del sistema, mientras que otros nos indicarán las llamadas a diferentes funciones. Estas segundas son útiles cuando se quiere encontrar un error, pero de normal suponen una sobrecarga innecesaria. Esto nos lleva a que es importante poder discriminar entre niveles de mensajes (normalmente llamada severidad del mensaje).

    Por otro lado, es interesante contar con un log limpio por ejecución, de forma que sea fácil poder seguir los pasos del usuario. Además, normalmente no son útiles los logs antiguos, por lo que nuestra aplicación debería ser capaz de deshacerse de ellos automáticamente. A todo esto se le llama rotación.

    ¿Más en la lista a los Reyes Magos? Inspeccionar un log largo no es divertido, por no decir que difícil, así que cualquier ayuda viene bien. Una forma es guardar el log en un formato que nos permita su estudio: por ejemplo un XML correctamente etiquetado, de forma que podemos filtrar los mensajes por tipo, rango de tiempo, módulo. Otro podría ser un HTML que visualmente nos separe mensajes de información de errores.

    Algo parecido podría decirse si queremos ver el log en tiempo real durante la ejecución del programa. Para ello se muestra el log por pantalla (consola, o una ventana separada). Esto permite activar una especie de modo depuración sin tener que recurrir a un debugger propiamente dicho (por no decir que a veces, como en aplicaciones concurrentes, abrir el depurador rompe el estado del sistema y no nos permite seguir correctamente la pista de un fallo).

    Soluciones básicas

    Obviamente no todo sistema de logging debe cumplir con todo los requisitos expuestos anteriormente, y un subconjunto puede perfectamente cubrir nuestras necesidades. Recuerdo uno que solía tener siempre a la mano un antiguo compañero de trabajo, y que podría resumirse en un pequeño fichero de cabecera tipo

    #ifndef LOG_H
    #define LOG_H
    
    #include <iostream>
    
    #ifndef NO_LOG
    # define LOG(msg) std::cerr << msg << std::endl;
    #else
    # define LOG(msg)
    #endif
    
    #endif
    

    Luego añadía variantes del LOG para diferentes niveles de severidad y estaba servido. No necesitaba más. Lo podía usar en desarrollo, y se podía sacar de cliente mandando una versión nueva del ejecutable y redirigiendo el error estándar a un fichero. No cumple con todo lo expuesto anteriormente pero sirve, es portable e incluso puede ser escrito sobre la marcha si se necesita. Si queréis ver la versión completa está disponible en el repositorio del miniLogger.

    Boost.Log

    Ahora bien, en este artículo quiero exponer una solución más completa. Usaré Boost.Log (boost::log), para no reinventar la rueda (bueno, al menos no toda la rueda). Como todos sabemos, Boost es uno de esos casi-inseparables de C++: mucho de lo que le falta a la biblioteca estándar se puede encontrar en Boost, hasta el punto que muchas de las nuevas adiciones a la biblioteca estándar toman como inspiración (o copia directa) a Boost.

    Como muchas cosas en Boost, Boost::log es enorme y complejo, por lo que limitaré este artículo a introducir aquellas funcionalidades que encajen con los requerimientos arriba mencionados.

    Namespaces

    Para simplificar el código y hablar el mismo lenguaje, renombraremos algunos espacios de nombre y tipos:

    namespace logging = boost::log;
    namespace expr = logging::expressions;
    namespace attrs = logging::attributes;
    namespace sinks = logging::sinks;
    namespace keywords = logging::keywords;
    
    using severity_t = logging::trivial::severity_level;
    

    Boost provee varias severidades por defecto bajo logging::trivial::severity_level: trace, debug, info, warning, error y fatal.

    Uso básico

    logging::sources::severity_logger<severity_t> log;
    
    BOOST_LOG_SEV(log, severity_t::info) << "Message to show";
    

    Normalmente se simplifica su uso mediante macros como

    #define LOG_INFO() BOOST_LOG_SEV(log, severity_t::info)
    #define LOG_DEBUG() BOOST_LOG_SEV(log, severity_t::debug)
    // ...
    
    LOG_INFO() << "Message to show";
    

    Log a consola

    Siendo la configuración más simple, comenzaremos por acá. Existen varias formas de configurar el log para mostrar los mensajes por pantalla, pero la más directa es mediante:

    logging::add_console_log(std::cout, logging::keywords::format = formatter);
    

    Donde formatter puede ser desde una simple cadena de formato tipo >> %Message%, a una función que lo haga. Optaremos por la segunda versión.

    Función de formateo

    Esta función recibe un registro del mensaje, con atributos como el mensaje, marca de tiempo, etc., y un stream al que escribir la entrada del log. Es en esta función donde podemos definir qué campos mostramos y cómo, formato del documento final (se usa el mismo tipo de función para consola que para fichero), coloreado, etc.

    Abajo se muestra un ejemplo para un formateo de mensaje a mostrar por consola, con el formato [severity] timestamp: message. Cada mensaje además se colorea de una forma distinta dependiendo de su severidad para facilitar la lectura del mismo.

    void formatter(logging::record_view const& rec, logging::formatting_ostream& strm)
    {
        strm << ">> ";
    
        // Severity
        static const auto s_severity_labels = std::vector<std::string>{
            "trace"s, "debug"s, "info"s, "warning"s, "error"s, "fatal"s,
        };
        static const auto s_severity_colours = std::vector<std::string>{
            "\033[37m"s, "\033[32m"s, "\033[36m"s, "\033[33m"s, "\033[31m"s, "\033[37;41m"s,
        };
    
        auto severity = rec[logging::trivial::severity];
        if (severity) {
            if (static_cast<std::size_t>(severity.get()) < s_severity_colours.size()) {
                // Colorize based on severity
                strm << s_severity_colours[severity.get()];
    
                // Show severity aligning messages
                strm << "[" << std::left << std::setw(7) << std::setfill(' ') << s_severity_labels[severity.get()] << "] ";
            }
        }
    
        // Timestamp and message
        strm << rec[attr_timestamp] << ": " << rec[expr::smessage];
    
        // Reset color
        if (severity) { strm << "\033[0m"; }
    }
    

    Para el estilo visual en consola se han usado códigos ANSI/VT100.

    Para el uso del timestamp es necesario definir el atributo en algún punto global:

    BOOST_LOG_ATTRIBUTE_KEYWORD(attr_timestamp, "TimeStamp", attrs::local_clock::value_type)
    

    Log a fichero

    La configuración para guardar el log a fichero es algo más larga y conlleva crear un objeto backend con información como nombre de los ficheros de log y datos de rotación, y adjuntarlo a un objeto sink junto al formato del mismo.

    auto backend = boost::make_shared<sinks::text_file_backend>(
        keywords::file_name = dir + "/" + prefix + "_%Y%m%d_%H%M%S.html", // filename
        keywords::rotation_size = max_file_size, // maximum file size
        keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0) // rotate every day
    );
    
    backend->set_file_collector(
        sinks::file::make_collector(keywords::target = dir, keywords::max_files = max_file_count));
    backend->scan_for_files(sinks::file::scan_all);
    
    // Setup log format (HTML in this case), and messages format
    // You could add your own stylesheet here for extended decoration
    backend->auto_flush(true);
    backend->set_open_handler(boost::lambda::_1 << "<html><h1>Log</h1><ul>\n");
    backend->set_close_handler(boost::lambda::_1 << "</ul></html>\n");
    
    sink = boost::make_shared<file_sink_t>(backend);
    
    sink->set_formatter(formatter);
    
    logging::core::get()->add_sink(sink);
    

    En el set_open_handler y set_close_handler es posible instalar los texto a añadir al log al principio de cada fichero y al final. En el ejemplo de arriba se usa un formato HTML, pero bien se podría describir cualquier otro formato.

    Yalog

    Este artículo se ha nutrido de la biblioteca de log yalog, la cual podéis ojear para encontrar más detalles de implementación y usar en vuestros proyectos (está publicada bajo licencia MIT).

    Otras soluciones

    El objetivo de esta entrada era mostrar cómo hacer un sistema de logging usando Boost. Existen otras soluciones muy buenas disponibles. Por ejemplo, una de las que más me gusta es spdlog, por su simplicidad y eficiencia. Como nota, usa cadenas de formato tipo fmt en lugar de flujos de datos (<<).

    Pueden encontrarse más en este listado de GitHub.

    Más opciones que se pueden implementar

    Este artículo no pretende cubrir al completo Boost.Log, sino ofrecer un primer acercamiento al mismo (aunque bastante completo). Como ideas futuras que se pueden agregar están:

    • Clasificación de los mensajes en módulos o espacios de nombre, de forma que se puedan habilitar bajo demanda.
    • Soporte para múltiples formatos de ficheros (XML, HTML, logs del sistema, etc.)

    » Leer más, comentarios, etc...

    Variable not found

    Enlaces interesantes 460

    noviembre 02, 2021 07:05

    Enlaces interesantes

    Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

    Por si te lo perdiste...

    .NET Core / .NET

    ASP.NET Core / ASP.NET / Blazor

    Azure / Cloud

    Conceptos / Patrones / Buenas prácticas

    Data

    Machine learning / IA / Bots

    Web / HTML / CSS / Javascript

    Visual Studio / Complementos / Herramientas

    Xamarin / MAUI

    Otros

    Publicado en Variable not found.

    » Leer más, comentarios, etc...

    info.xailer.com

    TinyMCE El más completo editor de textos HTML y ahora en aplicaciones de escritorio Xailer, ¿por que no?

    octubre 29, 2021 11:09

    Para los que seguimos creyendo firmemente que a las aplicaciones de escritorio les queda una larga vida, vemos que la Web está bien para depende que, pero no vemos aún a nuestros clientes realizando sus ventas de fruta conectadas a una báscula serie desde la web o realizando su facturación o su contabilidad desde la nube, bien sea por velocidad, inmediatez, sencillez o por costumbre simplemente.

    Pero a todos nosotros, desarrolladores de aplicaciones de escritorio, nos llama poderosamente la atención la riqueza gráfica de los componentes que hay para la Web, auténticas maravillas que por ejemplo permiten hacer graficas multi formato, coloridas y con movimiento.

    Y fue uno de estos componentes el que me impactó en cuanto lo vi funcionando dentro de la mayor parte de las Web hechas con WordPress y no es otro que un completo procesador de textos online llamado TinyMCE    https://www.tiny.cloud  tan completo que casi todas esas Web sustituyen el nativo de WordPress por éste. TinyMCE es multi idioma y totalmente parametrizable para tener el diseño a tu gusto.

    Internet está lleno de demos, ejemplos, videos de Youtube como éste, que muestran todo su increíble potencial, tanto que te hará olvidar a Word. Puedes manejar imágenes, recortarlas y girarlas, manejar tablas de datos con gran complejidad, etc. casi todo lo que se te ocurra y encima es un complemento gratuito, aunque también hay una versión comercial más completa, pero la básica es más que suficiente.

    Hace tiempo que empezamos a desarrollar aplicaciones WEB como complemento de nuestras aplicaciones de escritorio, de forma que los clientes puedan tener en su bolsillo ciertas utilidades, consultas o resultados de sus aplicaciones de escritorio y para ello empezamos a trabajar con Nefele 4 Harbour    https://www.nefele.dev   
    Esto nos abrió un universo de posibilidades en la Web y pudimos salir del escritorio, sin dejar de trabajar con el entorno Xailer y el lenguaje Harbour que conocemos y en el que nos sentimos tan cómodos, pero ahora para la Web.

    La experiencia recogida en estas aplicaciones Web y la aparición del increíble componente Edge WebView en Xailer 7 nos llevó a preguntarnos si era factible llevar la Web al escritorio y nos pusimos manos a la obra, por que no meter TinyMCE en nuestras aplicaciones a través del WebView integrado. Dicho y hecho, en pocas horas estaba andando.

    Ahora tenemos un procesador de texto que genera HTML con toda riqueza de detalles y que podemos grabar en un campo de una base de datos y leerlo desde este campo para mostrarlo de nuevo en pantalla, imprimirlo o casi lo que se quiera.

    Adiós al triste campo Memo y adiós al RTF que ya ha cumplido años y tocaba jubilar, bienvenido TiNyMCE.

    ¿Que hace falta para integrarlo en nuestras aplicaciones Xailer?

    1.- Creas un Form con un objeto WebView en su interior. Este ejemplo es nuestro redactor de correos electrónicos y el objeto Webview es el cuadro blanco inferior.

    2.- Sobre éste objeto contenedor instancio un componente TinyMCE

    WITH OBJECT ::oWebView
      With Object ::oTinyEditor := TTinyMCE( ):New( ::oWebView ) 
      End
    END

    Para ello debemos de contar con la CLASS TTinyMCE que hemos desarrollado y que se incluye en el proyecto Xailer que se adjunta y que puedes descargar desde el área de descargas de Xailer.

    Esta clase permite de una forma muy simple parametrizar el aspecto, el menú, los botones y el funcionamiento del editor de textos como puede verse en su definición:

    Property cLanguage         Init "esp"  //Opciones   esp, cat , eus, gal, mex
    Property lButtonBar        Init .T.
    Property lAllButtons       Init .T.    //Muestra una barra de botones con todas las opciones siguientes
    Property cFormatButtons    Init "bold italic underline |"
    Property cFormatExButtons  Init "formatselect  fontselect fontsizeselect | "
    Property lColorButtons     Init .F.   
    Property cColorButtons     Init "forecolor backcolor  |"
    Property lAdjustButtons    Init .F.   
    Property cAdjustButtons    Init "alignleft aligncenter alignright alignjustify |"
    Property lNotepadButtons   Init .F.
    Property cNotepadButtons   Init "cut copy paste|"
    Property lUndoButtons      Init .F.
    Property cUndoButtons      Init "undo redo|"
    Property lBulletButtons    Init .F.
    Property cBulletButtons    Init "bullist numlist outdent indent |"
    Property lInsertButtons    Init .F.
    Property cInsertButtons    Init "hr link insertfile | quickimage image | emoticons |"
    Property lTableButtons     Init .F.
    Property cTableButtons     Init "table |"
    Property lSearchButtons    Init .F.
    Property cSearchButtons    Init "searchreplace |"
    Property lPrintButtons     Init .F.
    Property cPrintButtons     Init "print export|"  //preview
    Property lConvertButtons   Init .F.
    Property cConvertButtons   Init "ConvertToWord |"
    Property cOwnerButtons     Init ""     //Para construir una barra especial del control, se mostrarán los controles que aquí se citen
    Property cDevelButtons     Init "|visualblocks code "  //Controles para el desarrollador permiten ver los bloques de texto del Html y editar el código fuente
    Property cFontSizes        Init "6pt 8pt 10pt 12pt 14pt 18pt 24pt 36pt 72pt"
    ACCESS   cSelectButtonbar  Inline ::cFormatButtons + ::cFormatExButtons + ::cColorButtons + ::cAdjustButtons
    Property lAutoSave         Init .F.    //Mensaje de guardar antes de salir
    Property lSpellChecker     Init  NIL   //Usar el corrector ortográfico de Edge
    Property lStatusBar        Init .T.    //Mostrar la barra de estadoY listo, ya sale andando y puedes escribir el texto que quieras o incluso editar WebPages que puedes copiar y pegar desde internet.

    3.- Pero como cualquier componente de Internet cada vez que lo invocamos irá a la Web a leer desde un CDN todo lo necesario para su funcionamiento, el código JavaScript, los iconos, etc. con lo cual necesitamos una conexión Internet y unos segundos de conexión. Pero esto puede evitarse si descargamos esta información y la metemos en una subcarpeta de nuestra propia aplicación, por ejemplo en el proyecto de ejemplo  .\Xtras\TinyMce  y de esta manera logramos independencia total de la Web y mayor velocidad de carga.

    Pegas de TinyMCE.

    La versión gratuita utiliza el corrector ortográfico del navegador del equipo y solo subraya los errores en el idioma en uso. Además el botón derecho no ofrece listas de correcciones, eso se reserva para la versión de pago.
    Otra pega es que el botón de pegar desde el portapapeles parece no funcionar en ningún sistema, pero te lo dice y te invita a pulsar Ctrl+V que si funciona.

    Y esto no es más que el principio de algo muy grande.

    Imagina poder tomar controles de esos que se te cae la baba al verlos por Internet y poder integrarlos en tus aplicaciones de escritorio de forma nativa y sin necesidad de conectarte siquiera a la web.

    Por ejemplo, este es un control de calendario https://fullcalendar.io.demos funcionando desde Xailer completamente en local contra una base de datos MariaDB.

    Pero esto ya será para otro capítulo……

    Descarga de ejemplo de uso

    » Leer más, comentarios, etc...

    Blog Bitix

    Medidas de seguridad a implementar para prevenir y minimizar daños en ataques informáticos

    octubre 28, 2021 05:00

    Los ataques informáticos dirigidos a los usuarios tienen el objetivo con una motivación económica del delincuente de robarles las credenciales de sus cuentas, datos de tarjetas de crédito y datos personales, otros ataques están dirigidos a los servicios que usan los usuarios. De los ataques dirigidos a los usuarios implementando las medidas de seguridad adecuadas en el servicio varios tipos de ataques son evitables como el phishing que es uno de los más comunes ofreciendo inicio de sesión con segundo factor de autenticación y con otras medidas los daños y riesgos son limitables. Otras medidas de seguridad implementadas en el servicio evita riesgos como usar salted pasword hashing. Como programadores los servicios deben hacer uso de buenas prácticas e implementar medidas adicionales para evitar riesgos y daños.

    Algunos ataques informáticos están dirigidos a las empresas y sus sistemas de computación explotando alguna vulnerabilidad de seguridad. Tener un fallo de seguridad ya de por sí es un grave problema para la imagen de la empresa también con consecuencias económicas de pérdida de clientes o valor en la bolsa sino también legales con posibles cuantiosas multas , además de otras consecuencias intangibles como la reputación entre sus clientes y usuarios.

    Otros ataques están dirigidos hacia los usuarios como el robo de datos personales, bancarios o credenciales con técnicas de suplantación de identidad o phishing. Aún hoy en día muchas personas apenas tienen unos conocimientos básicos de tecnología y la mayoría desconoce las medidas básicas de seguridad. Estas personas aún con una alfabetización digital muy básica están rodeadas de tecnología y realizan importantes tareas como compras y transacciones bancarias. Muchas personas son víctimas de fraudes y estafas por internet, a veces por su desconocimiento pero también a veces porque las empresas no implementan medidas de seguridad suficientes para que sus servicios sean más difícil de ser explotados.

    Los informáticos tenemos una gran responsabilidad para diseñar sistemas seguros aplicando las mejores prácticas de seguridad no solo como algo adicional a la finalización de una funcionalidad, sino involucrando al rol de security operations o SecOps desde el inicio, al igual que no se deben dejar las pruebas de aseguramiento de calidad para el final la seguridad tampoco debería. Los bancos utilizan medidas adicionales para realizar operaciones pero algunas medidas de seguridad dejan que desear en varios aspectos como requerir para todas las cuentas bancarias iniciar sesión en la banca online con el número del DNI y un código de seis dígitos, no implementar medidas de notificación de pagos, transferencias o falta un registro de actividad completo en la cuenta digital.

    Sin embargo, me da miedo que un banco que debería ser un referente en medidas de seguridad incluyan en la página donde los usuarios introducen sus credenciales para el acceso a la banca online recursos JavaScript de Facebook, Twitter y de dominios ajenos al banco que no controlan para hacer analítica web de seguimiento de usuarios.

    Contenido del artículo

    Inyección de SQL, XSS, tabnabbing y otras vulnerabilidades básicas

    Hay errores de seguridad comunes identificados hace ya tiempo que aún no están obsoletos, no son errores de seguridad complejos de explotar y tampoco son errores complejos de evitar usando las técnicas adecuadas de programación o evitando utilizar ciertas operaciones en la manipulación de datos. Varios de los errores de seguridad son por usar datos provenientes de fuentes no confiables sin aplicar el tratamiento adecuado. Aún siendo errores simples son peligrosos en una aplicación vulnerable.

    La fundación OWASP mantiene un registro detallado de los diferentes tipos de seguridad, explicando el problema de seguridad y cómo evitarlos. También publicar cada ciertos años una lista de los 10 errores más comunes durante ese año.

    Salted Password Hashing

    Una aplicación que guarda credenciales para autenticar a los usuarios habitualmente solicita dos datos, un identificador del usuario o de la cuenta y una contraseña que como solo conoce el legítimo usuario permite identificarle en el sistema al iniciar sesión. Los identificadores de los usuarios y las contraseñas la aplicación necesita guardarlas en una base de datos para que la aplicación las compare con las que proporciona un usuario al iniciar sesión.

    Guardar la contraseña en la base de datos el valor original que el usuario ha proporcionado es un peligro ya que cualquier persona con acceso a la base de datos es capaz de conocer el valor de la contraseña. Para no guardar el valor original es posible utilizar una función de hash de un solo sentido que permite transformar el valor original en otro derivador a partir del cual no es posible conocer el valor original pero permite conocer si es válido aplicando la función al dato proporcionado y comparándolo con el guardado en la base de datos. Sin embargo, usar una función hash no es suficiente ya que utilizando un ataque de diccionario con valores precalculados de hashes de valores comunes de contraseñas permite identificar cuentas con contraseñas débiles.

    La forma correcta de guardar contraseñas es utilizando cifrado o sin cifrado utilizando una versión modificada de hash denominada salted password hashing que evita ataques de diccionario.

    Implementación de segundo factor de autenticación

    Muchos usuarios no tienen conocimientos de informática, ni una alfabetización digital avanzada. Estos usuarios con unos conocimientos mínimos utilizan la tecnología por ser necesaria ya para muchas tareas o permitir realizarlas de forma más rápida y sencilla. Pero incluso usuarios con muchos conocimientos avanzados de tecnología también son vulnerables a ciertos tipos de ataques como los de phishing sin las precauciones adecuadas. Los ataques de suplantación de identidad o phishing son empleados por los delincuentes para robar información personal, credenciales de acceso a cualquier tipo de servicio y datos bancarios como tarjetas de crédito.

    Las aplicaciones que ofrecen el segundo factor de autenticación y los usuarios que lo emplean mantienen su cuenta a salvo incluso si son víctimas de un ataque de phishing. Con el segundo factor de autenticación además de la contraseña que es el algo que solo el usuario sabe se requiere algo que se tiene que sería un generador de códigos temporales. En un ataque de phishing los delincuentes se hacen con lo que se sabe, si esto es lo único que permite el acceso a una cuenta es suficiente para que los delincuentes accedan a ella. Con el segundo factor de autenticación la contraseña no es suficiente se requiere un código adicional, en caso de que un ataque de phishing robase el código temporal sólo permitiría iniciar sesión en la cuenta durante un breve periodo de tiempo habitualmente de 30 segundos.

    Los servicios más conocidos implementan el segundo factor de autenticación que los usuarios deben activar, no es difícil de implementar en Java.

    Notificación de acciones relevantes

    Algunas operaciones son relevantes desde el punto de vista de seguridad, como el inicio de sesión, un intento fallido de inicio de sesión, cambio de contraseña o realización de algunas operaciones en el ámbito de la aplicación. Para mejorar la seguridad conviene enviar en este tipo de acciones una notificación al usuario que permita advertir ante acciones que se puedan realizar sin su conocimiento. Las notificaciones permiten al usuario tomar medidas en caso de que detecte acciones fraudulentas. Las notificaciones pueden ser a través de un correo electrónico, mensaje SMS o a través de mensajería instantánea.

    Estos son dos ejemplos de correos electrónicos que envía Gmail y Wallapop para notificar al usuario de un nuevo inicio de sesión en su cuenta.

    Notificación de Gmail de inicio de sesión Notificación de Wallapop de inicio de sesión

    Correos electrónicos de notificación de inicio de sesión

    Registro de actividad

    Mantener un registro de la actividad es otra variante para dar visibilidad y permitirle al usuario identificar actividad fraudulenta en su cuenta en caso de que haya sido víctima de un ataque o sus credenciales hayan sido robadas. Algunos servicios mantienen un registro con las fechas de los últimos inicios de sesión, la dirección IP de la computadora junto con su geolocalización que permite conocer su ubicación aproximada, el navegador usado, sistema operativo o fecha de últimos cambios de contraseña.

    Además de proporcionar al usuario un registro de actividad al mismo tiempo este conviene guardarlo en los registros del propio servicio en caso de necesitar investigar actividad sospechosa.

    Registro de actividad en una cuenta de Gmail

    Registro de actividad en una cuenta de Gmail

    Establecer límites de uso

    Ya sea por una fallo de seguridad en un servicio vulnerable que ha sufrido un ataque o por un ataque dirigido al usuario por ejemplo con un ataque de phishing es posible implementar medidas no dirigidas a evitar los ataques sino a mitigar o reducir los posibles daños de un posible ataque.

    Para mitigar los posibles daños un servicio puede implementar medidas para limitar los datos como establecer un límite de intentos fallidos de inicio de sesión antes de bloquear la cuenta de forma temporal. Los bancos por ejemplo permiten activar o desactivar las tarjetas de crédito a petición del cliente que impidan la autorización de operaciones, con esta medida aunque un usuario haya sido atacado y un delincuente haya robado los datos de su tarjeta de crédito este puede desactivarla para evitar operaciones fraudulentas con ella unido a la notificación de acciones relevante un usuario puede actuar para evitar más daños. Otras medidas que utilizan los bancos son establecer límites de disposición de efectivo diario, importe máximo de transferencias, importe máximo en comercios físicos y electrónicos y de compras por internet.

    Cifrar información personal

    Los datos personales están protegidos por leyes, un fallo de seguridad con el resultado de robo de datos personales también tiene consecuencias legales para la empresa con importantes multas y económicas por pérdida de clientes y mala imagen.

    Los datos a proteger de los usuario son aquellos que permita identificarlos como nombre y apellidos, DNI, dirección de correo electrónico, dirección del domicilio, número de teléfono y por supuesto datos bancarios como número de cuenta y tarjetas de crédito.

    Para evitar el riesgo de un ataque dirigido al servicio que ocasione una fuga de datos es conveniente cifrarlos. Incluso para que los empleados que trabajan en la empresa no conozcan a quién corresponden esos datos.

    Cifrados los datos aun teniendo acceso a ellos la información está protegida ya que es necesario descifrarlos para obtener el valor original.

    Vault es una aplicación que ofrece el cifrado como servicio entre otras funcionalidades de seguridad.

    Informar a los usuarios

    Para prevenir fraudes otras medidas sencillas son informar a los usuarios de unas medidas básicas de prevención de fraude y explicar cómo son los procedimientos de comunicación.

    Algunos son desconfiar de mensajes inesperados, no acceder a enlaces de mensajes SMS, de mensajería instantánea y leer con atención la dirección en el navegador de los enlaces a los que se acceder.

    Nunca facilitar datos personales, credenciales de acceso a una cuenta no datos de tarjetas bancarias. Tampoco descargar ni instalar aplicaciones si no provienen de las tiendas oficiales del dispositivo. Y activar las notificaciones para conocer la actividad en la cuenta del servicio.

    Comunicaciones entre servicios

    La arquitectura de las aplicaciones tienden a diseñarse de forma que ofrezcan un medio de invocar sus funcionalidades mediante llamadas de red ya sea con el protocolo HTTP mediante REST, GraphQL o gRPC.

    Para autorizar las llamadas a los servicios estos han de implementar alguna forma de autenticación y autorización por ejemplo con OAuth y JWT.

    Otra forma de proteger los servicios más sencilla sin que cada uno de ellos tenga que implementar las funcionalidades de autenticación y autorización es utilizar un service mesh. Consul además de ser un servicio que ofrece registro y descubrimiento ofrece la funcionalidad de conexión entre servicios con cifrado, autenticación mutua y autorización especificando qué servicio está autorizado a comunicarse con cual.

    Con las funcionalidades de conexión de Consul los servicios no es necesario que implementen el cifrado, autenticación y autorización. Los servicios tienen menos responsabilidades, son más sencillos y la autorización de la comunicación es gestionada desde Consul.

    Contraseñas en repositorios de código fuente y artefactos compilados

    La seguridad de las aplicaciones se basa en contraseñas, claves privadas y certificados que únicamente las aplicaciones y los administradores de los servicios deben tener acceso.

    Las credenciales deben ser guardadas aparte del código fuente de la aplicación, fuera de la herramienta de control de versiones. Incluso las credenciales en una clase Java compila a bytecode es posible acceder a ellas.

    Estos secretos deben proporcionarse a las aplicaciones en tiempo de ejecución por el orquestador de procesos, el entorno de ejecución en la nube o de un servicio específico de seguridad del que obtenerlo. Para mayor seguridad las propiedades con secretos de los archivos de configuración en el sistema de archivos deben evitarse.

    Otras

    Otra medida de seguridad es ofrecer la posibilidad de eliminar una cuenta o desactivarla tras un periodo de inactividad prolongado.

    Referencia:

    » Leer más, comentarios, etc...

    Mascando Bits

    Cambiar de Branch en un Shallow Clone

    octubre 28, 2021 07:00

    Si estas usando sistemas de integración continua (Continuous Integration), trabajas con repositorios pesados o simplemente no quieres pasar por un un clonado de Git que te traiga todo el árbol de un repositorio, seguro que estás familiarizado con el concepto shallow clone o clonado superficial.

    Un shallow clone o cloando superficial permite traerse los últimos commits y no todo el histórico del repositorio Git. Aunque pueda parecer una solución maravillosa para desprenderse de los problemas de un clonado completo del histórico del árbol Git , presenta ciertos problemas a la hora de operarlo como un repositorio clonado de manera normal cuando se ha clonado bajo estas condiciones específicas de clonado.

    🐑 Crear un clonado superficial

    Para ejecutar un clonado superficial o shallow clone lo haremos con el siguiente comando:

    git clone -–depth [depth] [remote-url]
    

    Donde depth la profundidad es el número de commits que nos vamos a traer durante el clonado y remote-url es la dirección URL de origen de donde vamos a clonar el repositorio. 👀 El uso de --depth implica --single-branch.

    Para ejecutar clonado superficial o shallow clone de una rama o branch podemos hacerlo con:

    git clone [remote-url] -–branch [name] -–single-branch
    

    Donde name es el nombre de la rama o branch que queremos clonar.

    Si aún queremos hilar más fino y resulta que tenemos repositorios con submódulos (repositorios Git incluidos en otro repositorio), los cuales tienes su propio árbol Git y se inicializan usando alguno de los siguientes comandos:

    git clone -–recursive [remote-url]  # Git version >= 1.6.5
    git clone -–recurse-submodules -–jobs [num-jobs] [remote-url]   # Git version >= 2.13
    

    La primera sintaxis con recursive puede resultar más cómoda, aunque resulta más rápida y eficiente la segunda con recurse-submodules, la cual es la sintaxis vigente que permite especificar el número de submódulos operados concurrentemente mediante jobs.

    Si este es tu caso, no tiene sentido hacer un clonado superficial si se hace un clonado completo de los submódulo. Para ello ejecutaremos el siguiente comando:

    git clone -–depth [depth] -–shallow-submodules [remote-url]
    

    La opción --shallow-submodules implica que todos los submódulos se clonarán con una profundidad de 1.

    🐏 Convertir un repositorio con clonado superficial en uno de tipo clonado completo

    Si has seguido los pasos anteriores, te darás cuenta que si quieres cambiarte por ejemplo a otra rama no puedes. Eso es debido a que se ha omitido el resto del histórico según se lo hemos especificado. ¿Eso significa que no existe? No, eso sólo quiere decir que no lo conocemos.

    Si ejecutamos el siguiente comando sobre un repositorio clonado superficialmente, veremos los remotos que conocemos y los remotos existentes en el local:

    git branch -–all
    

    Si intentamos hacer un fetch del remoto veremos que tampoco conseguimos ver el histórico completo del responsorio:

    git fetch -–verbose
    

    Esto es debido a que nuestro remoto no está convenientemente configurados debido al clonado superficial. Podemos restaurar su funcionalidad completa partiendo de que nuestro remoto origin, de donde clonamos el repositorio, contiene la remote -url que metimos. Por ello podemos restaurar el acceso a todo el histórico del remoto para nuestro repositorio, usando el siguiente comando:

    git remote set-branches origin '*'
    

    Mediante la opción set-branches podemos cambiar la lista de ramas que son seguidas por el remoto conocido y por defecto que es origin.

    Ahora volvemos a ejecutar el comando fetch de nuevo y en este caso podremos apreciar que la totalidad de ramas aparecen:

    git fetch -–verbose
    

    Con esto ya tenemos acceso al historial completo del repositorio y podermeos cambiarnos a otra rama a la cual antes no podíamos:

    git checkout rama-que-estaba-buscando
    

    Si quieres comprobar el último commit de la rama local para cotejarlo con el último commit disponible el remoto y comprobar que está todo correcto, puedes hacerlo con:

    git show
    

    💡 Conclusiones

    El clonado superficial o shallow clone es una gran herramienta, pero puede echarnos el lazo al cuello si no sabemos y necesitamos deshacerlo. No obstante aunque siempre existe la opción de hacer un clonado clásico de nuevo, no resulta una opción elegante y eficiente que nos obliga a duplicar y volver a clonar el repositorio.

    » Leer más, comentarios, etc...

    Bitácora de Javier Gutiérrez Chamorro (Guti)

    ¿Era Watcom C el doble de rápido?

    octubre 26, 2021 03:00


    Cuando publiqué Watcom C++ y Sieve para DOS pareció que el rendimiento del compilador Watcom C/C++ aún siendo muy bueno, no llegaba a cumplir aquella promesa del pasado en la que se decía que Watcom C++ con aplicaciones de 32 bits generaba un código que era entre 2 y 5 veces más rápido que cualquier …

    ¿Era Watcom C el doble de rápido? Leer más »



    Artículo publicado originalmente en Bitácora de Javier Gutiérrez Chamorro (Guti)

    » Leer más, comentarios, etc...

    Bitácora de Javier Gutiérrez Chamorro (Guti)

    Hi-Tech Pacific C

    octubre 23, 2021 11:25


    Después de ¿Era Watcom C el doble de rápido que otros compiladores de C? hoy hablaré de Hi Tech Pacific C, un compilador que marcó una época. Sigo el desarrollo del proyecto FreeDOS desde sus inicios, momentos en los que apenas había oferta de compiladores para DOS que fueran gratuitos. El propio Jim Hall recomendaba …

    Hi-Tech Pacific C Leer más »



    Artículo publicado originalmente en Bitácora de Javier Gutiérrez Chamorro (Guti)

    » Leer más, comentarios, etc...

    Blog Bitix

    Manual básico sobre ataques informáticos, peligros, tipos, cómo detectarlos, cómo evitarlos y medidas de prevención

    octubre 21, 2021 06:00

    Las compañías realizan importantes esfuerzos para implementar medidas de seguridad pero aún con ellas si el usuario no toma las medidas oportunas muchas de las medidas de seguridad de una organización, computadora o de un dispositivo electrónico son inútiles. En vez de atacar la seguridad de los servicios o dispositivos los delincuentes pueden atacar una parte que suele ser más débil, el usuario. Para evitar ser víctima de un ataque informático conviene conocer unas pocas medidas preventivas que son sencillas para detectar la mayoría de potenciales ataques.

    La informática ha dejado de ser la de los ordenadores personales aislados para trabajos ofimáticos. La evolución de la tecnología informática por un lado llegando hasta los teléfonos inteligentes y la tecnología de internet permitiendo comunicaciones electrónicas a nivel mundial es una de las siguientes revoluciones a la revolución industrial en el siglo pasado. La informática hace tan solo unos pocos lustros era algo adoptado por personas interesadas en la tecnología, hoy quien no tiene un ordenador personal o portátil tiene un teléfono inteligente o smartphone. La tecnología se ha masificado y democratizado.

    Al mismo tiempo que la tecnología informática ofrece gran cantidad de beneficios para personas y empresas pueden ser utilizadas por personas sin escrúpulos para hacer el mal de forma intencionada y totalmente consciente de lo que hacen. A través de internet quizá los delincuentes no amenacen tu integridad física en la calle de las personas pero el daño psicológico o estafa económica tiene el potencial de ser igual de dañino.

    Contenido del artículo

    Cuales son los peligros de los ataques informáticos

    Los peligros y consecuencias de sufrir un ataque informático están a la misma altura de las tareas que hacemos de la informática, que ya son muchas y cada vez serán más.

    En el caso personal muchas cosas se puede hacer ya a través de internet, dos de ellas son especialmente sensibles. Una son las que involucran dinero como compras por internet con tarjeta de crédito o acceso a cuentas bancarias a través de la oficina digital que ya ofrecen y exigen todos los bancos para realizar transferencias y pagos. La segunda es aquellas que tienen que ver con datos personales dónde las redes sociales como Facebook, Twitter o LinkedIn recopilan y cualquier persona tiene acceso. En el ámbito profesional existen los mismos peligros con graves consecuencias para la empresa que sea víctima de un ataque.

    En un mundo capitalista en el que para la mayoría de las cosas se necesita dinero los ataques generalmente tienen un móvil económico en el que los delincuentes roban o estafan a las víctimas. El robo puede ser directamente a través de la tarjeta de crédito, de la cuenta bancaria o, de PayPal entre otros medios para transferir dinero entre cuentas y realizar pagos. Otra forma es indirecta, a través de la extorsión en el que el delincuente a través de una situación de poder exige a la víctima realizar acciones como la transferencia de dinero bajo la amenaza de por ejemplo publicar datos o información sensible robada exprimiendo a la víctima haciéndole creer que acatar sus exigencias la única posibilidad de recuperar datos importantes o cuentas de algún servicio, el desconocimiento o inocencia de la víctima es otra situación para perpetrar la estafa.

    Por un momento imagina que te roban las credenciales que dan acceso a un servicio importante como la del correo electrónico, las del banco, los datos de la tarjeta de crédito, los de la cuenta de Google con todos sus datos como correo electrónico, documentos, fotos y se ha configurado como medio de pago, de PayPal, de Amazon por poner solo unos ejemplos pero la lista seguramente sea mucho más larga. Las consecuencias son que te pueden joder la vida mucho y convertir de repente tu vida en una pesadilla por simplemente un pequeño error de unos minutos del que ni siquiera has sido consciente. Puedes perder los ahorros de varios años de trabajo y dejarte la cuenta del banco vacía con problemas adicionales asociados si no se pueden afrontar pagos de hipoteca o ese dinero era el medio de afrontar los gastos. No te van a hacer daño físico pero el daño económico puede ser extremadamente importante también con un daño psicológico que quizá esté a mayor o la misma altura.

    Este es un mensaje de audio de lo que parece una comercial o trabajadora en una sucursal de una entidad bancaria ante un número de ataques masivo no solo en la suya que muestra el grado de alarma y caos que es capaz de generar un ataque masivo con la capacidad de ser a nivel nacional.

    Audio con un mensaje de advertencia después de un ataque informático

    En el caso de sufrir un ataque informático los grupos dedicados a delitos informáticos de los diferentes cuerpos de policía harán todo lo posible para evitar más daños, reparar el causado que quizá no sea mucho y poner a disposición de la justicia a los delincuentes si pueden dependiendo del país el país en el que está el delincuente pero tampoco son todo poderosos y sus recursos materiales y de personal son limitados. La policía no da a basto con el número de casos que ya se dan, y los ataques parece que solo van a ir a mayor en número y gravedad. La policía únicamente se centrará en los más graves o en aquellos que se produzcan por bandas organizadas, por reiteración o por la posibilidad de acabar con ataques futuros. El mejor consejo que te va a dar la policía seguramente es la prevención, que evites ser víctima de un ataque informático. Con unas pautas sencillas la mayoría de ataques son detectables y evitables.

    Quizá los seguros del banco o vivienda previstos a tal efecto permitan recuperar a la víctima parte del dinero que le han estafado pero seguramente sea una pequeña parte del total y por supuesto el daño psicológico no es reparable vivido durante un periodo de incertidumbre que puede durar semanas y meses.

    Medios de ataque informático

    Antes de la llegada de internet el mayor peligro eran los virus informáticos que eran programas con funciones maliciosas que causaban pérdida de datos o bloqueos en el sistema que requerían un reinicio. Su medio de transmisión era a través discos extraíbles y estaban ocultos en programas con funciones legítimas, al ejecutar estos el virus se ejecutaba al mismo tiempo. Una vez ejecutado el virus este se replicaba en el ejecutable del resto de programas con lo que al llevar discos de una computadora a otra la infección se extendía.

    La mayoría de ataques son masivos aunque algunos aún costando más trabajo por parte del delincuente son individuales.

    En computadores, correo electrónico y documentos

    Hoy en día los virus informáticos siguen existiendo pero el medio por el que se transmiten ha cambiado de los discos extraíbles a programas descargados por internet o archivos adjuntos en correos electrónicos. Los virus no solo se ejecutan al ejecutar un programa infectado sino que los documentos de datos también pueden contenerlos como un documento de Word, hoja Excel o presentación de PowerPoint y documentos de otros programas. Además de realizar la función maliciosa una forma de transmitirse es enviando un correo electrónico a todos los contactos del usuario.

    Las acciones de un virus informático son diversas como secuestrar los documentos del usuario, posteriormente el delincuente solicita un pago si la víctima quiere recuperarlos. Otra acción es registrar todas las pulsaciones del teclado denominada keylogger que también es peligrosa ya que al mismo tiempo envía al delincuente el registro con potencialmente el usuario y contraseñas de cuentas importantes como las mencionas de bancos Google o Amazon, además los keyloggers pasan desapercibidos.

    En dispositivos móviles, correo electrónico, SMS, WhatsApp

    Los dispositivos móviles ya sean teléfonos móviles inteligentes o tabletas con conexión a internet mediante WIFI son dispositivos también vulnerables y medios que utiliza el usuario a través de los que realizar ataques. Además del correo electrónico los dispositivos móviles añaden otros vectores de ataque como las aplicaciones de mensajería instantánea como WhatsApp, Telegram o simplemente mensajes SMS. Lo único que se necesita para hacer llegar de forma directa un ataque a un usuario de forma muy precisa es su número de teléfono, un dato que no es especialmente difícil de conseguir. En los dispositivos móviles, además, detectar algunos ataques es un poco más complicado por la forma de interactuar.

    Ejemplo de ataque mediante suplantación de identidad o phishing

    Este es un ejemplo de mensaje SMS con una alarmante supuesta desactivación de la cuenta que solicita una verificación por motivos de seguridad. En realidad el enlace lleva a una página de phishing que trata de suplantar la identidad de la página de inicio de sesión de la banca online del banco Santander que en caso de que el usuario introduzca los datos de inicio de sesión será una víctima si este banco no implementa medidas adicionales de seguridad. Y aún implementando medidas adicionales que simplemente consisten en enviar un mensaje SMS al móvil asociado a la cuenta online, los delincuentes se las pueden saltar sin dificultad solicitando un duplicado de la SIM de la víctima y usando SIM swapping.

    Una combinación de phishing para obtener las credenciales de acceso a la banca online, conocido el número de la víctima junto con un SIM swapping y las medidas de seguridad de algunos bancos resultan insuficientes para evitar operaciones fraudulentas.

    El enlace del mensaje SMS usa un acortador de direcciones para ocultar la dirección destino a la que se dirige. Este tipo de ataques son más difíciles de detectar en los móviles por no poder examinar el destino del enlace y por la limitación de las pantallas que son más pequeñas y no permiten ver la dirección completa una vez cargadas en el navegador. Este tipo de ataques también son posibles en ordenadores con enlaces que llegan a través de correo electrónico.

    En este ejemplo la página que suplanta la identidad de la banca online del banco tiene un aspecto que perfectamente podría considerarse válido si no se compara con la página real. Utiliza los colores corporativos del banco, el logotipo oficial y un aspecto bastante similar al real. La diferencia para darse cuenta de ser una página de suplantación de identidad está en la dirección de la página que muestra el navegador en la barra de direcciones con un dominio que no se corresponde con el oficial del banco y por el detalle del marcador en la parte inferior del Powered by.

    Este es el caso de un ejemplo potencialmente de un ataque de phishing que he recibido.

    Mensaje SMS de alarma y urgencia con un enlace a una página de phishing Página web de phishing que suplanta la identidad del inicio de sesión en la banca online

    Ejemplo de los pasos en un ataque de phishing a través de un mensaje SMS

    Página real de inicio de sesión de la banca online

    Página real de inicio de sesión de la banca online

    Ataques personalizados

    Otros ataques comienzan con un mensajes basado en un texto genérico. Al responder al correo electrónico el receptor válida que la dirección de correo electrónico es correcta y en uso y el destinatario original muestra interés. Una vez iniciada la conversación el objetivo es algún tipo de solicitud aparentemente buena pero que al finalizar requiera un pago momento en el que se produce algún tipo de ataque informático. Los más perseverantes quizá involucre una transacción que haya ido perfectamente pero una vez ganada la confianza en las siguientes con algún tipo de excusa haber algún cambio en el proceso de forma de pago donde se produce el ataque.

    Páginas peligrosas

    Algunas páginas tratan de ofrecer algo muy demandado por muchos usuarios que suelen ser del tipo obtener algo gratis que cuesta dinero comprarlo. Dada la cantidad de usuarios que visitan esas páginas si contienen algún tipo de ataque informático seguro que algunos visitantes se conviertan en víctimas. Algunos tipos de cosas muy buscadas por los usuarios son piratear la licencia de Microsoft Windows y la suite ofimática de Microsoft Office, pirateo de programas profesionales como la herramienta de retoque fotográfico Adobe Photoshop, descarga de contenido digital como películas de estreno, series, libros electrónicos y música, pirateo de televisión de pago y por supuesto páginas pr0n.

    Muchas de estas páginas al acceder a ellas abren pestañas y ventanas emergentes aún con las medidas que implementan los navegadores para evitarlo, las ventanas emergentes son muy molestas y suelen contener algún tipo de publicidad de baja calidad. El abrir ventanas emergentes es el tipo de entorno en el que emplear un ataque de tabnabbing.

    Tipos y formas de ataque informático

    La mayoría de ataques comienzan de la misma forma en cualquiera de sus variantes, con una oferta tentadora por muy inverosimil que parezca para que el usuario no se resista a responder.

    Secuestro de datos

    En los ataques informáticos que consisten en el secuestro de datos los delincuentes extorsionan a la víctima posteriormente si quiere recuperarlos exigiendo un pago. Aunque el ataque está dirigido contra los datos de la víctima el móvil suele ser uno económico. Aceptar el chantaje no es la opción recomendada ya que no hay garantía de recuperar los datos, el delincuente podría seguir chantajeando más a la víctima con un monto total de dinero estafado importante sin garantías. Una vez de haber sufrido el ataque informático contra los datos la mejor opción para no caer en la extorsión es recuperar los datos de una copia de seguridad. Tener una copia de seguridad de los datos es una forma de prevención para estos casos y otros de pérdida de datos.

    Robo de credenciales y datos bancarios

    Otros ataques informáticos están dirigidos a robar las credenciales o los datos de su tarjeta de crédito de una cuenta importante del usuario. El robo de las credenciales de una cuenta o datos de la tarjeta de crédito ocurre sin ni siquiera ser la víctima consciente del robo. El delincuente hace llegar a la víctima a través de cualquier medio y dispositivo un enlace que lleva a una página aparentemente igual que la legítima pero que en realidad es una página maliciosa que simula ser una legítima, en algún punto a la víctima se le presenta el formulario que solicita las credenciales de la cuenta o los datos de la tarjeta bancaria. La víctima los introduce y la página controlada por el delincuente ahora en posesión de los datos puede ir a la página legítima y realizar las mismas acciones que pudiera hacer el usuario.

    Este tipo de ataques de suplantación de identidad son denominados de phishing. Son muy peligrosos por dos motivos, porque son muy simples de realidad y porque se pueden hacer de forma masiva a muchos usuarios. Seguramente muchos usuarios potenciales víctimas no caigan en la trampa pero por probabilidad y estadística con que unos pocos se conviertan en víctimas compensa a los delincuentes.

    Si son los datos de la tarjeta de crédito es posible realizar compras y pagos en cualquier página que la acepte hasta el límite que permita. Si se trata de las credenciales de una cuenta bancaria y el banco no tiene medidas adicionales de seguridad es posible realizar transferencias bancarias.

    Para cuando la víctima se da cuenta puede ser demasiado tarde de que está siendo o ha sido estafado de una cantidad importante de dinero con un límite de los fondos de la cuenta bancaria que respalde las transferencias o los pagos de la tarjeta de crédito. Esto es, la víctima puede llegar a perder la totalidad de los fondos de su cuenta bancaria en un plazo de varios días.

    Estafa o timo nigeriano

    La estafa o timo nigeriano o la estafa nigeriana es su encarnación en internet al timo de la estampita que se daba en las calles. El timo del nigeriano y el timo de la estampita al igual que otros timos por internet basan su efectividad en la avaricia de la víctima.

    En el caso del timo del nigeriano suele darse a través de mensajes de correo electrónico. Hay muchas versiones en el contenido del mensajes pero todas se basan en el contar una historia en el que una persona muy rica a punto de fallecer con mucho dinero desea donar su fortuna de varios millones al receptor del mensaje por muy raro que parezca ya que que en realidad se conocen de nada. Si el receptor del mensaje se cree por avaricia e inocencia algo tan bueno pero que no es verdad entrando en el juego se convertirá en víctima.

    Iniciada la conversación el delincuente pide un pequeño pago para desbloquear los fondos del supuesto rico para que la víctima pueda recibirlos. Por supuesto, el delincuente no realizará ninguna transferencia y con alguna excusa seguirá pidiendo más pagos a la víctima. El resultado es que la víctima dependiendo de lo que tarde en darse cuenta de que está siendo objeto de una estafa pierde más o menos dinero en las transferencias que haya hecho. Otra forma de estafa es que el delincuente pida los datos bancarios o de tarjeta de crédito, información que nunca bajo ningún concepto hay que proporcionar a nadie por internet ni siquiera a alguien que diga ser un empleado de nuestro banco.

    Cómo detectar potenciales ataques con consejos simples

    Aunque algunos de los ataque son muy burdos, por su capacidad de causar daños muy graves conviene estar prevenidos y alerta. Por suerte, muchos de los potenciales intentos de ataque informático son muy sencillos de detectar con unas pocas y sencillas pautas.

    Los servicios de correo electrónicos en la nube como Gmail son capaces de detectar la mayoría de correos electrónicos con potenciales ataques y de spam, sin embargo, como crear una cuenta de correo electrónico es gratuita los delincuentes y personas dedicadas a enviar correos electrónicos no deseados o spammers les resulta fácil continuar con su actividad en caso de que su cuenta sea cerrada por actividad ilegal según los términos de Google o el servicio que utilicen. Aún con la tasa de acierto de Google de detectar spam y correos fraudulentos con ataques el sistema no es perfecto y algunos llegan a la bandeja de entrada como cualquier otro correo válido. Con caer en un único ataque es suficiente con tener una buena cantidad de problemas y daños.

    Una forma muy utilizada es a través de correos electrónicos por su sencillez y posibilidad de hacerlo masivo. Como muchos ataques tienen origen en otros países el lenguaje en los correos electrónicos recibidos está en inglés. En el caso de los hispano hablantes recibir un correo electrónico en inglés ya es un potencial indicio de potencial ataque que junto con otros factores es reconocible.

    Por el mismo motivo que los ataques tienen un origen extranjero aún cuando los correos electrónicos llegan en español es porque los delincuentes realizan una traducción desde su idioma nativo, normalmente con alguna herramienta automatizada o la hacen ellos mismos. El texto en español aunque entendible suele tener fallos ortográficos, de sintaxis o utilizar expresiones que no se suelen utilizar. Los correos que tienen este tipo de errores también son potenciales correos de ataques.

    Un dato importante es saber cual es la cuenta origen que envía el correo electrónico, si es una desconocida ya es sospechoso más cuando al mismo tiempo se trata de un correo inesperado. Conviene fijarse bien tanto en el nombre del usuario como en el dominio del correo electrónico ya que algunos cambian una letra para parecer el mismo que uno legítimo siendo totalmente uno diferente. Por ejemplo, si el correo legítimo es gestor@bancosantander.es uno fraudulento podría ser gestor@bancosantander.ink, conviene conocer cuál es el dominio legítimo del emisor para identificar este tipo de avisos, este ejemplo es muy claro pero hay otros más difíciles de identificar.

    Enviar correos de forma masiva una gran cantidad de usuarios requiere utiliza el mismo texto para todos, esto hace que los correos electrónicos no estén personalizados y su salida sea un simple «Hola» ni el texto del mensaje incluya ningún detalle relacionado con el usuario. En estos correos el texto es creado a partir de una plantilla genérica.

    Para tratar de incitar a la potencial víctima a realizar la acción que los delincuentes desean, tanto el asunto del mensaje como el texto del mismo suelen usar un lenguaje que provoque urgencia, requerir una acción inmediata, tiene un contenido emocional y se autodefinen como correos importantes. El motivo de este lenguaje es evitar que el usuario reaccione de forma inmediata sin pensar, para evitar la detección del fraude. Los mensajes que utilizan este lenguaje de urgencia e inmediatez suelen ser otra forma de detectar correos electrónicos potencialmente con ataques informáticos.

    Otros correos de ataques aunque en menor cantidad están más elaborados y son más difíciles de detectar. Los más avanzados no son tan burdos y pueden utilizar un correo electrónico bien diseñado con el logotipo original de la compañía y sin faltas de ortografía en un perfecto español. En estos casos la forma de detectarlos es por el origen de la dirección de correo electrónico comentada anteriormente y por incluir enlaces que llevan a páginas que no son las legítimas. Al igual que en el caso de la dirección de correo electrónico, un correo fraudulento puede incluir un enlace con una dirección parecida a la legítima pero algo diferente. Por ejemplo, si la dirección legítima y correcta es https://particulares.bancosantander.es/login/ la fraudulenta podría ser https://particulares.bancosantander.ink/login/, si no se presta atención a ese ink en la barra de direcciones del navegador pasa perfectamente desapercibido. Por ello, siempre conviene fijarse en la barra de direcciones del navegador. Hay que tener en cuenta que aunque el texto que el usuario ve de un enlace sea https://particulares.bancosantander.es/login/ la dirección del mismo ser la página fraudulenta https://particulares.bancosantander.ink/login/.

    Los navegadores al pasar con el ratón por encima del texto de un enlace suelen mostrar la dirección del mismo, esto permite saber cual es su dirección real sin tener que pulsarlo. Los navegadores de los dispositivos móviles no ofrecen esta funcionalidad por no utilizarse un ratón y este tipo de trucos son más difíciles de detectar.

    Especialmente hay que tener en cuenta los correos electrónicos con comunicaciones de los bancos. Otros asuntos muy utilizados son la de mensajes con paquetes que no hemos pedido pero que solicitan un pago para recogerlo tan bajo muchos usuarios pican en la trampa. O correos relacionados con algún organismos estatal SEPE, la seguridad social o servicio de salud.

    Como norma básica nunca se deben enviar o proporcionar las credenciales de ningún servicio o datos de tarjeta bancaria a alguien que los solicite ni introducir en ninguna otra página. Los delincuentes se aprovechan de que por naturaleza muchas personas son muy confiadas. Ningún empleado de ningún banco va a pedir nunca las credenciales de inicio de sesión en la banca electrónica o tarjeta de crédito de un cliente ni por correo electrónico ni por teléfono. Conviene conocer estos casos que nunca se pueden dar y en caso de que una comunicación o alguien lo intente saber de forma inmediata que es un muy potencial ataque informático.

    Este es el manual de Google conocer que es el phishing y que datos se suelen robar demás para evitar y denunciar los correos electrónicos de phishing con varios de los consejos comentados en este artículo y con algunos detalles más, por ejemplo, como denunciar una cuenta de Gmail que esté siendo utilizada para realizar ataques de phishing. La versión en inglés de la misma página es más detallada, Avoid and report phishing emails.

    Medidas preventivas para evitar problemas de seguridad

    Aún conociendo los indicios de potenciales correos electrónicos o direcciones de páginas nadie está a salvo de los ataques por las múltiples formas en las que estos se presentan. En este artículo se comentan los más básicos y habituales pero hay algunos más elaborados en los que incluso alguien experto puede ser víctima perfectamente. Para evitar riesgos conviene tomar unas medidas de prevención básicas.

    Hay que estar siempre alerta y sospechar cuando algunas cosas no encajan o parezcan demasiado buenas de personas desconocidas o con pseudónimos. Ante un correo electrónico o mensaje considerado como un ataque informático lo mejor es ignorarlo, no interactuar con él, ni siquiera abrirlo, ni descargar sus adjuntos si los tiene. En caso de ser un mensaje sospechoso pero no estar seguros lo mejor es estar alerta analizando la dirección del origen, enlaces que contiene y cuidado con los adjuntos.

    En el caso de una computadora nunca hay que ejecutar programas obtenidos de adjuntos de un correo electrónico ni obtenidos en internet que no sean de fuentes fiables. Abrir documentos también es peligroso, por ejemplo esos típicos correos con una presentación de Power Point con algo gracioso o emocional que se difunden en cadenas con los contactos son candidatos a tener funciones maliciosas que exploten alguna vulnerabilidad del programa que los abre.

    Utilizar un programa gestor de contraseñas

    Cada servicio ha de tener sus propias credenciales y contraseña de inicio de sesión, esto hace que en caso de que las credenciales de un servicio sean robadas no afecte ni sirvan para otros servicios. Aunque uno no haya tenido el ataque de forma directa los puede sufrir a consecuencia del ataque que haya sufrido un servicio, los propios servicios también reciben ataques informáticos y robo de credenciales, en caso de que las mismas credenciales de un servicio se utilicen en otros todos de esos otros también están en peligro.

    Ya, pero si tengo que tener unas credenciales y contraseña para cada servicio… ¿cómo recuerdo las contraseñas de todos?. Sencillo, utilizando un programa gestor de contraseñas KeePassXC o similar. Los programas gestores de contraseñas son bases de datos de credenciales que las guardan cifradas, la base de datos está protegida con una contraseña maestra con lo que solo es necesario recordar una contraseña. Los programas gestores de contraseñas tienen otras funciones útiles como generador de contraseñas fuertes, soporte como generador de segundo factor de autenticación y mantener cifradas las contraseñas en la base de datos con lo que aunque el archivo de base de datos fuera robado las contraseñas seguirán estando seguras.

    Configurar el segundo factor de autenticación para iniciar sesión

    Los servicios de grandes compañías e importantes ofrecen configurar segundo factor de autenticación como medida adicional a las credenciales de usuario y contraseña. El segundo factor de autenticación además de la contraseña requiere un código temporal generado con un dispositivo que tiene el usuario como un smartphone, aunque la contraseña haya sido robada el código temporal mantiene protegida la cuenta. Conviene activar el segundo factor de autenticación en aquellos servicios importantes que lo ofrezcan como Google, Amazon y PayPal. El programa KeePassXC ofrece soporte para actuar como generador de códigos temporales del segundo factor de autenticación.

    Utilizar tarjetas de crédito virtuales

    Seguramente todos los bancos ofrezcan la posibilidad de crear tarjetas de crédito virtuales. En vez de introducir los datos de la tarjeta física, una tarjeta virtual es una tarjeta que actua como una tarjeta real pero que existe físicamente y se crea bajo lo demanda del usuario en unos pocos segundos, permiten realizar el pago de una compra en internet con mayor seguridad que las tarjetas físicas. Al crear la tarjeta virtual los datos asociados a la misma son los mismos de una tarjeta física real como los 16 dígitos del número de tarjeta, fecha de caducidad y código de seguridad.

    Adicionalmente al crear la tarjeta virtual es posible especificar el importe máximo permitido a cargar en la tarjeta que será un poco superior al importe de la compra en la que se pretenda usar. También es posible especificar los meses deseados de su caducidad pudiendo elegir entre ser de tan solo tres meses o un año.

    Al no usar los datos de la tarjeta real, establecer un límite máximo en el importe que se puede cargar en la tarjeta virtual y establecer una fecha de caducidad menor aumenta la seguridad en una compra por internet.

    Hacer copias de seguridad

    No solo por los ataques de seguridad sino por corrupción de datos y fallos de hardware es necesario hacer copias de seguridad de forma periódica. Los datos son más importantes que el propio hardware donde se almacena, el hardware es reemplazable en caso de fallo pero los datos no son reemplazables en caso de pérdida por cualquier motivo. El programa FreeFileSync permite hacer copias de seguridad de forma sencilla.

    Comprobar registros de actividad

    Algunos servicios mantienen un registro de la actividad de la cuenta, como dirección IP de los dispositivos con sesión iniciada, ubicación estimada, navegador, fecha y hora, envían correos electrónicos para notificar la realización de acciones críticas como inicio de sesión en dispositivos nuevos, cambio de contraseña o realización de pagos.

    Ante dudas de actividad sospechosa se puede consultar estos registros, y comprobar que las notificaciones del servicio legítimo solo llegan como consecuencia de una acción que realiza el usuario y no por actividad de un delincuente. Si hay sospechas fundadas o se detecta actividad fraudulenta hay que cambiar la contraseña si aún es posible.

    Que hacer en caso de sufrir un ataque informático

    En caso de un ataque informático según su gravedad algunas de las acciones a realizar son recopilar todos los datos posibles del ataque incluyendo los datos que se tenga del delincuente y como se ha producido el ataque, denunciar ante la policía, avisar al banco para que bloqueen la cuenta o tarjeta de crédito para impedir más daños y cambiar de contraseñas de los servicios afectados si aún se puede. En caso de extorsión atender las exigencias de los delincuentes posiblemente no sea una buena idea, en estos casos la opción es denunciar ante la policía.

    Conclusión, tómatelo muy en serio

    Mantened los dispositivos y programas actualizados y seguros instalados únicamente de fuentes fiables. Conoced las mínimas nociones de los ataques de robo de credenciales y phishing y estar alerta ante mensajes no esperados por cualquier medio, asi como conocer los tipos de ataques habituales e ser capaz de identificarlos.

    Internet permite estar conectados con muchas personas que están lejos o no veis en persona a las que queréis, pero también permite a cualquier persona del mundo contactarnos directamente. En las redes sociales se comparte mucha información personal demasiado alegremente (fotos propias, de hijos menores de edad, de otras personas sin su consentimiento, trabajo, …) y en este mundo hay personas que cometen delitos muy graves intencionadamente y conscientemente (robo, extorsión, …). La información pública y las redes sociales son un filón para ellos para realizar ataques informáticos.

    » Leer más, comentarios, etc...

    Bitácora de Javier Gutiérrez Chamorro (Guti)

    Los orígenes de Borland

    septiembre 30, 2021 10:58


    Me sorprende, de forma agradable, como esto de la retro-informática se ha ido popularizando tanto, que ahora hasta en la Wikipedia aparece la historia antigua del software. Borland Ltd. fue fundada en agosto de 1981 por tres ciudadanos de Dinamarca (Niels Jensen, Ole Henriksen y Mogens Glad), con el objetivo de desarrollar productos como Word …

    Los orígenes de Borland Leer más »



    Artículo publicado originalmente en Bitácora de Javier Gutiérrez Chamorro (Guti)

    » Leer más, comentarios, etc...

    Bitácora de Javier Gutiérrez Chamorro (Guti)

    WordPress y el problema con wp_options

    septiembre 24, 2021 07:24


    Con un tráfico en crecimiento la página funcionaba cada vez con más lentitud y de vez en cuando daba errores. Así que pagando más, he migrado a un nuevo alojamiento en forma de VPS (Virtual Private Server), aunque probablemente no lo recordéis, fue unos meses atrás cuando realicé todo el proceso y que hubo algunas …

    WordPress y el problema con wp_options Leer más »



    Artículo publicado originalmente en Bitácora de Javier Gutiérrez Chamorro (Guti)

    » Leer más, comentarios, etc...

    Bitácora de Javier Gutiérrez Chamorro (Guti)

    FileOptimizer premiado en el Building Good with C++ Builder Contest 2021

    septiembre 23, 2021 04:36


    Aunque la última vez que escribí sobre FileOptimizer fue en 2018 con el artículo Análisis estático de FileOptimizer, su desarrollo no se ha detenido, y regularmente he ido lanzando nuevas versiones, la última es la 15.10 de hace un par de semanas. Ciertamente el desarrollo se ha ido frenando poco a poco, en un software …

    FileOptimizer premiado en el Building Good with C++ Builder Contest 2021 Leer más »



    Artículo publicado originalmente en Bitácora de Javier Gutiérrez Chamorro (Guti)

    » Leer más, comentarios, etc...

    Una sinfonía en C#

    Ejecutar Wordpress + MySQL en Kubernetes paso a paso 3, configuración

    septiembre 21, 2021 12:00

    En el post anterior Agregamos Persisten Volumens y Persisten Volume Claims para tener un persistencia más allá del ciclo de vida de los Pods, en este Post vamos a mover la configuración a ConfigMaps y Secrets.

    Crear config maps

    El siguiente paso es pasar las environment variables a configuración, de modo de poder modificarlas y que sea escalable. De momento no vamos a crear secrets, solo pasar los valores a un configmap

    Primero creamos el configmap, de momento con los secrets y el mismo para ambas aplicaciones

    apiVersion: v1
    kind: ConfigMap
    metadata:
      labels:
        app: my-wordpress
      name: mywordpress-config
    data:
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
      MYSQL_DATABASE: password 
      MYSQL_USER: readWrite
      MYSQL_PASSWORD: password
      MYSQL_HOST: mysql
    

    Y modificamos los deployment para cargar sus valores en las variables de entorno

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-db
      labels:
        app: my-db
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: my-db
      template:
        metadata:
          labels:
            app: my-db
        spec:
          containers:
          - name: my-db
            image: mysql:5.7
            ports:
            - containerPort: 80
            volumeMounts:
            - mountPath: /var/lib/mysql
              name: my-db-pv
            env:
            - name: MYSQL_RANDOM_ROOT_PASSWORD
              valueFrom:
                configMapKeyRef:
                  name: mywordpress-config
                  key: MYSQL_RANDOM_ROOT_PASSWORD
            - name: MYSQL_DATABASE
              valueFrom:
                configMapKeyRef:
                  name: mywordpress-config
                  key: MYSQL_DATABASE
            - name: MYSQL_USER
              valueFrom:
                configMapKeyRef:
                  name: mywordpress-config
                  key: MYSQL_USER
            - name: MYSQL_PASSWORD
              valueFrom:
                configMapKeyRef:
                  name: mywordpress-config
                  key: MYSQL_PASSWORD
          volumes:
          - name: my-db-pv
            persistentVolumeClaim:
              claimName: mysql-pvc
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-wordpress
      labels:
        app: my-wordpress
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: my-wordpress
      template:
        metadata:
          labels:
            app: my-wordpress
        spec:
          containers:
          - name: my-wordpress
            image: wordpress:latest
            volumeMounts:
            - name: my-wp-pv
              mountPath: /var/www/html
            ports:
            - containerPort: 80
            env:
            - name: WORDPRESS_DB_PASSWORD
              valueFrom:
                configMapKeyRef:
                  name: mywordpress-config
                  key: MYSQL_PASSWORD
            - name: WORDPRESS_DB_USER
              valueFrom:
                configMapKeyRef:
                  name: mywordpress-config
                  key: MYSQL_USER
            - name: WORDPRESS_DB_NAME
              valueFrom:
                configMapKeyRef:
                  name: mywordpress-config
                  key: MYSQL_DATABASE
            - name: WORDPRESS_DB_HOST
              valueFrom:
                configMapKeyRef:
                  name: mywordpress-config
                  key: MYSQL_HOST
          volumes:
          - name: my-wp-pv
            persistentVolumeClaim:
              claimName: mywordpress-pvc
    

    Proteger secrets

    Los secrets o passwords de la base de datos en el yaml del config map no son una buena idea, podemos hacer dos cosas:

    • Crear dos objetos secret en yaml
    • Crear los secrets por línea de comandos

    Cada uno tiene sus ventajas y desventajas.

    Crear dos objectos secret Ya que los secrets se guardan en base64 primero hay que encodearlos

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecrets
    type: Opaque
    data:
      MYSQL_PASSWORD: bXlwYXNzd29yZA==
    

    Modificamos el configmap para quitar el password y modificamos los deployments para leer el secret

    apiVersion: v1
    kind: ConfigMap
    metadata:
      labels:
        app: my-wordpress
      name: mywordpress-config
    data:
      MYSQL_DATABASE: password 
      MYSQL_USER: readWrite
      MYSQL_HOST: mysql
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-db
      labels:
        app: my-db
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: my-db
      template:
        metadata:
          labels:
            app: my-db
        spec:
          containers:
          - name: my-db
            image: mysql:5.7
            ports:
            - containerPort: 80
            volumeMounts:
            - mountPath: /var/lib/mysql
              name: my-db-pv
            env:
            - name: MYSQL_RANDOM_ROOT_PASSWORD
              valueFrom:
                configMapKeyRef:
                  name: mywordpress-config
                  key: MYSQL_RANDOM_ROOT_PASSWORD
            - name: MYSQL_DATABASE
              valueFrom:
                configMapKeyRef:
                  name: mywordpress-config
                  key: MYSQL_DATABASE
            - name: MYSQL_USER
              valueFrom:
                configMapKeyRef:
                  name: mywordpress-config
                  key: MYSQL_USER
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysecrets
                  key: MYSQL_PASSWORD
          volumes:
          - name: my-db-pv
            persistentVolumeClaim:
              claimName: mysql-pvc
          - name: my-db-config
            configMap:
              name: mywordpress-config
    
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-wordpress
      labels:
        app: my-wordpress
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: my-wordpress
      template:
        metadata:
          labels:
            app: my-wordpress
        spec:
          containers:
          - name: my-wordpress
            image: wordpress:latest
            volumeMounts:
            - name: my-wp-pv
              mountPath: /var/www/html
            ports:
            - containerPort: 80
            env:
            - name: WORDPRESS_DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysecrets
                  key: MYSQL_PASSWORD
            - name: WORDPRESS_DB_USER
              valueFrom:
                configMapKeyRef:
                  name: mywordpress-config
                  key: MYSQL_USER
            - name: WORDPRESS_DB_NAME
              valueFrom:
                configMapKeyRef:
                  name: mywordpress-config
                  key: MYSQL_DATABASE
            - name: WORDPRESS_DB_HOST
              valueFrom:
                configMapKeyRef:
                  name: mywordpress-config
                  key: MYSQL_HOST
          volumes:
          - name: my-wp-pv
            persistentVolumeClaim:
              claimName: mywordpress-pvc
    
    

    Genial, el último paso sería para no tener el secret en un archivo (aunque se puede restringir su acceso) es crearlo por línea de comandos Borramos el existente y lo creamos por línea de comandos

    kubectl delete secret mysecrets
    kubectl create secret generic mysecrets --from-literal=MYSQL_PASSWORD='bXlwYXNzd29yZA=='
    kubectl get secret mysecrets -o yaml
    

    Alternativamente podemos crearlo por línea de comandos a partir de un file (por ejemplo si es un texto largo o un certificado, etc.)

    kubectl create secret generic db-user-pass --from-file=username=./username.txt --from-file=password=./password.txt
    

    Nos leemos.

    » Leer más, comentarios, etc...

    Una sinfonía en C#

    Ejecutar Wordpress + MySQL en Kubernetes paso a paso 2, agregando persistencia

    septiembre 12, 2021 12:00

    En el post anterior vimos cómo ejecutar Wordpress (Wordpress + MySQL) en Kubernetes, del modo más básico, solo con dos Pods separados. En este post vamos a poner la persistencia en elementos externos (volúmenes) para que los datos tengan un ciclo de vida separado de los Pods.

    Mejorando la persistencia

    Evidentemente la persistencia se hace dentro de los containers y esto no es ideal. Vamos a agregar algo de storage. Primero creamos el Persisten volumen, como yo estoy en Docker en Windows será del tipo local-storage En este caso este tipo no permite Dynamic Provisioning, así que no hace falta StorageClass Entonces creamos dos PV

    kind: PersistentVolume
    metadata:
      name: wp-pv
    spec:
      capacity:
        storage: 1Gi
      volumeMode: Filesystem
      accessModes:
      - ReadWriteOnce
      storageClassName: local-storage
      local:
        path: /run/desktop/mnt/host/c/k8svolume/wp #windows path
      nodeAffinity:
        required:
          nodeSelectorTerms:
          - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
              - docker-desktop
    
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: mysql-pv
    spec:
      capacity:
        storage: 1Gi
      volumeMode: Filesystem
      accessModes:
      - ReadWriteOnce
      storageClassName: local-storage
      local:
        path: /run/desktop/mnt/host/c/k8svolume/mysql
      nodeAffinity:
        required:
          nodeSelectorTerms:
          - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
              - docker-desktop
    

    Creamos un persisten volume claim para cada deployment

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: mysql-pvc
    spec:
      accessModes:
      - ReadWriteOnce
      storageClassName: local-storage
      resources:
        requests:
          storage: 1Gi
    
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: mywordpress-pvc
    spec:
      accessModes:
      - ReadWriteOnce
      storageClassName: local-storage
      resources:
        requests:
          storage: 1Gi
    

    Y por último modificamos los deployments de Wordpress y MySQL para declarar y montar el los claims

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-db
      labels:
        app: my-db
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: my-db
      template:
        metadata:
          labels:
            app: my-db
        spec:
          containers:
          - name: my-db
            image: mysql:5.7
            ports:
            - containerPort: 80
            volumeMounts:
            - mountPath: /var/lib/mysql
              name: my-db-pv
            env:
            - name: MYSQL_ROOT_PASSWORD
              value: "my-secret-pw"
            - name: MYSQL_DATABASE
              value: "my-db"
            - name: MYSQL_USER
              value: "my-user"
            - name: MYSQL_PASSWORD
              value: "my-secret-pw"
          volumes:
          - name: my-db-pv
            persistentVolumeClaim:
              claimName: mysql-pvc
    
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-wordpress
      labels:
        app: my-wordpress
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: my-wordpress
      template:
        metadata:
          labels:
            app: my-wordpress
        spec:
          containers:
          - name: my-wordpress
            image: wordpress:latest
            volumeMounts:
            - name: my-wp-pv
              mountPath: /var/www/html
            ports:
            - containerPort: 80
            env:
            - name: WORDPRESS_DB_PASSWORD
              value: "my-secret-pw"
            - name: WORDPRESS_DB_USER
              value: "my-user"
            - name: WORDPRESS_DB_NAME
              value: "my-db"
            - name: WORDPRESS_DB_HOST
              value: "mysql"
          volumes:
          - name: my-wp-pv
            persistentVolumeClaim:
              claimName: mywordpress-pvc
    

    Y ya está, en el siguiente post mejoraremos la configuración. Nos leemos en la próxima

    » Leer más, comentarios, etc...

    Fixed Buffer

    ¡¡FixedBuffer ha cumplido su tercer año!!

    septiembre 11, 2021 10:04

    Tiempo de lectura: 2 minutos

    Otro año más llega la vuelta de vacaciones y con ello FixedBuffer cumple un año más. Tres años hace desde que empece esta andadura donde voy publicando mis notas sobre nuevas tecnologías y sobre cosas que en general me parecen interesantes.

    Es cierto que este último año he estado sin escribir desde febrero, la muerte de mi padre, el COVID, cambios de trabajo y demás cosas me han alejado de escribir en el blog (principalmente por no tener ganas o simplemente no creer que tenía nada interesante para contar). La parte buena es que aunque no he escrito activamente si he seguido participando activamente en la comunidad así que al menos si alguien ha querido saber de mí (no alcanzo a imaginar por qué… xD), no se ha quedado sin la oportunidad.

    También voy a aclarar que no todo ha sido malo, y que he cumplido con otras metas personales: he comprado mi casita, sigo siendo MVP y mi mujer todavía no se ha cansado de mí y de todo el tiempo que dedico a estas cosas (toda una santa he de añadir).

    Dicho esto, ¿qué va a ser de FixedBuffer de aquí en adelante? Pues la verdad no tengo una idea clara… Me gustaría y voy a intentar escribir una entrada nueva cada 2-3 semanas, el verano me ha servido para recuperar fuerzas y llevo lo suficiente en mi nuevo trabajo como para haber descubierto varias tecnologías muy interesantes de las que escribir, o de cosas que si bien son básicas, no todo el mundo las conoce. Veremos en que se traduce y si no acabaré solo con las charlas (‘traccionando’ que diría alguno 😉 )

    Y ya como despedida, solo 2 cosas más. La primera es agradecer a la gente que seguís aquí pese a que no haya escrito demasiado últimamente, la verdad es que ver que el contenido sigue siendo útil es una de las principales razones para seguir tirando líneas 🙂
    La segunda, como ya empieza a ser tradición, es el top 5 de las entradas del último año:

    1. Haciendo fácil el acceso a datos con Entity Framework Core (Parte 2)
    2. Inyección de Dependencias en .Net Framework
    3. Worker Service: Cómo crear un servicio .Net Core 3 multiplataforma
    4. Cómo medir tiempos en C# y .Net con precisión
    5. Generación de ficheros «Excel» (xlsx) con ClosedXML

    **La entrada ¡¡FixedBuffer ha cumplido su tercer año!! se publicó primero en Fixed Buffer.**

    » Leer más, comentarios, etc...

    Meta-Info

    ¿Que es?

    Planeta Código es un agregador de weblogs sobre programación y desarrollo en castellano. Si eres lector te permite seguirlos de modo cómodo en esta misma página o mediante el fichero de subscripción.

    rss subscripción

    Puedes utilizar las siguientes imagenes para enlazar PlanetaCodigo:
    planetacodigo

    planetacodigo

    Si tienes un weblog de programación y quieres ser añadido aquí, envíame un email solicitándolo.

    Idea: Juanjo Navarro

    Diseño: Albin