Go Back   CodingForums.com > :: Server side development > PHP

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 10-13-2011, 04:33 PM   PM User | #1
Psionicsin
Regular Coder

 
Psionicsin's Avatar
 
Join Date: Aug 2010
Location: Ann Arbor, Michigan
Posts: 334
Thanks: 51
Thanked 0 Times in 0 Posts
Psionicsin is an unknown quantity at this point
HELP: Direct PHP/MySQL Link Flaw

I'm not sure this is MySQL injection from what I see, but here's the scenario.

We have a contest that runs on our site. A cousin of one of the contestants posted a link, from his browser after he'd voted, in a forum to have other people go vote for her.

The problem, however, is that he posted the url to the vote result page that still had the contestants info in it. So instead of directing people to the site for them to vote for themselves, this caused anyone who clicked the link to automatically vote for here against their will.

This was the posted link (ALTERED OBVIOUSLY LOL):
Code:
http://www.our-url.com/sencha-tallyvote.php?sen_id=705
Now I can't go about re-writing the entire code as I didn't create it, it would take vast amounts of time for me, and we're still in the middle of the contest.

However can anyone aid me in adding something into these php files that will protect against things like this? Or is it unavoidable?

Here is the file that I think needs altering, although if this is not it, please let me know and I can gather the required info ASAP.

tally.php:
PHP Code:
<?php
require_once('./templates/mysql_connect.php');

/////////////
function escape_data ($data)
{
    global 
$dbc;
    
    if(
ini_get('magic_quotes_gpc'))
    
$data stripslashes($data);
    
    return 
mysql_real_escape_string($data$dbc);    
}
////////////

$ip=$_SERVER['REMOTE_ADDR'];

$queryIP "SELECT INET_NTOA('ip') FROM ips WHERE ip=INET_ATON('$ip')";
$resultIP mysql_query ($queryIP);
$existIP mysql_num_rows($resultIP);


if (isset(
$_COOKIE['vote']) || $existIP 0)
{
    
$message "<b>You have already voted in this year's Senior Challenge!</b> <p>To view the rankings of the current Senior Challenge contestants, <a href=\"/voteresults.php\">click here</a></p>";
}
else
{
    
//Get Senior info
    
$query "SELECT * FROM seniors WHERE sen_id=$_GET[sen_id]";
    
$result mysql_query ($query);
    
$row mysql_fetch_array ($result);

    
//Tally vote
    
$votes $row['votes'] + 1;
    
$queryTally "UPDATE seniors SET votes='$votes' WHERE sen_id=$_GET[sen_id] LIMIT 1";
    
$resultTally mysql_query ($queryTally);
    
    if(isset(
$resultTally))
    {
        
$message "<b>Your vote has been registered!</b>  <p>Thank you for participating in the 2012 Senior Challenge.  To view the rankings of the current Senior Challenge contestants, <a href=\"/sencha-top10.php\">click here</a></p>";
        
        
//Set cookie + ip
    
setcookie ("vote""yes"time()+15552000);
    
$queryInsertIP "INSERT INTO ips (ip, person) VALUES(INET_ATON('$ip'), '$row[last_name]')";
    
$resultInsertIP mysql_query ($queryInsertIP);

    }
    else
    {
        
$message "<b>Error:  Vote was not counted!</b>  <p>You have encountered an error, and your vote was NOT tallied.  Please, <a href=\"/contact.html\">contact us</a> to tally your vote.</p>";
    }
}

?>

<?php 
$page_title 
'Ruth Olson Photography - Vote Result';
$query "SELECT * FROM seniors WHERE sen_id=$_GET[sen_id]";
$result mysql_query ($query);
$row mysql_fetch_array ($result);

?>

<h3><?php echo $row['first_name'], " "$row['last_name'], " has <font style=\"color:#FF0000\">
$row[votes]</font> votes"
;?></h3>

<?php echo "<p>"$message"</p>"?>

