So here is the form where users input data:
Code: Select all
<?php
session_start();
function generateToken($seed='mysupermagnificentkey')
{
$token = md5($seed.mktime());
$_SESSION['token']=$token;
return $token;
}
generateToken();
?>
Code: Select all
<form method="POST" action="proofsend.php">
<textarea rows="10" name="proof" cols="60"></textarea></b></p>
<!--hidden values saving information about the current user -->
<input name="userproof_id" type="hidden" value="<? echo $_SESSION['user_id'] ;?>">
<!--hidden values saving information about the job information -->
<input name="createuser_id2" id="createuser_id2" type="hidden" value="<? echo $row['createuser_id'] ;?>" />
<input name="perperson" id="perperson" type="hidden" value="<? echo $row['perperson'] ;?>" />
<input name="job_id" id="job_id" type="hidden" value="<? echo $my_id ;?>" />
<input name="title" type="hidden" value="<? echo $row['title'] ;?>">
<input name="amountworkers" id="amountworkersn" type="hidden" value="<? echo $row['amountworkers'] ;?>" />
<input type="submit" value="Submit Proof" name="submit"></p>
</form>
Now the data is sent to proofsend.php and this is where the security issues are, i will just paste the whole code its pretty ashamful i guess:
Code: Select all
<?php
// Check the form token
if(isset($_POST['job_id']) && isset($_POST['userproof_id']) && isset($_POST['proof']) && isset($_POST['title']) && isset($_POST['perperson']) && isset($_POST['amountworkers']) && isset($_POST['createuser_id2']))
{
if($_POST['token'] != $_SESSION['token'])
{
die('Token is invalid');
}
// token is now valid, process rest of form
$tbl_name = 'proof';
//Function definition
function onlyLetters($str){
$text = str_replace("\n", "xyxy", $str);
$pattern = '/[^0-9a-zA-Z-. ]*/';
$text = preg_replace($pattern, '', $text);
return str_replace("xyxy", "\n", $text);
}
function onlyNumbers($str){
$pattern = '/[^0-9.]*/';
return preg_replace($pattern, '', $str);
}
// Get and strip values from form
$job_id=onlyLetters($_POST['job_id']);
$userproof_id=onlyLetters($_POST['userproof_id']);
$proof=onlyLetters($_POST['proof']);
$title=onlyLetters($_POST['title']);
$perperson=onlyLetters($_POST['perperson']);
$createuser_id2=onlyLetters($_POST['createuser_id2']);
$query = "SELECT proof.* FROM proof WHERE proof.userproof_id ='$_SESSION[user_id]' and proof.job_id =$job_id";
$result = mysql_query($query);
$num_rows = mysql_num_rows($result);
if ($num_rows != 0){die("You have already completed this job. Please try another job.");
}else{
// Get and strip values from form again ... probably not needed.
$job_id=onlyLetters($_POST['job_id']);
$userproof_id=onlyLetters($_POST['userproof_id']);
$proof=onlyLetters($_POST['proof']);
$title=onlyLetters($_POST['title']);
$perperson=onlyLetters($_POST['perperson']);
$createuser_id2=onlyLetters($_POST['createuser_id2']);
// Insert data into mysql
$sql="INSERT INTO $tbl_name(job_id, userproof_id, proof, title, perperson, createuser_id2, date)VALUES('$job_id', '$userproof_id', '$proof','$title','$perperson','$createuser_id2',NOW())";
$result=mysql_query($sql);
// message to creator
$title = "A worker has completed your job.";
$to = "$createuser_id2";
$message =
"We are happy to inform you that a worker has completed your job. Please head over to the My Jobs section in the employers menu to view the proof submitted, once there you can approve or deny the proof given depending on if the worker has done what is required. \n <br />
<br />
Please note if you mark a workers proof as unexceptable when the proof is what is required your account will be deleted and IP banned.<br />
<br />
If you have any problems dont hesitate to contact us by using the report feature on the My Account page or through forums.";
// now insert message into database
$sql2 = "INSERT INTO messages SET `to` = '".$to."', `title` = '".$title."', `message` = '".$message."', `created` = NOW()";
$result = mysql_query($sql2)
or die('Invalid query: ' . $sql2 . ' - Error is ' . mysql_error());
// run process, update values in the database.
$sql = "SELECT `fulldata`.*
FROM `fulldata`
WHERE fulldata.job_id = $job_id";
$result = mysql_query($sql)
or die('Invalid query: ' . $sql . ' - Error is ' . mysql_error());
$sql = "UPDATE `fulldata`
SET amountworkers = amountworkers - 1
WHERE fulldata.job_id = $job_id";
$result = mysql_query($sql)
or die('Invalid query: ' . $sql . ' - Error is ' . mysql_error());
$sql = "UPDATE `fulldata`
SET amountcomplete = amountcomplete + 1
WHERE fulldata.job_id = $job_id";
$result = mysql_query($sql)
or die('Invalid query: ' . $sql . ' - Error is ' . mysql_error());
// is the job complete now?
$workers = mysql_real_escape_string($_POST['amountworkers']);
if ($workers == 1)
{
$sql = "UPDATE `fulldata`
SET completedjob = 1
WHERE fulldata.job_id = $job_id";
$result = mysql_query($sql)
or die('Invalid query: ' . $sql . ' - Error is ' . mysql_error());
}
// if successfully insert data into database, displays message "Successful".
if($result){
echo "Your proof has now been sent to the employer, When approved you will recieve money.";
echo "<BR>";
echo "<a href='/jobs.php'>Click here to go back to miniworkers</a>";
echo "$workers";
}
else {
echo "ERROR";
}
}
?>
Now for the vulnrabilities i need help fixing in this script.
1) SQLi: There are about 200+ different types input not just using (JyI%3D) of SQLi what can be used on this script here are the variables effected though:
The POST variable userproof_id has been set to JyI%3D.
The POST variable amountworkers has been set to JyI%3D.
The POST variable proof has been set to JyI%3D.
The POST variable Id has been set to %00'. (Where is Id =/)
The POST variable job_id has been set to '.
The POST variable createuser_id2 has been set to '.
So I presume my function fails horribly to clean the data? mysql_real_escape_string should be used maybe?
2)SQLi Cookies:
The Cookie variable user_name has been set to %00'. (A cookie i created)
The Cookie variable __utmc has been set to %2527. (Not my cookie i think its forum cookie)
The Cookie variable phpbb3_q529l_k has been set to %00'. (Not my cookie i think its forum cookie)
Need some guidence on this as i dont even know how cookie manipulation can be prevented.
3) SQLi Headers:
The HTTP header referer has been set to \'.
The HTTP header user-agent has been set to '.
The HTTP header x-forwarded-for has been set to '.
The HTTP header accept-language has been set to \".
There is more but you get the drift, how can i prevent a SQLi from injecting the headers? This sounds like the worst one.
Thats the exploits!(you will be glad if your reading)
Im not asking for my script to be rewritten by you, I just care about the security and would like the knowledge to fix these security issues.