prevent multi page form against bots - php

I try to design a save reset-password-page for my scripts. I got very far, but now I could need some help. What I got already:
user puts his mail into a form and the script is sending him a mail with a url the user have to open. parameters: usertype, userid, token.
if the users visits the url he will get to a page, with a form where the token is already inserted. he only needs to click "proceed".
third page shows a form to change the password.
Now I'm a little doubtful with the security of this script. Lets say the attacker knows the mail, the usertype and the userid (would only be people with login, but its possible to know all that). He can now send a password-reset-link to users mail. Not a problem so far.
But he knows that there is a token generated now and can try to brutforce it. For this he calls the 2nd or 3rd page with the known parameters and just trys every token.
To prevent this I put a captcha in the 2nd-page.
But now I need to protect the 3rd page/form. For now I give the token and check it a 2nd time. Thats not nice and makes the 1st-captcha just useless. Giving it another captcha would be possible, but not userfriendly. Checking the captcha after 3rd form is filled is also not userfriendly.
So how can I make sure, the users passed the token-page (with captcha) in my script. So that the user can not just send a POST (e.g. with curl) with input-data of my 3rd-form (the password-change-form).
Thank you in advance.
2nd-form
<form name="confirm" method="GET">
<p>
<label for="confirm">Token
<input type="text" name="confirm" id="confirm_code"
<?php
if(isset($_GET['confirm'])) echo ' value="'.$_GET['confirm'].'"';
?>
></label>
</p>
<p><div class="g-recaptcha" data-sitekey="X" data-callback="checked" data-size="invisible"></div></p>
<p style="text-align:center;">
<input type="submit" value="Proceed">
</p>
<?php
echo '<input type="hidden" name="usertype" value="'.$_GET['usertype'].'">';
echo '<input type="hidden" name="userid" value="'.$_GET['userid'].'">';
echo '</form>';
3rd-form
<form name="change" method="post">
<p>
<label for="pw">New pw
<input type="password" name="pw" id="pw"></label>
</p><p><label for="pw_repeat">Repeat
<input type="password" name="pw_r" id="pw_repeat"></label>
</p><p style="text-align:center;">
<input type="hidden" name="usertype" value="<?php echo $_GET['usertype']; ?>">
<input type="hidden" name="userid" value="<?php echo $_GET['userid']; ?>">
<input type="submit" name="change" value="Change now">
</p>
</form>

