How to encrypt GET and copy the parameter

Asked

Viewed 990 times

2

I have an e-mail from feedback that is sent to a user after the service is completed. This email has 5 links, where each is the respective service note (from 1 to 5).

I want to direct to the update page in the database, service evaluation, using the id of the customer, the provider, the order and the note.

For this I used link as.. /avaliacao.php?prestador=1&cliente=2&pedido=3&avaliacao=4

In PHP, I’m using $_GET['prestador'] to take the parameters and define the variable that will be inserted in a Mysql database, but I do not want the client to see this url, so he doesn’t change the way he wants.

How can I do it? Encrypt? There’s another way?

  • 5

    Ever thought of using POST?

  • but then each link would be a form? I will use so, link 1 evaluation=1, Link2 evaluation=2...etc. These links will be in the email sent

  • I don’t understand, I could post the code of your back end too, so it’s easier to help

  • @Leandromarzullo if you want to obfuscate the parameters you can use the functions urlencode() and base64_encode(), then just decode.

  • 1

    But as @Rafaelaugusto said, it would be better to use the verb POST for this scenario.

  • got. doing the post like you said, I’ll post here as it was, BRIGADÃO!!

  • 1

    POST will not guarantee security, the ideal to avoid the manipulation I believe, would be a unique and exclusive TOKEN that would already contain the data provider and customer and request and after used, the such TOKEN could no longer be reused.

Show 2 more comments

2 answers

1

You can use a simple HMAC to check if the id remains unchanged, this will be safe as long as no one knows the key used by you, logical it must be strong and generated safely, I will explain this also.

Also you should make sure that one cannot get Hmacs from other accounts, otherwise it would be the same as it having the key.


/!\ Do not use the keys mentioned in the examples.

In general, something like:

$id = '1234'; 
// Este é o id do usuário, que deve estar associado de alguma forma segura.

$chave = pack('H*', '07e8796b87caa27d793dbe2ecfa7c85f753a9c920cb5d1394fbc36c20f1755b818c9afe37fb453ebf42724c8670d365ca9f0d12d49e31ea843023126f3174df9');
// Esta sua chave secreta e segura que foi gerada por você.

$hmac = hash_hmac('sha512', $id, $chave);
// Este é o resultado do HMAC de SHA-512.


<form action="avaliacao.php" method="post">

<input name="id" type="hidden" value="<?= $id ?>" />
<input name="hmac" type="hidden" value="<?= $hmac ?>" />


<input type="submit" name="avaliacao" value="1" />
<!-- ... Resto das outras opções  -->
</form>

Then to check for change:

$chave = pack('H*', '07e8796b87caa27d793dbe2ecfa7c85f753a9c920cb5d1394fbc36c20f1755b818c9afe37fb453ebf42724c8670d365ca9f0d12d49e31ea843023126f3174df9');

if(!isset($_POST['hmac'], $_POST['id'])) {
    echo 'Erro: faltam dados';
    exit;
}

$isHMACValido = hash_equals(
    hash_hmac('sha512', $_POST['id'], $chave),
    $_POST['hmac']
);
// Comparamos de maneira segura e em tempo contante o HMAC enviado pelo usuário e o computado agora.

if(!$isHMACValido){
    echo 'Erro: Dados foram manipulados';
    exit;
}

// Chegou até aqui está tudo certo!
// ...

What protection this brings?

  • Against amendment of id by a user who does not know the key.

How this protection is achieved?

  • HMAC is an option of the type H(K⊕opad||H((K⊕ipad)||m), therefore two messages (m, in this case the id) different result in a different HMAC. A malicious user can modify both (example, upload: id=99&hmac=aaaa), but this will be compared to the new HMAC (we will do hmac(id, key)), obviously it will be different from the hash sent by the user.

This has no risk?

Of HMAC...

  • CPA attacks do not work, even if the attacker creates thousands of accounts (thus having multiple valid Hmacs for each account) he will have no clue as to which key is used.

  • Exhaustive search attacks will always work, but are 512 bits, this results in more than 2 512 possibilities, which makes the attack unfeasible, at least until this time.

  • Exhaustive search attacks against the key also work. For this the key must be safe and generated from a CSPRNG safe and strong enough, otherwise brute force attacks will be fast, also use 512 key bits.

  • Mitm’s attacks are valid. If not using HTTPS one person monitoring the network will be able to obtain the HMAC from the other user, this would not only affect the HMAC, but the whole system.

Of the application...

  • It should not be possible for the user to have access to other Hmacs users. The id should be solely his. Your application should not say what is the HMAC of an X, being X sent by the user, allow this will override all security.

  • The key must be kept secret and must not be known by the client, if the key is exposed it will be possible to compute valid Hmacs.


To generate a safe key use:

echo unpack('H*', random_bytes(32))[1];

0

As Rafael Augusto said, changed using the POST, there was so:

email:

<form action="avaliacao.php" method="post">
<input name="id" type="hidden" value="1" />
<input type="submit" name="avaliacao" value="1" />
<input type="submit" name="avaliacao" value="2" />
<input type="submit" name="avaliacao" value="3" />
<input type="submit" name="avaliacao" value="4" />
<input type="submit" name="avaliacao" value="5" />
</form>

php evaluation.

<?php

$id = $_POST['id'];
$avaliacao = $_POST['avaliacao'];
echo 'id: '.$id.' - Avaliação: '.$avaliacao.'<br/>';

$conn = new mysqli('localhost', 'user', 'password', 'db');
$sqlverifica = '
SELECT avaliacao
FROM prestadores_avaliacao
WHERE id = '.$id;
$result = $conn->query($sqlverifica);
while($row = $result->fetch_assoc()) {
    $avaliacaoatual = $row["avaliacao"];
    echo "Avaliação Original: ".$avaliacaoatual;
}

if($avaliacaoatual==''){
$sql = '
UPDATE prestadores_avaliacao
SET avaliacao = '.$avaliacao.'
WHERE id = '.$id;
$conn->query($sql);
}

?>
  • 1

    POST does not change anything, it is still possible to change the data.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.