<br />
<h3>Invite people to vote!</h3>
<p>Increase <?php echo $row['first_name']?>'s chances of winning the Senior Challenge by inviting friends and family to vote!</p> 
<form action ="<?PHP echo $_SERVER['PHP_SELF']; ?>?sen_id=<?php echo $row['sen_id']; ?>" method="post">
<p>E-mail address: <input name="addy" type="text" size="30" maxlength="50" ></p>
<input name="mail" type="submit" value="Send">
</form> 

<?php 
//Email!

if (isset($_POST['mail']))
{
    if (empty(
$_POST['addy']))
    {
        
$e FALSE;
        
$Pmessage .= '<p>Please enter the e-mail address...</p>';
    }
    
        else if(!
eregi("^[[:alnum:]][a-z0-9_.-]*@[a-z0-9.-]+\.[a-z]{2,4}$"stripslashes(trim($_POST['addy']))))
            {
                    
$problem FALSE;
                    
$Pmessage .= '<p>Please enter a valid e-mail address.</p>';
            }
            
    else
    
$e escape_data($_POST['addy']);
    
    if (
$e)
    {
    
    
//Send an e-mail
            
$to "$e";
            
$subject "Vote for $row[first_name] $row[last_name] in the Ruth Olson Photography Senior Challenge!";
            
$message "Hello,

$row[first_name] $row[last_name] is a contestant in the Ruth Olson Photography Senior Challenge.  $row[first_name] currently has $row[votes] votes, but every new vote counts!

If you would like to vote for $row[first_name], follow the link below...

http://www.rutholsonphoto.com/sencha-vote-af.php

Thank you,
Ruth Olson Photography"
;
            
$from "Senior Challenge@rutholsonphoto.com";
            
$headers "From: $from";
            
mail($to,$subject,$message,$headers);
            
            echo 
"<br />The e-mail has been sent successfully!";
                        }
                        
                        else
                            echo 
$Pmessage;
                    }    
?>

Last edited by Psionicsin; 10-13-2011 at 07:42 PM..
Psionicsin is offline   Reply With Quote
Old 10-13-2011, 05:49 PM   PM User | #2
myfayt
Senior Coder

 
Join Date: Apr 2010
Posts: 1,156
Thanks: 46
Thanked 95 Times in 94 Posts
myfayt can only hope to improve
If you do a url rewrite, you can hide the value, so the link won't work. Making it be http://www.our-url.com/sencha-tallyvote.php

http://www.cyberdesignz.com/blog/web...url-rewriting/
__________________
Been a sign maker for 5 years. My business:
American Made Signs
myfayt is offline   Reply With Quote
Old 10-13-2011, 06:25 PM   PM User | #3
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,635
Thanks: 4
Thanked 2,448 Times in 2,417 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
There is no 'flaw' in this (from the problem stance anyway). The problem is you're relying on the GET which has been passed as a part of the hard url. Rewrite the code to use POST instead, and it won't matter if a querystring is provided to it.
If you cannot rewrite it, you're out of luck. URL Rewriting cannot be done to fix this. If the value is stripped out of it, then it will never process it either. In either case, the code was not written properly to handle input in any way; providing it with nothing in the querystring would still attempt to update that non-existent entry.
Fou-Lu is offline   Reply With Quote
Old 10-13-2011, 06:27 PM   PM User | #4
Psionicsin
Regular Coder

 
Psionicsin's Avatar
 