Hey I too am a programmer who is getting started and I work mostly on logins and stuff.
Here are my Suggestions:
Add an algorithm that generates some automatic key purely on random basis.
Produce a link based on that random piece of key and a specified set of values(keep that a secret) and also make sure the final generated link is pretty big.
At the second page make sure you ask for a key (You'd send this key straight to his email along with the page link) i.e., the random generated key and then the algorithm magically decrypts to see if the underlying data is the same based on some values attached to his account or something else.
Make sure the link expires in the time needed to brute force through the page
If you can make sure above steps are followed correctly, then even with a bit of discomfort to the user your security will be pretty good. What do you think?
Cheers,
Rj

Related

When clicking submit the form redirects to the registration manager

I am attemping to create a PHP login system using MySQLi.
However I have created an HTML Form:
<form action="register_manager.php" method="post">
<p>Please fill all fields!</p>
<input type="text" name="username" value="<?PHP print $getuser; ?>" maxlength="15" /><br />
<input type="password" name="password" placeholder="Password" maxlength="15" />
<input type="password" name="confirmpassword" placeholder="Confirm Password" /><br />
<input type="text" name="email" placeholder="E-Mail Address" />
<p style="margin: 0; padding: 0;">
(Use a vaid a valid E-Mail Address for activation!)
</p>
<p>
Already got an account?
</p>
<input type="submit" name="regsubmit" value="Register"/><br />
<?PHP echo '<p>'.$errormsg.'</p>'; ?>
</form>
Once I click submit, it redirects me to the registration_manager.php page, which is not what I want it to do. I am new to PHP so I am not aware on why it is doing this, instead of registering the user.
This is the register_manager.php file:
http://pastebin.com/cvbA6L6P
The action specified in your form is register_manager.php so whenever you hit the submit button you will get redirected there. Also, in the link you provided of the source code of register_manager.php, you're generating error messages, depending on the case, but never printing them on the page so the user can see what is wrong, unless of course the html form you provided is included in the register_manager.php. Finally, when testing make sure you fill all the requirements set by the if statements in you register_manager.php file, i.e. pass all wanted fields (username, email (which must be longer than 7 chars, containing the '#' and '.' characters), password, password confirmation). Hope this solves your question!
What you are describing is normal. The browser will send a POST request to the URL defined as action. So you need to render the form there as well. You can either abstract the form out and reuse it in both files or do the initial form rendering and the processing in one file by checking if $_POST['regsubmit'] is set (if it is not set you are rendering the form initially).
Submit button will activate the request of the webpage specified in the attribute action, passing the information inside the form by the method selected. In your example, the information is passed to register_manager.php using POST method.
To retrieve the information passed, you could use the arrays $_POST and $_GET depending the method used. In your example:
<?php
print $_POST['password'];
print $_POST['confirmpassword'];
print $_POST['email'];
?>

can I send additional variables through form post in PHP?

I have mysql table members with columns id, user, password, and verified
When a user logs in, using user and password (compared against members-db) they are presented with a form. The form gathers info to be manually checked by an admin.
Upon submitting the form, it will send an email to admin with all the details to manually confirm.
The problem that I am hitting is that admin wants the email to contain a link that will enable him to update the verified field in members table upon clicking. I need to send a previously stored variable with the form to do so. That way I have a link to the members table.
For example, If I store $user_id as the id of whichever row I need to update, and I could send it forward with the form, then I could just use the UPDATE feature WHERE id = $user_id
Here is my form ...
<form method="post" name="verify_form" action="../includes/verify.php">
Website for Online Verification: <input type="text" name="webpage" id="webpage" /><br />
Identification Number: <input type="text" name="number" id="number" /><br />
Expiration Date: <input type="text" name="expire" id="expire" /><br />
<input type="submit" value="Verify Me!" onclick="return vformhash(this.form, this.form.webpage, this.form.number, this.form.expire);" />
<input type="reset" value="Clear Form" />
</form>
Is there a way to send my previously captured $user_id to the verify.php page when user submits?
You could use a hidden field:
<input type="hidden" name="userid" value="<?php echo $user_id; ?>" >
You can use:
<input type='hidden' name='user' value=<?php echo $user_id; ?>>
inside the form.
You could send it in url like
$url = "verify.php?user_id=" . $ user_id;
And access it in verify.php page by
$ user_id = $_GET ['user_id'];
You can use hidden fields: <input type="hidden"....
If the information is sensitive, you should not put it in those hidden fields, but rather store it in the session or otherwise on your server. You can then use a hidden field to store a key that you can use to find those values again later.
If you would use regular session variables, without a key in the form, you might get the issue of finding the wrong value if the user has multiple forms open in multiple tabs.
Two options:
Change your for tag to pass the ID as a GET param :
action="../includes/verify.php?user_id=123"
-or-
Add a hidden field :
<input type="hidden" name="user_id" id="user_id" value="123" />
You will be able to access this value with either $_GET['user_id'] for option #1, or $_POST['user_id'] for option #2 within your PHP script.
When the user logs in, save their ID in a session value such as $_SESSION["userID"]. Then in verify.php you can access $_SESSION["userID"]. It's cleaner than passing the ID back and forth as parameters.

Curl login with hash or random hidden codes

I'm trying to login to a site and from there i want to send a message with the form available there. It looks like
<form method="POST" action="pm.php">
To: <input type="text" name="user" />
<input type="hidden" name="pm_tid" value="ef0gjpmgwag5g21agjg" />
<input type="hidden" name="box" value="new" />
Subject: <input type="text" name="subject" />
message: <textarea name="text"></textarea>
<input type="submit" value="Send" />
</form>
I managed to enter the login and to the page where is the message send form but in that html code you can see that there is a hidden random hash value which changes after every reload. I want to get that correctly and post in the form. Only then my message will be sent. Please don't say that it's IMPOSSIBLE. It is possible. One of my classmate succeeded in it but he is not helping me.
Please try to help me.
This looks like CSRF protection. The usual implementation for this is to store the token in a cookie (or server session if a session token cookie is used) and then compare it to the token in the form.
You need to:
request the HTML document containing the form
store the cookies you get at the same time (assuming that they come with the form)
parse the html to get the token from the input
make the request to pm.php including the token and the cookie

safely getting back info presented in a form (PHP)

Let's say I have a form that looks like this:
<form action="/script.php" method="post">
<input name="my_input" length="80" />
<input type="submit" value="submit" />
</form>
Now I also want to include a numeric identifier - call it a ticket id. "Here's the ticket history, do you want to add something?" The user can't modify that.
My question is...what is the safest way to get that ticket id in the form submission?
No problem accomplishing it, but my question is around security. So here are the ways to get a variable back that I can think of:
<form action="/script.php" method="post">
<input name="my_input" length="80" />
<input type="hidden" name="ticket_id" value="12345" />
<input type="submit" value="submit" />
</form>
or
<form action="/script.php?ticket_id=12345" method="post">
<input name="my_input" length="80" />
<input type="submit" value="submit" />
</form>
I'm concerned that someone could craft a malicious POST and submit it and append their comments to a different ticket. i.e., compose a POST from their own server/browser/tool. If I was doing this with GET then they certainly could do that just by changing the url vars - it's possible to do that also with POST too, right?
I can check that the user owns that ticket of course and do some other validation, but fundamentally, how do you present data to a user and safely get it back again in an HTML form?
Is there something other than creating a unique serial number ("FORM 12345 should present ticket id 6789") record on the server side and then checking it back?
I'm using PHP & MySQL on the backend though I'm not sure my question is specific to those technologies.
use session
form.php
<?
session_start();
$_SESSION['ticket_id'] = '1234';
?>
script.php
<?
session_start();
$ticket_id = $_SESSION['ticket_id'];
?>

Automatically log in on another website at the click of a button - cURL or Javascript?

I would like to make a button on my website that automatically logs me in on another website. I recon I can use either Javascript/jQuery or PHP/cURL to do this.
Which is the best way to go?
You may use either remote javascript or iFrame. Find more details here: http://kuza55.blogspot.com/2007/06/building-secure-single-sign-on-systems.html
Also checkout google's approach named SAML: http://code.google.com/googleapps/domain/sso/saml_reference_implementation.html
It depends what the website is. JavaScript and jQuery alone cannot be used due to the cross-domain policy. You could perhaps use a combination of cURL and AJAX to achieve something similar.
I think you might need to provide a little more information about the site, and exactly why you'd want to do this...
I'm not sure if this is exactly what you're looking for, but one thing I have done in the past is to mimic the login form on the site you want to log in to.
For example lets say you want to log in to 'example.com'. In the source code for the login page of 'example.com' you will find the html code for the login form.
Example
<form name="blabla" action="action.php" method="post">
<input type="text" name="username" />
<input type="password" name="password" />
<input type="sumbit" value="Login" />
</form>
Create a form on your site similar to the one you find in 'example.com'. If you want you can even hide the fields, include values to make it a one button login. The trick is making sure that the action has the actual url. For example if the form says 'action.php' for 'example.com' you would put 'http://example.com/action.php'
Example
<form name="blabla" action="http://example.com/action.php" method="post">
<input type="hidden" name="username" value="testuser" />
<input type="hidden" name="password" value="testpass" />
<input type="sumbit" value="Login" />
<form>
This will log you in to the site in most cases. If you don't want to leave your own site you can set a 'target' for the form to an iframe or something.

Categories