Cross-site request forgery defense for code to count Likes I have the following code which is supposed to insert a row into a DB table "clicks" (consisting of 1 Primary AI column "id" and another column "user" which contains the user's session ID) upon clicking the Like button. For each user assuming they have a session ID set from a login I would like to return to them their most recently inserted ID from the table. So the first time the button is clicked it will return 1 etc. I would like this to be accessible to multiple users through a login system.

Is this vulnerable to Cross-site request forgery and if so, how can I alter the code to defend against it?

index.php:

&lt;?php
include 'init.php';
include 'connect.php';
?&gt;
&lt;!doctype html&gt;
&lt;html&gt;
&lt;body&gt;
    &lt;?php       
    $userid = $_SESSION['user_id'];
   echo '&lt;a class="like" href="#" onclick="like_add(', $userid,   
  ');"&gt;Like&lt;/a&gt;';
    ?&gt;
    &lt;script type ="text/javascript" src="jquery-1.11.1.min.js"&gt;&lt;/script&gt;
    &lt;script type ="text/javascript" src="like.js"&gt;&lt;/script&gt;      
&lt;/body&gt;
&lt;/html&gt;


connect.php

&lt;?php  
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "DB";
$conn = new mysqli($servername, $username, $password, $dbname);

if ($conn-&gt;connect_error) {
die("Connection failed: " . $conn-&gt;connect_error);
}
?&gt;


init.php

&lt;?php
session_start();
$_SESSION['user_id']='1';
$userid = $_SESSION['user_id'];
include 'connect.php';
include 'like.php';
?&gt;


like.js

function like_add(userid) {
$.post('like_add.php', {userid:userid}, function(data) {
   if (data == 'success'){
    add_like($userid);
   } else{
       alert(data);
   }
});
}


like.php

&lt;?php
function add_like($userid){
include 'connect.php';

$stmt = $conn-&gt;prepare("INSERT INTO clicks (user) VALUES (?)");
$stmt-&gt;bind_param("s", $userid);

$stmt-&gt;execute();
$stmt = $conn-&gt;prepare("SELECT max(id) FROM clicks WHERE user=?");
$stmt-&gt;bind_param("s", $userid);
$stmt-&gt;execute();
$stmt-&gt;bind_result($click);
$stmt-&gt;fetch();
echo $click;
$stmt-&gt;close();
}
?&gt;


like_add.php

&lt;?php
include 'init.php';
if (isset($userid)) {
$userid = $userid;
add_like($userid);
}
?&gt;
Defending agains CSRF offens happens by creating a token that can only be used once by the client that requested it. For proper protection, that token should ofcourse be linked to a form.

A simple one could be to add a md5 hash or similar to all your forms, store that hash somewhere. And then when the user submits, check or the hash is valid. Depending on the requirements, you can also add a Time to live to the hash (e.g. did it take more then 30minutes to submit the form?)

In your case, it is not a form, but a request being send to the server. Simply adding a token to that request (and validating it) would help you protect agains CSRF atacks.