Join Date: Aug 2010
Location: Ann Arbor, Michigan
Posts: 334
Thanks: 51
Thanked 0 Times in 0 Posts
Psionicsin is an unknown quantity at this point
Quote:
Originally Posted by Fou-Lu View Post
There is no 'flaw' in this (from the problem stance anyway). The problem is you're relying on the GET which has been passed as a part of the hard url. Rewrite the code to use POST instead, and it won't matter if a querystring is provided to it.
If you cannot rewrite it, you're out of luck. URL Rewriting cannot be done to fix this. If the value is stripped out of it, then it will never process it either. In either case, the code was not written properly to handle input in any way; providing it with nothing in the querystring would still attempt to update that non-existent entry.
Is that as simple as changing get to post, or is it more complicated than that? A year later and I'm still struggling to understand what this guys did.
Psionicsin is offline   Reply With Quote
Old 10-13-2011, 06:45 PM   PM User | #5
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,635
Thanks: 4
Thanked 2,448 Times in 2,417 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
To make it workable, _POST would have to be used instead of _GET, the form would need to be modified to use POST instead of GET or implicit method, and the action would have to drop the querystring added and use a hidden submit field instead.
The actual processing should be modified to only deal with it if $_POST['sen_id'] isset. Although if it doesn't, it will simply throw errors (which it currently does now if now sen_id isn't provided, but must not be configured to show).
I see that there are two processing blocks though, one for voting and one for mailing. Is there a different form that's actually used prior to this one?
Fou-Lu is offline   Reply With Quote
Old 10-13-2011, 07:28 PM   PM User | #6
myfayt
Senior Coder

 
Join Date: Apr 2010
Posts: 1,156
Thanks: 46
Thanked 95 Times in 94 Posts
myfayt can only hope to improve
I believe what Fou Lu is saying is when you convert it to POST, you are using only the file name with no added extension.

So picture this, you have a vote page with four names on it, each has a radio button next to it, it only allows you to select one of them.

Then you hit the submit button and it updates the query and posts the results.

So http://www.our-url.com/sencha-tallyvote.php
stays http://www.our-url.com/sencha-tallyvote.php.

Then no one can manually link to or type in an id.

That what you mean Fou?
__________________
Been a sign maker for 5 years. My business:
American Made Signs
myfayt is offline   Reply With Quote
Old 10-13-2011, 07:33 PM   PM User | #7
Psionicsin
Regular Coder

 
Psionicsin's Avatar
 
Join Date: Aug 2010
Location: Ann Arbor, Michigan
Posts: 334
Thanks: 51
Thanked 0 Times in 0 Posts
Psionicsin is an unknown quantity at this point
Quote:
Originally Posted by Fou-Lu View Post
To make it workable, _POST would have to be used instead of _GET, the form would need to be modified to use POST instead of GET or implicit method, and the action would have to drop the querystring added and use a hidden submit field instead.
The actual processing should be modified to only deal with it if $_POST['sen_id'] isset. Although if it doesn't, it will simply throw errors (which it currently does now if now sen_id isn't provided, but must not be configured to show).
I see that there are two processing blocks though, one for voting and one for mailing. Is there a different form that's actually used prior to this one?
Yes. We have the actual voting pages which after a vote is placed, they are directed to the tally page. Code down below.


1 out of the 5 voting pages (pulls specific groups of the alphabet)
:
PHP Code:
<div id="sencha">

<h3>2012 Senior Challenge Contestants</h3>
<br />

<p><span id="strong">Senior Challenge Leaderboard:</span> <a href="./sencha-top10.php">Click here to view the current Top 10!</a><br /><br />
To build suspense we have removed the voting counters. Keep up the voting!<br />
We allow one vote per household.</p><br />

<div class="section-1">
<ul id="menu2">
    <li id="nav-1"><a href="sencha-vote-af.php"><u>A - F</u></a></li>
    <li id="nav-2"><a href="sencha-vote-gl.php"><u>G - L</u></a></li>
    <li id="nav-3"><a href="sencha-vote-mr.php"><u>M - R</u></a></li>
    <li id="nav-4"><a href="sencha-vote-sx.php"><u>S - X</u></a></li>
    <li id="nav-5"><a href="sencha-vote-yz.php"><u>Y - Z</u></a></li>
</ul>


<div id="query">

<?php

include("./templates/mysql_connect.php");

 
//FOR LETTER: A

