Lack of security page register

2

Well, I'm having 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 he wants to do for example, 1000 entries, can he? If so, is there any way around this?

<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>
    
asked by anonymous 08.11.2017 / 03:08

2 answers

1

Yes, he can. There are actually two issues here:

  • Send this information as if logged into a user's session:

  • Send this information arbitrarily without being a logged in user.

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

    There are ways to mitigate or resolve both attacks:

    1. Abuse open sessions:

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

    For something minimally secure (and easy to use), then let's go.

    First you need to create a session, there are actually other ways, such as sending a custom header, but this will require more 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 cause the cookie to not be fetched by Javascript, due to HttpOnly as true , it will only be trafficked in SSL ( Secure as true ) and still add the samesite=strict it prevents , in modern browsers, that another site sends requests containing the cookie.

    Now we have created the CSRF-Token:

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

    This will generate 192 random bits, converted to hexadecimal, so that it is easier to insert into forms, although double the size to 48 bytes.

    Then, to add in the form:

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

    Now when the user submits 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:

  • The generator must be unpredictable for the attacker ( random_bytes is sufficient, but can not use time() or mt_rand() , for example.)
  • The user must be using a minimally updated browser, extremely obsolete browsers can let the contents of the page get caught, which would allow the attacker to access the CSRF-Token.
  • Your website can not be vulnerable to Session Fixation, otherwise the attacker can set a cookie (the session identifier) with a CSRF that he already knows.
  • This is not the safest method of all, but it is easy to implement. The CSRF should be changed from time to time, or each page a different CSRF token.

    This ensures that:

    Any other site that can not get the code will not be able to make a valid request.

    2. Spam

    The above case does not prevent someone from using a cURL of life and makes the request, it is quite simple to ignore the CSRF-Token in these cases. Assuming that the attacker is not using the browser, he can simply make a request (al curl https://site.com/form.php ) and get 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 sort of Hashcash. This will at least increase the cost for each submission, which should reduce the number of requests made.

        
    08.11.2017 / 11:48
    0

    I think it's not ideal to keep everything on the same page. Anyway I think a malicious programmer would only get it if it was with injections.

    In order for him to be able to put in his code he would have to know his PHP and be connected to his database. This is the part he would only do with injections.

        
    08.11.2017 / 11:51