Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I want to reward users if they refer a friend. I've been using the following code to do it, but I'm worried that it might not be secure (users make fake accounts to game it). Can I improve this code? Are there any other alternative scripts that do this better?

if (isset($_GET['refer']) || isset($_GET['r'])) {
global $database, $session;
    if (!$session->logged_in) {
        $username = mysql_safe($_GET['refer']);
        if($database->usernameTaken($username)) {
            $userip= getRealIP();

            $q="SELECT uname FROM " . TBL_USERS . " WHERE ipad = '$userip'";
                $result=mysql_query($q, $database->connection);
                $result = mysql_numrows($result);      

            if ($result == 0) {
                $_SESSION['referer'] = $username;

            }
        }
    }

    function getRealIP()
{
    if (!empty($_SERVER['HTTP_CLIENT_IP']))   //check ip from share internet
    {
      $ip=$_SERVER['HTTP_CLIENT_IP'];
    }
    elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))   //to check ip is pass from proxy
    {
      $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    else
    {
      $ip=$_SERVER['REMOTE_ADDR'];
    }
    return $ip;
}
share|improve this question
You can start by using mysqli or PDO instead of mysql_* to stay clear of sql injections – Tifa 22 hours ago
What approach did you used to generate referral link? Was it generated with a kind of random token or something? If it is random token generated, then you should be ok because, a referral link (token) must match to the one that exist on your database. It's almost impossible for people to guess the right referral token to match the one in your database otherwise, it'll be rejected. – Faron 22 hours ago
I use their username. ?refer=username – user2418168 22 hours ago
I hope mysql_safe isn't a custom attempt at doing mysql_real_escape_string's job. – Philip Whitehouse 22 hours ago
One thing to note: even though you are using a set of ways to return and IP address, users who are behind a NAT may still return the same IP. Say everyone in a particular company started referring each other. Same IP, but you'd probably never give any credit. I've seen code where there was a combination approach: IP address, User Agent (this CAN vary among users, but not always), Cookies, and throttling (Ie, chances are it doesn't take off SO Fast, so credit is only awareded if each request is say more than 5 mins apart). In general, its very difficult to stop users from gaming. :-/ – Aaron Saray 22 hours ago
show 2 more comments

1 Answer

It depends on what level of abuse you're expecting.

Non-technically:

Are rewards transferable, are they tangible or not? Can I just create a bunch of acounts, then use ALL of them to refer a bunch of other accounts, and reap rewards on my fake accounts and send them to my main? If I create 20 accounts, and use each to refer once, do I wind up with 20x the rewards (spread across my fake accounts).

I can create fake accounts and log in from different places, easily.

Options: make it harder to claim the reward. If the user just has to create an account, it's trivial. If they have to log in and then do X, Y, and Z, it's harder to do, and you'll see less fakes.

Technically:

First off: you're relying on headers for IPs (X_FORWARDED_FOR, etc.) which can be spoofed, fairly easily. So if you're trying to limit it to one-per-IP, this is one flaw.

Second, while you're sanitizing the username, it appears, you do not appear to be sanitizing the IP before using it in a query. If you're going to do manual sanitization, do it consistently, or you have gaping holes. In this case, you can spoof the IP string - I don't know what PHP will do with a bogus string, but if it doesn't barf on it, you're asking for attacks.

Thirdly: I can come from an array of sites. If I hard reset my DSL, I get a new IP most of the time. I can log in from work. I can log in from my webserver box. All have unique IPs. I can find proxies which may or may not actually set those fields.

You can look at other identification. Simplest: cookies. Crazily more complex: things like this: https://panopticlick.eff.org/index.php?action=log&js=yes

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.