$query "SELECT * FROM seniors WHERE last_name LIKE 'A%' ORDER BY last_name ASC";
$result = @mysql_query ($query);

echo 
'<table><tr>
  <td>
  <p><span class="style19"><u>-A-</u></span><br />'
;

while (
$row mysql_fetch_array ($result)){
        
        echo 
"<a href=\"$row[pic_url]\" rel=\"lightbox[seniors]\" 
title=\" &lt;form action =&quot;/sencha-tallyvote.php?sen_id=$row[sen_id]&quot; method=&quot;post&quot;&gt;

$row[first_name] $row[last_name] - $row[school] <br />

 &nbsp; &nbsp; &lt;input name=&quot;submit&quot; align=&quot;right&quot; type=&quot;submit&quot; value=&quot;Vote&quot; &gt;  
 
 &lt;/form&gt; \">$row[last_name], $row[first_name]</a><br/>"
;
        
    }
echo 
'</p>';
?>

<?php
 
//FOR LETTER: B

$query "SELECT * FROM seniors WHERE last_name LIKE 'B%' ORDER BY last_name ASC";
$result = @mysql_query ($query);

echo 
'<td><p><span class="style19"><u>-B-</u></span><br />';

while (
$row mysql_fetch_array ($result)){
        
        echo 
"<a href=\"$row[pic_url]\" rel=\"lightbox[seniors]\" 
title=\" &lt;form action =&quot;/sencha-tallyvote.php?sen_id=$row[sen_id]&quot; method=&quot;post&quot;&gt;

$row[first_name] $row[last_name] - $row[school]

 &nbsp; &nbsp; &lt;input name=&quot;submit&quot; type=&quot;submit&quot; value=&quot;Vote&quot; &gt;  
 
 &lt;/form&gt; \">$row[last_name], $row[first_name]</a><br/>"
;
        
    }
echo 
'</p></td>';
?>

<?php
 
//FOR LETTER: C

$query "SELECT * FROM seniors WHERE last_name LIKE 'C%' ORDER BY last_name ASC";
$result = @mysql_query ($query);

echo 
'<td><p><span class="style19"><u>-C-</u></span><br />';

while (
$row mysql_fetch_array ($result)){
        
        echo 
"<a href=\"$row[pic_url]\" rel=\"lightbox[seniors]\" 
title=\" &lt;form action =&quot;/sencha-tallyvote.php?sen_id=$row[sen_id]&quot; method=&quot;post&quot;&gt;

$row[first_name] $row[last_name] - $row[school]

 &nbsp; &nbsp; &lt;input name=&quot;submit&quot; type=&quot;submit&quot; value=&quot;Vote&quot; &gt;  
 
 &lt;/form&gt; \">$row[last_name], $row[first_name]</a><br/>"
;
        
    }
echo 
'</p></td></tr>';
?>

<?php
 
//FOR LETTER: D

$query "SELECT * FROM seniors WHERE last_name LIKE 'D%' ORDER BY last_name ASC";
$result = @mysql_query ($query);

echo 
'<tr><td><p><span class="style19"><u>-D-</u></span><br />';

while (
$row mysql_fetch_array ($result)){
        
        echo 
"<a href=\"$row[pic_url]\" rel=\"lightbox[seniors]\" 
title=\" &lt;form action =&quot;/sencha-tallyvote.php?sen_id=$row[sen_id]&quot; method=&quot;post&quot;&gt;

$row[first_name] $row[last_name] - $row[school]

 &nbsp; &nbsp; &lt;input name=&quot;submit&quot; type=&quot;submit&quot; value=&quot;Vote&quot; &gt;  
 
 &lt;/form&gt; \">$row[last_name], $row[first_name]</a><br/>"
;
        
    }
echo 
'</p></td>';
?>

<?php
 
//FOR LETTER: E

