Ofuscando Dados com DataMask

Quando a nossa aplicação lida com dados sigilosos, precisamos nos atentar em como ela armazena isso fisicamente. Se alguém não autorizado tem acesso à base de dados, ele poderá visualizar todos os dados que estão lá. Uma opção que temos é armazenar os dados criptografados, mas nesta situação,  temos que nos preocupar como a chave de criptografia se quisermos reverter o valor para utilizá-lo novamente.

Imagine que o cliente faça uma compra no site, e depois que ele informa o cartão de crédito, queremos armazenar ele para melhor a experiência sua usuário, e assim, na próxima compra, o cartão já estará armazenado, não precisando informar novamente. Por mais que a aplicação não exponha diretamente o número do cartão de crédito em suas páginas/telas, se houver alguma vulnerabilidade, é possível ter acesso à tabela e, consequentemente, ao número de todos os cartões que estiverem lá.

O SQL Server 2016 possui um recurso chamado data mask, que como o próprio nome sugere, permite ofuscar a informação de uma determinada coluna para um determinado login, e por mais que se explore a vulnerabilidade, o SELECT sempre retornará o dado aplicando a mascará que você configurou. No script abaixo, alteramos a coluna CartaoDeCredito para exibir apenas os dois primeiros e os dois últimos números do cartão. Há ainda outras funções predefinidas, que retornam o valor padrão do tipo de dado da coluna, uma que substitui o endereço de e-mail por asteriscos, entre outras.

ALTER TABLE Cliente
    ALTER COLUMN CartaoDeCredito 
        ADD MASKED WITH (FUNCTION = 'partial(2, "**-****-****-**", 2)')
GO

Para o exemplo, criei um login limitado chamado WebUser, concedendo a permissão para realizar SELECT na tabela de clientes. Agora note que abaixo estamos utilizado ADO.NET para extrair o número do cartão de crédito para apresentar na tela. Quando utilizamos a string de conexão com acesso irrestrito, o cartão de crédito é exibido integralmente; se utilizarmos a string de conexão com o usuário WebUser, o cartão é apresentado com uma porção de asteriscos.

static void Main(string[] args)
{
    const string conexao1 = "Data Source=.;Initial Catalog=DB;user id=WebUser;password=123";
    const string conexao2 = "Data Source=.;Initial Catalog=DB;Integrated Security=True";

    Exibir(conexao1);
    Exibir(conexao2);
}

private static void Exibir(string connString)
{
    using (var conn = new SqlConnection(connString))
    {
        using (var cmd = new SqlCommand("SELECT CartaoDeCredito FROM Cliente", conn))
        {
            conn.Open();

            using (var dr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                if (dr.Read())
                    Console.WriteLine(dr.GetString(0));
        }
    }
}

E o resultado é:

12-****-****-78
1234-5678-1234-5678

Publicidade