Lack of security page registration

Asked

Viewed 39 times

2

Guys, I have a question about security.

I made a form, to register users, until then ok. But for example, this form has an action, which is for the same page in the case.

If a person creates a page in PHP for example, with a form similar to mine, and in the action of his form, is pointed to my page, and the same wants to do for example, 1000 entries, can he? If so, is there any way around it?

<form method="POST">
    <div class="form-group">
        <label for="nome">Seu nome completo: </label>
        <input type="text" name="nome" class="form-control" id="nome" placeholder="Nome Completo, Ex: Lucas de Carvalho Alves" required="required">
    </div>
    <div class="form-group">
        <label for="email">Seu E-Mail: </label>
        <input type="email" name="email" class="form-control" id="email" placeholder="Seu e-mail, Ex: [email protected]" required="required">
    </div>
    <div class="form-group">
        <label for="senha">Sua Senha: </label>
        <input type="password" name="senha" class="form-control" id="senha" placeholder="Sua senha, escolha uma senha segura"required="required">
    </div>
    <div class="form-group">
        <label for="nascimento">Data de Nascimento: </label>
        <input type="date" name="nascimento" class="form-control" id="nascimento" required="required">
    </div>
    <button class="btn btn-success">Cadastrar</button>
</form>

2 answers

1

Yes, he can. Actually there are two questions here:

  1. Send this information as if you are logged in to a user session:

  2. Send this information arbitrarily without posing as a connected user.

In both cases this is called Cross-Site Request Forgery.


There are ways to mitigate or resolve both attacks:

1. Abusing open sessions:

For this you need to ensure that the customer was the one who submitted the form and not an external website. One of the ways to do this is, in short, to create a random code and protect the cookies used by the session (if you use the standard session_start he uses a cookie as an identifier).

For something minimally safe (and easy to use), then let’s go.

First you will need to create a session, there are actually other ways, such as sending a custom header, but this will require major changes and is not supported by a simple form. To create the session use:

$default = session_get_cookie_params();
session_set_cookie_params(
    $default['lifetime'],
    $default['path'] . '; samesite=strict',
    $default['domain'],
    true,
    true
);

session_start();

This will make the cookie unable to be fetched by Javascript due to the HttpOnly as true, will only be dealt in SSL (Secure as true) and add the samesite=strict that prevents, in modern browsers, another site from sending requests containing the cookie.

Now we create this CSRF-Token:

if(!isset($_SESSION['csrf'])){
    $_SESSION['csrf'] = pack('H*', random_bytes(24))[1];
}

This will generate 192 random bits, converted to hexadecimal, in order to make it easier to insert in the forms, despite doubling the size to 48 bytes.

Then to add to the form:

<input type="hidden" name="csrf" value="<?= $_SESSION['csrf'] ?>">

Now, when the user submit the form we need to compare it:

if(!isset($_POST['csrf'], $_SESSION['csrf'])){
    echo 'Dados não foram enviados';
    exit();
}

if(!hash_equals($_SESSION['csrf'], $_POST['csrf'])){
    echo 'O "CSRF-Token" está incorreto'
    exit();   
}

// Chegou aqui está tudo certo.
insere_dados_do_formulario();

// Alteramos o CSRF, para não reutiliza-lo:
$_SESSION['csrf'] = pack('H*', random_bytes(24))[1];

This will be enough to prevent both cases. But there are some criteria for this to be safe:

  1. The generator must be unpredictable to the attacker (random_bytes is sufficient, but cannot use time() or mt_rand(), for example.).
  2. The user must be using a minimally updated browser, extremely obsolete browsers may let pick up the content of the page, which would make the attacker have access to CSRF-Token.
  3. Your website may not be vulnerable to Session Fixation, otherwise the attacker may set a cookie (the session identifier) with a CSRF he already knows.

This is not the safest method of all, but it is easy to implement. The CSRF must be changed from time to time, or at each page a different CSRF token.

This ensures that:

Any other site that cannot obtain the code will not be able to perform a valid request.

2. Spam

The above case does not prevent someone from using one Curl of life and make the request, it is quite simple to ignore the CSRF-Token in such cases.

Assuming the attacker is not using the browser, he can simply make a request (Alá curl https://site.com/form.php) and take the CSRF-Token, then make a curl -H "Cookie: phpsessid=ccccc" -d "csrf=aaaaa" https://site.com/form.php). The values of ccccc and aaaaa were obtained in the previous request.

The only way to mitigate this is by using captcha, or some kind of hashcash. This will at least increase the cost for each shipment, which should reduce the number of requests made.

0

I don’t think it’s ideal for you to keep everything on the same page. Anyway, I think a malicious programmer could only do it with injections.

In order for him to be able to put in his code he would have to already know his PHP and be connected in his database. That’s the part he’d only do with injections.

Browser other questions tagged

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