$query "SELECT * FROM seniors WHERE last_name LIKE 'E%' ORDER BY last_name ASC";
$result = @mysql_query ($query);

echo 
'<td><p><span class="style19"><u>-E-</u></span><br />';

while (
$row mysql_fetch_array ($result)){
        
        echo 
"<a href=\"$row[pic_url]\" rel=\"lightbox[seniors]\" 
title=\" &lt;form action =&quot;/sencha-tallyvote.php?sen_id=$row[sen_id]&quot; method=&quot;post&quot;&gt;

$row[first_name] $row[last_name] - $row[school]

 &nbsp; &nbsp; &lt;input name=&quot;submit&quot; type=&quot;submit&quot; value=&quot;Vote&quot; &gt;  
 
 &lt;/form&gt; \">$row[last_name], $row[first_name]</a><br/>"
;
        
    }
echo 
'</p></td>';
?>

<?php
 
//FOR LETTER: F

$query "SELECT * FROM seniors WHERE last_name LIKE 'F%' ORDER BY last_name ASC";
$result = @mysql_query ($query);

echo 
'<td><p><span class="style19"><u>-F-</u></span><br />';

while (
$row mysql_fetch_array ($result)){
        
        echo 
"<a href=\"$row[pic_url]\" rel=\"lightbox[seniors]\" 
title=\" &lt;form action =&quot;/sencha-tallyvote.php?sen_id=$row[sen_id]&quot; method=&quot;post&quot;&gt;

$row[first_name] $row[last_name] - $row[school]

 &nbsp; &nbsp; &lt;input name=&quot;submit&quot; type=&quot;submit&quot; value=&quot;Vote&quot; &gt;  
 
 &lt;/form&gt; \">$row[last_name], $row[first_name]</a><br/>"
;
        
    }
echo 
'</p></td></tr>';
?>

</table>

</div>
</div>
</div>
...and the tally page:
PHP Code:
<?php
require_once('./templates/mysql_connect.php');

/////////////
function escape_data ($data)
{
    global 
$dbc;
    
    if(
ini_get('magic_quotes_gpc'))
    
$data stripslashes($data);
    
    return 
mysql_real_escape_string($data$dbc);    
}
////////////

$ip=$_SERVER['REMOTE_ADDR'];

$queryIP "SELECT INET_NTOA('ip') FROM ips WHERE ip=INET_ATON('$ip')";
$resultIP mysql_query ($queryIP);
$existIP mysql_num_rows($resultIP);


if (isset(
$_COOKIE['vote']) || $existIP 0)
{
    
$message "<b>You have already voted in this year's Senior Challenge!</b> <p>To view the rankings of the current Senior Challenge contestants, <a href=\"/voteresults.php\">click here</a></p>";
}
else
{
    
//Get Senior info
    
$query "SELECT * FROM seniors WHERE sen_id=$_GET[sen_id]";
    
$result mysql_query ($query);
    
$row mysql_fetch_array ($result);

    
//Tally vote
    
$votes $row['votes'] + 1;
    
$queryTally "UPDATE seniors SET votes='$votes' WHERE sen_id=$_GET[sen_id] LIMIT 1";
    
$resultTally mysql_query ($queryTally);
    
    if(isset(
$resultTally))
    {
        
$message "<b>Your vote has been registered!</b>  <p>Thank you for participating in the 2012 Senior Challenge.  To view the rankings of the current Senior Challenge contestants, <a href=\"/sencha-top10.php\">click here</a></p>";
        
        
//Set cookie + ip
    
setcookie ("vote""yes"time()+15552000);
    
$queryInsertIP "INSERT INTO ips (ip, person) VALUES(INET_ATON('$ip'), '$row[last_name]')";
    
$resultInsertIP mysql_query ($queryInsertIP);

    }
    else
    {
        
$message "<b>Error:  Vote was not counted!</b>  <p>You have encountered an error, and your vote was NOT tallied.  Please, <a href=\"/contact.html\">contact us</a> to tally your vote.</p>";
    }
}

