diff --git a/api.php b/api.php
index b3bdabb..b33c18c 100644
--- a/api.php
+++ b/api.php
@@ -14,6 +14,9 @@
include("session_verif.php");
include("bdd.php");
+ include('php-csrf.php');
+ $csrf = new CSRF();
+
// Get the requested URL
$request_uri = $_SERVER['REQUEST_URI'];
@@ -177,8 +180,16 @@
if($_SERVER['REQUEST_METHOD'] === 'POST'){
verifier_session();
+
switch(array_pop($url_parts)){
case "aj_doc":
+
+
+ if(!$csrf->validate($context='televersement',$_POST["jeton-csrf"])){
+ echo( json_encode(["status"=> "2","msg"=>"jeton csrf manquant.".$_POST["jeton-csrf"]]) );
+ break;
+ }
+
try{
ajouter_doc($_POST);
@@ -188,6 +199,11 @@
break;
case "valider_ensemble":
+
+ if(!$csrf->validate($context='valider_ensemble',$_POST["jeton-csrf"])){
+ echo( json_encode(["status"=> "2","msg"=>"jeton csrf manquant.".$_POST["jeton-csrf"]]) );
+ break;
+ }
try{
valider_ensemble($_POST["ensemble_id"]);
echo(json_encode(["status"=>"1","msg"=>"Ensemble validé."]));
@@ -197,6 +213,12 @@
break;
case "supprimer_ensemble":
+
+ if(!$csrf->validate($context='supprimer_ensemble',$_POST["jeton-csrf"])){
+ echo( json_encode(["status"=> "2","msg"=>"jeton csrf manquant." ]) );
+ break;
+ }
+
try{
supprimer_ensemble($_POST["ensemble_id"]);
echo(json_encode(["status"=>"1","msg"=>"Ensemble supprimé."]));
diff --git a/index.php b/index.php
index 84d5770..5e9d48e 100644
--- a/index.php
+++ b/index.php
@@ -8,6 +8,7 @@
diff --git a/php-csrf.php b/php-csrf.php
new file mode 100644
index 0000000..940c8b4
--- /dev/null
+++ b/php-csrf.php
@@ -0,0 +1,340 @@
+,
+ *
+ * );
+ * // Generate an input for a form with a token
+ * // Tokens on the list are binded on a group so that
+ * // they can only be matched on that group
+ * // You can use as a group name the form name
+ * echo $csrf_tokens->input();
+ */
+class CSRF {
+
+ private $name;
+ private $hashes;
+ private $hashTime2Live;
+ private $hashSize;
+ private $inputName;
+
+ /**
+ * Initialize a CSRF instance
+ * @param string $session_name Session name
+ * @param string $input_name Form name
+ * @param integer $hashTime2Live Default seconds hash before expiration
+ * @param integer $hashSize Default hash size in chars
+ */
+ function __construct ($session_name='csrf-lib', $input_name='key-awesome', $hashTime2Live=0, $hashSize=64) {
+ // Session mods
+ $this->name = $session_name;
+ // Form input name
+ $this->inputName = $input_name;
+ // Default time before expire for hashes
+ $this->hashTime2Live = $hashTime2Live;
+ // Default hash size
+ $this->hashSize = $hashSize;
+ // Load hash list
+ $this->_load();
+ }
+
+ /**
+ * Generate a CSRF_Hash
+ * @param string $context Name of the form
+ * @param integer $time2Live Seconds before expiration
+ * @param integer $max_hashes Clear old context hashes if more than this number
+ * @return CSRF_Hash
+ */
+ private function generateHash ($context='', $time2Live=-1, $max_hashes=5) {
+ // If no time2live (or invalid) use default
+ if ($time2Live < 0) $time2Live = $this->hashTime2Live;
+ // Generate new hash
+ $hash = new CSRF_Hash($context, $time2Live, $this->hashSize);
+ // Save it
+ array_push($this->hashes, $hash);
+ if ($this->clearHashes($context, $max_hashes) === 0) {
+ $this->_save();
+ }
+
+ // Return hash info
+ return $hash;
+ }
+
+ /**
+ * Get the hashes of a context
+ * @param string $context the group to clean
+ * @param integer $max_hashes max hashes to get
+ * @return array array of hashes as strings
+ */
+ public function getHashes ($context='', $max_hashes=-1) {
+ $len = count($this->hashes);
+ $hashes = array();
+ // Check in the hash list
+ for ($i = $len - 1; $i >= 0 && $len > 0; $i--) {
+ if ($this->hashes[$i]->inContext($context)) {
+ array_push($hashes, $this->hashes[$i]->get());
+ $len--;
+ }
+ }
+ return $hashes;
+ }
+
+ /**
+ * Clear the hashes of a context
+ * @param string $context the group to clean
+ * @param integer $max_hashes ignore first x hashes
+ * @return integer number of deleted hashes
+ */
+ public function clearHashes ($context='', $max_hashes=0) {
+ $ignore = $max_hashes;
+ $deleted = 0;
+ // Check in the hash list
+ for ($i = count($this->hashes) - 1; $i >= 0; $i--) {
+ if ($this->hashes[$i]->inContext($context) && $ignore-- <= 0) {
+ array_splice($this->hashes, $i, 1);
+ $deleted++;
+ }
+ }
+ if ($deleted > 0) {
+ $this->_save();
+ }
+ return $deleted;
+ }
+
+ /**
+ * Generate an input html element
+ * @param string $context Name of the form
+ * @param integer $time2Live Seconds before expire
+ * @param integer $max_hashes Clear old context hashes if more than this number
+ * @return integer html input element code as a string
+ */
+ public function input ($context='', $time2Live=-1, $max_hashes=5) {
+ // Generate hash
+ $hash = $this->generateHash ($context, $time2Live, $max_hashes);
+ // Generate html input string
+ return '';
+ }
+
+ /**
+ * Generate a script html element with the hash variable
+ * @param string $context Name of the form
+ * @param string $name The name for the variable
+ * @param integer $time2Live Seconds before expire
+ * @param integer $max_hashes Clear old context hashes if more than this number
+ * @return integer html script element code as a string
+ */
+ public function script ($context='', $name='', $declaration='var', $time2Live=-1, $max_hashes=5) {
+ // Generate hash
+ $hash = $this->generateHash ($context, $time2Live, $max_hashes);
+ // Variable name
+ if (strlen($name) === 0) {
+ $name = $this->inputName;
+ }
+ // Generate html input string
+ return '';
+ }
+
+ /**
+ * Generate a javascript variable with the hash
+ * @param string $context Name of the form
+ * @param string $name The name for the variable
+ * @param integer $time2Live Seconds before expire
+ * @param integer $max_hashes Clear old context hashes if more than this number
+ * @return integer html script element code as a string
+ */
+ public function javascript ($context='', $name='', $declaration='var', $time2Live=-1, $max_hashes=5) {
+ // Generate hash
+ $hash = $this->generateHash ($context, $time2Live, $max_hashes);
+ // Variable name
+ if (strlen($name) === 0) {
+ $name = $this->inputName;
+ }
+ // Generate html input string
+ return $declaration . ' ' . $name . ' = ' . json_encode($hash->get()) . ';';
+ }
+
+ /**
+ * Generate a string hash
+ * @param string $context Name of the form
+ * @param integer $time2Live Seconds before expire
+ * @param integer $max_hashes Clear old context hashes if more than this number
+ * @return integer hash as a string
+ */
+ public function string ($context='', $time2Live=-1, $max_hashes=5) {
+ // Generate hash
+ $hash = $this->generateHash ($context, $time2Live, $max_hashes);
+ // Generate html input string
+ return $hash->get();
+ }
+
+ /**
+ * Validate by context
+ * @param string $context Name of the form
+ * @return boolean Valid or not
+ */
+ public function validate ($context='', $hash = null) {
+ // If hash was not given, find hash
+ if (is_null($hash)) {
+ if (isset($_POST[$this->inputName])) {
+ $hash = $_POST[$this->inputName];
+ }
+ else if (isset($_GET[$this->inputName])) {
+ $hash = $_GET[$this->inputName];
+ }
+ else {
+ return false;
+ }
+ }
+
+ // Check in the hash list
+ for ($i = count($this->hashes) - 1; $i >= 0; $i--) {
+ if ($this->hashes[$i]->verify($hash, $context)) {
+ array_splice($this->hashes, $i, 1);
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ * Load hash list
+ */
+ private function _load () {
+ $this->hashes = array();
+ // If there are hashes on the session
+ if (isset($_SESSION[$this->name])) {
+ // Load session hashes
+ $session_hashes = unserialize($_SESSION[$this->name]);
+ // Ignore expired
+ for ($i = count($session_hashes) - 1; $i >= 0; $i--) {
+ // If an expired found, the rest will be expired
+ if ($session_hashes[$i]->hasExpire()) {
+ break;
+ }
+ array_unshift($this->hashes, $session_hashes[$i]);
+ }
+ if (count($this->hashes) != count($session_hashes)) {
+ $this->_save();
+ }
+ }
+ }
+
+ /**
+ * Save hash list
+ */
+ private function _save () {
+ $_SESSION[$this->name] = serialize($this->hashes);
+ }
+}
+
+class CSRF_Hash {
+
+ private $hash;
+ private $context;
+ private $expire;
+
+ /**
+ * [__construct description]
+ * @param string $context [description]
+ * @param integer $time2Live Number of seconds before expiration
+ */
+ function __construct($context, $time2Live=0, $hashSize=64) {
+ // Save context name
+ $this->context = $context;
+
+ // Generate hash
+ $this->hash = $this->_generateHash($hashSize);
+
+ // Set expiration time
+ if ($time2Live > 0) {
+ $this->expire = time() + $time2Live;
+ }
+ else {
+ $this->expire = 0;
+ }
+ }
+
+ /**
+ * The hash function to use
+ * @param int $n Size in bytes
+ * @return string The generated hash
+ */
+ private function _generateHash ($n) {
+ return bin2hex(openssl_random_pseudo_bytes($n/2));
+ }
+
+ /**
+ * Check if hash has expired
+ * @return boolean
+ */
+ public function hasExpire () {
+ if ($this->expire === 0 || $this->expire > time()) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Verify hash
+ * @return boolean
+ */
+ public function verify ($hash, $context='') {
+ if (strcmp($context, $this->context) === 0 && !$this->hasExpire() && hash_equals($hash, $this->hash)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Check Context
+ * @return boolean
+ */
+ public function inContext ($context='') {
+ if (strcmp($context, $this->context) === 0) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Get hash
+ * @return string
+ */
+ public function get () {
+ return $this->hash;
+ }
+}
\ No newline at end of file
diff --git a/televerser.php b/televerser.php
index 1720b58..4375de0 100644
--- a/televerser.php
+++ b/televerser.php
@@ -8,7 +8,11 @@
@@ -61,7 +65,10 @@ function uploadFiles() {
i ++;
}
- // Append captured images as files to the FormData
+ //csrf token
+ formData.append("jeton-csrf","=$csrf->string($context="televersement")?>");
+
+ // Append captured images as files to the FormData
const capturedImages = document.querySelectorAll('#selectedImages img');
i = 0;
diff --git a/validation.php b/validation.php
index e197822..954f7eb 100644
--- a/validation.php
+++ b/validation.php
@@ -1,8 +1,12 @@