?>

<?php 
$page_title 
'Ruth Olson Photography - Vote Result';
$query "SELECT * FROM seniors WHERE sen_id=$_GET[sen_id]";
$result mysql_query ($query);
$row mysql_fetch_array ($result);

?>

<h3><?php echo $row['first_name'], " "$row['last_name'], " has <font style=\"color:#FF0000\">
$row[votes]</font> votes"
;?></h3>

<?php echo "<p>"$message"</p>"?>

<br />
<h3>Invite people to vote!</h3>
<p>Increase <?php echo $row['first_name']?>'s chances of winning the Senior Challenge by inviting friends and family to vote!</p> 
<form action ="<?PHP echo $_SERVER['PHP_SELF']; ?>?sen_id=<?php echo $row['sen_id']; ?>" method="post">
<p>E-mail address: <input name="addy" type="text" size="30" maxlength="50" ></p>
<input name="mail" type="submit" value="Send">
</form> 

<?php 
//Email!

if (isset($_POST['mail']))
{
    if (empty(
$_POST['addy']))
    {
        
$e FALSE;
        
$Pmessage .= '<p>Please enter the e-mail address...</p>';
    }
    
        else if(!
eregi("^[[:alnum:]][a-z0-9_.-]*@[a-z0-9.-]+\.[a-z]{2,4}$"stripslashes(trim($_POST['addy']))))
            {
                    
$problem FALSE;
                    
$Pmessage .= '<p>Please enter a valid e-mail address.</p>';
            }
            
    else
    
$e escape_data($_POST['addy']);
    
    if (
$e)
    {
    
    
//Send an e-mail
            
$to "$e";
            
$subject "Vote for $row[first_name] $row[last_name] in the Ruth Olson Photography Senior Challenge!";
            
$message "Hello,

$row[first_name] $row[last_name] is a contestant in the Ruth Olson Photography Senior Challenge.  $row[first_name] currently has $row[votes] votes, but every new vote counts!

If you would like to vote for $row[first_name], follow the link below...

http://www.rutholsonphoto.com/sencha-vote-af.php

Thank you,
Ruth Olson Photography"
;
            
$from "Senior Challenge@rutholsonphoto.com";
            
$headers "From: $from";
            
mail($to,$subject,$message,$headers);
            
            echo 
"<br />The e-mail has been sent successfully!";
                        }
                        
                        else
                            echo 
$Pmessage;
                    }    
?>
If you could heavily assist me in this, I'd be so appreciative.

Last edited by Psionicsin; 10-13-2011 at 07:37 PM..
Psionicsin is offline   Reply With Quote
Old 10-13-2011, 07:44 PM   PM User | #8
Psionicsin
Regular Coder

 
Psionicsin's Avatar
 
Join Date: Aug 2010
Location: Ann Arbor, Michigan
Posts: 334
Thanks: 51
Thanked 0 Times in 0 Posts
Psionicsin is an unknown quantity at this point
Quote:
Originally Posted by myfayt View Post
I believe what Fou Lu is saying is when you convert it to POST, you are using only the file name with no added extension.

So picture this, you have a vote page with four names on it, each has a radio button next to it, it only allows you to select one of them.

Then you hit the submit button and it updates the query and posts the results.

So http://www.our-url.com/sencha-tallyvote.php
stays http://www.our-url.com/sencha-tallyvote.php.

Then no one can manually link to or type in an id.

That what you mean Fou?
Thanks for that . I get what he's saying. It's just that since I don't know a lot about PHP coding and that guys hasn't been here for the past 2-3 years...I have no clue how to go about changing it lol. So I have no idea what exactly needs to get changed to POST and what needs to stay and what needs to be deleted.

Last edited by Psionicsin; 10-13-2011 at 07:46 PM..
Psionicsin is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 04:59 AM.


Advertisement
Log in to turn off these ads.