Websocket chat, get session data from apacheProtecting a database from bad dataFiltering data from usersGet...

VAT refund for a conference ticket in Sweden

Is divide-by-zero a security vulnerability?

Should we avoid writing fiction about historical events without extensive research?

Roots of 6th chords on the guitar for different inversions/voicings

I encountered my boss during an on-site interview at another company. Should I bring it up when seeing him next time?

If a set is open, does that imply that it has no boundary points?

The need of reserving one's ability in job interviews

Calculating Hyperbolic Sin faster than using a standard power series

Starting index at zero

What type of investment is best suited for a 1-year investment on a down payment?

Giving a talk in my old university, how prominently should I tell students my salary?

Is there a full canon version of Tyrion's jackass/honeycomb joke?

Source for Cremation Specifically Not Jewish

What is the difference between a forward slip and a side slip?

What is better: yes / no radio, or simple checkbox?

Real life puzzle: Unknown alphabet or shorthand

At what level can a party fight a mimic?

Dystopian novel where telepathic humans live under a dome

Did Amazon pay $0 in taxes last year?

What should the omniscient narrator call a character?

Where is the line between being obedient and getting bullied by a boss?

How can atoms be electrically neutral when there is a difference in the positions of the charges?

Can we carry rice to Japan?

Don't know what I’m looking for regarding removable HDDs?



Websocket chat, get session data from apache


Protecting a database from bad dataFiltering data from usersGet data from some SOAP resourcesReal-time bitcoin data feed and storage using websocket frameworkImmediately send redirect response, preserving session dataSimple PHP session handler class (using MySQL for session data storage)Read and display data from MySQL tableEliminate redundancy from session authenticationSend Opencv::Mat image from Qt application to HTML client, using websocketGet chat message data from table, grouped by date













0












$begingroup$


In my chat system users are allowed to report spammers, I'm using the Rachet Websocket library from http://socketo.me/docs/hello-world, I was searching for a way to use the $_SESSION variables from Apache server on Websocket server, the only way (easy way) i found was put the data from the $_SESSION variables in the websocket url connection:



//this is on the Apache server
var conn = new WebSocket('ws://localhost:8080?key_1='+jsonKey.key_1+'&key_2='+jsonKey.key_2+'&key_3='+jsonKey.key_3);


This way i can identify users and check if he are flagged as spammer, and also retrive infomation fom my table to use in the chat (user name, avatar...etc) But only this is not enough because he could put this code bellow on the developer tools and send menssages to everyone as he wish:



var conn = new WebSocket('ws://localhost:8080');
data = {msg: 'hello'};
conn.send(JSON.stringify(data));


To prevent it i also added a password on the query string to send to the websocket server.



Because the connection to the websocket is in javascript i had to do some workaround, I'm sure that there's a better way to do it, example: i saw on the Ratchet website that i can use the Symfony Library to use sessions http://socketo.me/docs/sessions, but it seems to be much complicated, i have never used this library, and to learn how to use it would be really tiring.



register_account.php:



//code used to generate the user's tokens, i know that it does
//not generate a unique token, but i have a sql query to check if
//the generated token already exist in my table, if exist i do a
//redirect to a error page, it's not the best way but was the bestest
//that i found
$a_uniq_token = md5(mt_rand(10, 1000000000));
$b_uniq_token = md5(mt_rand(10, 1000000000));

$a_l_hidden_token = md5(mt_rand(10, 1000000000));
$a_r_hidden_token = md5(mt_rand(10, 1000000000));
$b_l_hidden_token = md5(mt_rand(10, 1000000000));
$b_r_hidden_token = md5(mt_rand(10, 1000000000));


index.php:



//in this ajax i get my password and the unique token that
//is used to identify the user
$.ajax({
type:'post',
url:siteURL+'/check_user.php',
success:function(data){
var jsonKey = JSON.parse(data);
var conn = new WebSocket('ws://localhost:8080?key_1='+jsonKey.key_1+'&key_2='+jsonKey.key_2+'&key_3='+jsonKey.key_3);
.
.
.
}
})


check_user.php:



if(!isset($_SESSION))session_start();
if($_SERVER['REQUEST_METHOD'] != 'POST' || empty($_SESSION['user_id'])){
session_unset();
session_destroy();
die();
}

//this function might be kinda usless because i have a password
//but i would like to keep it

//I used two more tokens to hide the real token, i made it
//because since only me knows the token length, it will be
//really hard to guess the token from another user, and it's
//to confuse his mind because he would probably think that it's a
//72 token length
//My first idea was to use bin2hex(random_bytes(150)), but
//i failed to find a way to use this hex token in a SELECT query
//I'm not sure about this one bellow but I think it's safe atleast
function hideToken($hidden_left, $hidden_right, $real_token){
$a = substr($hidden_left,0,15);
$b = substr($hidden_right,0,25);
$c = $real_token;
return base64_encode($a.$c.$b);
}

$a_l = $_SESSION['a_l_hidden_token'];
$a_r = $_SESSION['a_r_hidden_token'];
$c_a = $_SESSION['a_uniq_token'];

$b_l = $_SESSION['b_l_hidden_token'];
$b_r = $_SESSION['b_r_hidden_token'];
$c_b = $_SESSION['b_uniq_token'];

$token_a = hideToken($a_l, $a_r, $c_a);
$token_b = hideToken($b_l, $b_r, $c_b);

require 'websocket_password.php';
//here i used password_hash() to encrypt my password and send through
//the query string, and because a string encrypted with password_hash()
//can't be decrypt it's perfect for my case
$token_passw_crypt = password_hash($token_passw, PASSWORD_BCRYPT);
$crypt = base64_encode($token_passw_crypt);

echo json_encode(['key_1' => $token_a, 'key_2' => $token_b, 'key_3' => $crypt]);


websocket_password.php:



//obviously it's not my real password, just a example
$token_passw = 'h41j55@5G1.@/2hU>$5F1hm1.$#d5g2Blh#0g.vw;we/#55wch74jtwdw';


websocket_chat.php:



namespace MyApp;
require dirname(__DIR__) . '/vendor/autoload.php';
use RatchetMessageComponentInterface;
use RatchetConnectionInterface;

function userData($a_uniq_token, $b_uniq_token, $token_crypt, $msg = NULL){

require dirname(__DIR__).'/websocket_password.php';
//check the password, and if it returns false he
//won't be able to connect and send menssages to another user
if(password_verify($token_passw, base64_decode($token_crypt))){

//extract the tokens from the query string
$a_token_decode = substr(base64_decode($a_uniq_token), 15);
$b_token_decode = substr(base64_decode($b_uniq_token), 15);
$a_token = substr($a_token_decode, 0, 32);
$b_token = substr($b_token_decode, 0, 32);

require dirname(__DIR__).'/data_base_config.php';

$get_data = $conn_db->prepare("SELECT `linkN`, `username`, `avatarUP` FROM `users` WHERE `a_uniq_token` = :a_uniq_token AND `b_uniq_token` = :b_uniq_token");
$get_data->bindParam(":a_uniq_token", $a_token, PDO::PARAM_STR);
$get_data->bindParam(":b_uniq_token", $b_token, PDO::PARAM_STR);
$get_data->execute();
$data = $get_data->fetch(PDO::FETCH_ASSOC);

//check if the user is flagged as spammer
$linkN = $data['linkN'];
if(!empty($linkN)){
$abuso_verbal = 5;
$spam = 5;
$check_report = $conn_db->prepare("SELECT count(link_id) FROM `report_public_chat` WHERE `link_id` = :link_id AND (`abuso_verbal` > :abuso_verbal OR `spam` > :spam)");
$check_report->bindParam(":link_id", $linkN, PDO::PARAM_INT);
$check_report->bindParam(":abuso_verbal", $abuso_verbal, PDO::PARAM_INT);
$check_report->bindParam(":spam", $spam, PDO::PARAM_INT);
$check_report->execute();
$rst_report = $check_report->fetchColumn();

if($rst_report == 0){
if(!empty($msg)){
try{
$msg_data = json_decode($msg);
$msgPC = $msg_data->msgPC ?? NULL;
$imgShare = $msg_data->imgShare ?? NULL;
$ytUrl = $msg_data->ytUrl ?? NULL;

$data = '{//json here, to send the message data}';

//if everything is right, retrun the $data
//else, return 1 and he won't be able to do
//anything
return $data;
}catch (Exception $e){
return 1;
}
}else{
//return 0 because the variable $msg will be
//empty when i use this function to allow the
//conection to the webscoket in the function
//onOpen()
return 0;
}
}else{
return 1;
}
}else{
//return 1 if everything is right unless the user token,
//it can happen because i could have deleted the user's
//account while he is online (for some reason), and it
//will return 1 till he reloads the page and be redirected
//to the login page
return 1;
}
}else{
return 1;
}
}
//these functions bellow is from http://socketo.me/docs/hello-world,
public function onOpen(ConnectionInterface $conn) {

parse_str($conn->httpRequest->getUri()->getQuery(), $token);
$key_a = $token['key_1'];
$key_b = $token['key_2'];
$psswd = $token['key_3'];

//check if the query strings is not empty and if the function
//userData() anything that is != 1
if(!empty($key_a) && !empty($key_b) && !empty($psswd)){
if(userData($key_a, $key_b, $psswd) != 1){
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})n";
}
}

}
//because this function onMessage() is triggered on every message
//he does not need to reload the page to be "blocked" from the chat
public function onMessage(ConnectionInterface $conn, $msg) {

parse_str($conn->httpRequest->getUri()->getQuery(), $token);
$key_a = $token['key_1'];
$key_b = $token['key_2'];
$psswd = $token['key_3'];

if(!empty($key_a) && !empty($key_b) && !empty($psswd)){

$get_data = userData($key_a, $key_b, $psswd, $msg);

//if userData() returns anything that is != 1 he is allowed to
//send messages
if($get_data != 1){
foreach ($this->clients as $client) {
$client->send($get_data);
}
}else{
//if userData() returnn 1, remove the user from the current
//conections, this way he cannot receive messages
$this->clients->detach($conn);
}
}

}


I made some tests and this code is working perfectly, but i would like to know where i can improve it, and if there's any erros, because if someone find a way to bypass it, it will be hard for me to fix it because at my actual knowlegde i'm not seeing any breachs in this code.









share









$endgroup$

















    0












    $begingroup$


    In my chat system users are allowed to report spammers, I'm using the Rachet Websocket library from http://socketo.me/docs/hello-world, I was searching for a way to use the $_SESSION variables from Apache server on Websocket server, the only way (easy way) i found was put the data from the $_SESSION variables in the websocket url connection:



    //this is on the Apache server
    var conn = new WebSocket('ws://localhost:8080?key_1='+jsonKey.key_1+'&key_2='+jsonKey.key_2+'&key_3='+jsonKey.key_3);


    This way i can identify users and check if he are flagged as spammer, and also retrive infomation fom my table to use in the chat (user name, avatar...etc) But only this is not enough because he could put this code bellow on the developer tools and send menssages to everyone as he wish:



    var conn = new WebSocket('ws://localhost:8080');
    data = {msg: 'hello'};
    conn.send(JSON.stringify(data));


    To prevent it i also added a password on the query string to send to the websocket server.



    Because the connection to the websocket is in javascript i had to do some workaround, I'm sure that there's a better way to do it, example: i saw on the Ratchet website that i can use the Symfony Library to use sessions http://socketo.me/docs/sessions, but it seems to be much complicated, i have never used this library, and to learn how to use it would be really tiring.



    register_account.php:



    //code used to generate the user's tokens, i know that it does
    //not generate a unique token, but i have a sql query to check if
    //the generated token already exist in my table, if exist i do a
    //redirect to a error page, it's not the best way but was the bestest
    //that i found
    $a_uniq_token = md5(mt_rand(10, 1000000000));
    $b_uniq_token = md5(mt_rand(10, 1000000000));

    $a_l_hidden_token = md5(mt_rand(10, 1000000000));
    $a_r_hidden_token = md5(mt_rand(10, 1000000000));
    $b_l_hidden_token = md5(mt_rand(10, 1000000000));
    $b_r_hidden_token = md5(mt_rand(10, 1000000000));


    index.php:



    //in this ajax i get my password and the unique token that
    //is used to identify the user
    $.ajax({
    type:'post',
    url:siteURL+'/check_user.php',
    success:function(data){
    var jsonKey = JSON.parse(data);
    var conn = new WebSocket('ws://localhost:8080?key_1='+jsonKey.key_1+'&key_2='+jsonKey.key_2+'&key_3='+jsonKey.key_3);
    .
    .
    .
    }
    })


    check_user.php:



    if(!isset($_SESSION))session_start();
    if($_SERVER['REQUEST_METHOD'] != 'POST' || empty($_SESSION['user_id'])){
    session_unset();
    session_destroy();
    die();
    }

    //this function might be kinda usless because i have a password
    //but i would like to keep it

    //I used two more tokens to hide the real token, i made it
    //because since only me knows the token length, it will be
    //really hard to guess the token from another user, and it's
    //to confuse his mind because he would probably think that it's a
    //72 token length
    //My first idea was to use bin2hex(random_bytes(150)), but
    //i failed to find a way to use this hex token in a SELECT query
    //I'm not sure about this one bellow but I think it's safe atleast
    function hideToken($hidden_left, $hidden_right, $real_token){
    $a = substr($hidden_left,0,15);
    $b = substr($hidden_right,0,25);
    $c = $real_token;
    return base64_encode($a.$c.$b);
    }

    $a_l = $_SESSION['a_l_hidden_token'];
    $a_r = $_SESSION['a_r_hidden_token'];
    $c_a = $_SESSION['a_uniq_token'];

    $b_l = $_SESSION['b_l_hidden_token'];
    $b_r = $_SESSION['b_r_hidden_token'];
    $c_b = $_SESSION['b_uniq_token'];

    $token_a = hideToken($a_l, $a_r, $c_a);
    $token_b = hideToken($b_l, $b_r, $c_b);

    require 'websocket_password.php';
    //here i used password_hash() to encrypt my password and send through
    //the query string, and because a string encrypted with password_hash()
    //can't be decrypt it's perfect for my case
    $token_passw_crypt = password_hash($token_passw, PASSWORD_BCRYPT);
    $crypt = base64_encode($token_passw_crypt);

    echo json_encode(['key_1' => $token_a, 'key_2' => $token_b, 'key_3' => $crypt]);


    websocket_password.php:



    //obviously it's not my real password, just a example
    $token_passw = 'h41j55@5G1.@/2hU>$5F1hm1.$#d5g2Blh#0g.vw;we/#55wch74jtwdw';


    websocket_chat.php:



    namespace MyApp;
    require dirname(__DIR__) . '/vendor/autoload.php';
    use RatchetMessageComponentInterface;
    use RatchetConnectionInterface;

    function userData($a_uniq_token, $b_uniq_token, $token_crypt, $msg = NULL){

    require dirname(__DIR__).'/websocket_password.php';
    //check the password, and if it returns false he
    //won't be able to connect and send menssages to another user
    if(password_verify($token_passw, base64_decode($token_crypt))){

    //extract the tokens from the query string
    $a_token_decode = substr(base64_decode($a_uniq_token), 15);
    $b_token_decode = substr(base64_decode($b_uniq_token), 15);
    $a_token = substr($a_token_decode, 0, 32);
    $b_token = substr($b_token_decode, 0, 32);

    require dirname(__DIR__).'/data_base_config.php';

    $get_data = $conn_db->prepare("SELECT `linkN`, `username`, `avatarUP` FROM `users` WHERE `a_uniq_token` = :a_uniq_token AND `b_uniq_token` = :b_uniq_token");
    $get_data->bindParam(":a_uniq_token", $a_token, PDO::PARAM_STR);
    $get_data->bindParam(":b_uniq_token", $b_token, PDO::PARAM_STR);
    $get_data->execute();
    $data = $get_data->fetch(PDO::FETCH_ASSOC);

    //check if the user is flagged as spammer
    $linkN = $data['linkN'];
    if(!empty($linkN)){
    $abuso_verbal = 5;
    $spam = 5;
    $check_report = $conn_db->prepare("SELECT count(link_id) FROM `report_public_chat` WHERE `link_id` = :link_id AND (`abuso_verbal` > :abuso_verbal OR `spam` > :spam)");
    $check_report->bindParam(":link_id", $linkN, PDO::PARAM_INT);
    $check_report->bindParam(":abuso_verbal", $abuso_verbal, PDO::PARAM_INT);
    $check_report->bindParam(":spam", $spam, PDO::PARAM_INT);
    $check_report->execute();
    $rst_report = $check_report->fetchColumn();

    if($rst_report == 0){
    if(!empty($msg)){
    try{
    $msg_data = json_decode($msg);
    $msgPC = $msg_data->msgPC ?? NULL;
    $imgShare = $msg_data->imgShare ?? NULL;
    $ytUrl = $msg_data->ytUrl ?? NULL;

    $data = '{//json here, to send the message data}';

    //if everything is right, retrun the $data
    //else, return 1 and he won't be able to do
    //anything
    return $data;
    }catch (Exception $e){
    return 1;
    }
    }else{
    //return 0 because the variable $msg will be
    //empty when i use this function to allow the
    //conection to the webscoket in the function
    //onOpen()
    return 0;
    }
    }else{
    return 1;
    }
    }else{
    //return 1 if everything is right unless the user token,
    //it can happen because i could have deleted the user's
    //account while he is online (for some reason), and it
    //will return 1 till he reloads the page and be redirected
    //to the login page
    return 1;
    }
    }else{
    return 1;
    }
    }
    //these functions bellow is from http://socketo.me/docs/hello-world,
    public function onOpen(ConnectionInterface $conn) {

    parse_str($conn->httpRequest->getUri()->getQuery(), $token);
    $key_a = $token['key_1'];
    $key_b = $token['key_2'];
    $psswd = $token['key_3'];

    //check if the query strings is not empty and if the function
    //userData() anything that is != 1
    if(!empty($key_a) && !empty($key_b) && !empty($psswd)){
    if(userData($key_a, $key_b, $psswd) != 1){
    $this->clients->attach($conn);
    echo "New connection! ({$conn->resourceId})n";
    }
    }

    }
    //because this function onMessage() is triggered on every message
    //he does not need to reload the page to be "blocked" from the chat
    public function onMessage(ConnectionInterface $conn, $msg) {

    parse_str($conn->httpRequest->getUri()->getQuery(), $token);
    $key_a = $token['key_1'];
    $key_b = $token['key_2'];
    $psswd = $token['key_3'];

    if(!empty($key_a) && !empty($key_b) && !empty($psswd)){

    $get_data = userData($key_a, $key_b, $psswd, $msg);

    //if userData() returns anything that is != 1 he is allowed to
    //send messages
    if($get_data != 1){
    foreach ($this->clients as $client) {
    $client->send($get_data);
    }
    }else{
    //if userData() returnn 1, remove the user from the current
    //conections, this way he cannot receive messages
    $this->clients->detach($conn);
    }
    }

    }


    I made some tests and this code is working perfectly, but i would like to know where i can improve it, and if there's any erros, because if someone find a way to bypass it, it will be hard for me to fix it because at my actual knowlegde i'm not seeing any breachs in this code.









    share









    $endgroup$















      0












      0








      0





      $begingroup$


      In my chat system users are allowed to report spammers, I'm using the Rachet Websocket library from http://socketo.me/docs/hello-world, I was searching for a way to use the $_SESSION variables from Apache server on Websocket server, the only way (easy way) i found was put the data from the $_SESSION variables in the websocket url connection:



      //this is on the Apache server
      var conn = new WebSocket('ws://localhost:8080?key_1='+jsonKey.key_1+'&key_2='+jsonKey.key_2+'&key_3='+jsonKey.key_3);


      This way i can identify users and check if he are flagged as spammer, and also retrive infomation fom my table to use in the chat (user name, avatar...etc) But only this is not enough because he could put this code bellow on the developer tools and send menssages to everyone as he wish:



      var conn = new WebSocket('ws://localhost:8080');
      data = {msg: 'hello'};
      conn.send(JSON.stringify(data));


      To prevent it i also added a password on the query string to send to the websocket server.



      Because the connection to the websocket is in javascript i had to do some workaround, I'm sure that there's a better way to do it, example: i saw on the Ratchet website that i can use the Symfony Library to use sessions http://socketo.me/docs/sessions, but it seems to be much complicated, i have never used this library, and to learn how to use it would be really tiring.



      register_account.php:



      //code used to generate the user's tokens, i know that it does
      //not generate a unique token, but i have a sql query to check if
      //the generated token already exist in my table, if exist i do a
      //redirect to a error page, it's not the best way but was the bestest
      //that i found
      $a_uniq_token = md5(mt_rand(10, 1000000000));
      $b_uniq_token = md5(mt_rand(10, 1000000000));

      $a_l_hidden_token = md5(mt_rand(10, 1000000000));
      $a_r_hidden_token = md5(mt_rand(10, 1000000000));
      $b_l_hidden_token = md5(mt_rand(10, 1000000000));
      $b_r_hidden_token = md5(mt_rand(10, 1000000000));


      index.php:



      //in this ajax i get my password and the unique token that
      //is used to identify the user
      $.ajax({
      type:'post',
      url:siteURL+'/check_user.php',
      success:function(data){
      var jsonKey = JSON.parse(data);
      var conn = new WebSocket('ws://localhost:8080?key_1='+jsonKey.key_1+'&key_2='+jsonKey.key_2+'&key_3='+jsonKey.key_3);
      .
      .
      .
      }
      })


      check_user.php:



      if(!isset($_SESSION))session_start();
      if($_SERVER['REQUEST_METHOD'] != 'POST' || empty($_SESSION['user_id'])){
      session_unset();
      session_destroy();
      die();
      }

      //this function might be kinda usless because i have a password
      //but i would like to keep it

      //I used two more tokens to hide the real token, i made it
      //because since only me knows the token length, it will be
      //really hard to guess the token from another user, and it's
      //to confuse his mind because he would probably think that it's a
      //72 token length
      //My first idea was to use bin2hex(random_bytes(150)), but
      //i failed to find a way to use this hex token in a SELECT query
      //I'm not sure about this one bellow but I think it's safe atleast
      function hideToken($hidden_left, $hidden_right, $real_token){
      $a = substr($hidden_left,0,15);
      $b = substr($hidden_right,0,25);
      $c = $real_token;
      return base64_encode($a.$c.$b);
      }

      $a_l = $_SESSION['a_l_hidden_token'];
      $a_r = $_SESSION['a_r_hidden_token'];
      $c_a = $_SESSION['a_uniq_token'];

      $b_l = $_SESSION['b_l_hidden_token'];
      $b_r = $_SESSION['b_r_hidden_token'];
      $c_b = $_SESSION['b_uniq_token'];

      $token_a = hideToken($a_l, $a_r, $c_a);
      $token_b = hideToken($b_l, $b_r, $c_b);

      require 'websocket_password.php';
      //here i used password_hash() to encrypt my password and send through
      //the query string, and because a string encrypted with password_hash()
      //can't be decrypt it's perfect for my case
      $token_passw_crypt = password_hash($token_passw, PASSWORD_BCRYPT);
      $crypt = base64_encode($token_passw_crypt);

      echo json_encode(['key_1' => $token_a, 'key_2' => $token_b, 'key_3' => $crypt]);


      websocket_password.php:



      //obviously it's not my real password, just a example
      $token_passw = 'h41j55@5G1.@/2hU>$5F1hm1.$#d5g2Blh#0g.vw;we/#55wch74jtwdw';


      websocket_chat.php:



      namespace MyApp;
      require dirname(__DIR__) . '/vendor/autoload.php';
      use RatchetMessageComponentInterface;
      use RatchetConnectionInterface;

      function userData($a_uniq_token, $b_uniq_token, $token_crypt, $msg = NULL){

      require dirname(__DIR__).'/websocket_password.php';
      //check the password, and if it returns false he
      //won't be able to connect and send menssages to another user
      if(password_verify($token_passw, base64_decode($token_crypt))){

      //extract the tokens from the query string
      $a_token_decode = substr(base64_decode($a_uniq_token), 15);
      $b_token_decode = substr(base64_decode($b_uniq_token), 15);
      $a_token = substr($a_token_decode, 0, 32);
      $b_token = substr($b_token_decode, 0, 32);

      require dirname(__DIR__).'/data_base_config.php';

      $get_data = $conn_db->prepare("SELECT `linkN`, `username`, `avatarUP` FROM `users` WHERE `a_uniq_token` = :a_uniq_token AND `b_uniq_token` = :b_uniq_token");
      $get_data->bindParam(":a_uniq_token", $a_token, PDO::PARAM_STR);
      $get_data->bindParam(":b_uniq_token", $b_token, PDO::PARAM_STR);
      $get_data->execute();
      $data = $get_data->fetch(PDO::FETCH_ASSOC);

      //check if the user is flagged as spammer
      $linkN = $data['linkN'];
      if(!empty($linkN)){
      $abuso_verbal = 5;
      $spam = 5;
      $check_report = $conn_db->prepare("SELECT count(link_id) FROM `report_public_chat` WHERE `link_id` = :link_id AND (`abuso_verbal` > :abuso_verbal OR `spam` > :spam)");
      $check_report->bindParam(":link_id", $linkN, PDO::PARAM_INT);
      $check_report->bindParam(":abuso_verbal", $abuso_verbal, PDO::PARAM_INT);
      $check_report->bindParam(":spam", $spam, PDO::PARAM_INT);
      $check_report->execute();
      $rst_report = $check_report->fetchColumn();

      if($rst_report == 0){
      if(!empty($msg)){
      try{
      $msg_data = json_decode($msg);
      $msgPC = $msg_data->msgPC ?? NULL;
      $imgShare = $msg_data->imgShare ?? NULL;
      $ytUrl = $msg_data->ytUrl ?? NULL;

      $data = '{//json here, to send the message data}';

      //if everything is right, retrun the $data
      //else, return 1 and he won't be able to do
      //anything
      return $data;
      }catch (Exception $e){
      return 1;
      }
      }else{
      //return 0 because the variable $msg will be
      //empty when i use this function to allow the
      //conection to the webscoket in the function
      //onOpen()
      return 0;
      }
      }else{
      return 1;
      }
      }else{
      //return 1 if everything is right unless the user token,
      //it can happen because i could have deleted the user's
      //account while he is online (for some reason), and it
      //will return 1 till he reloads the page and be redirected
      //to the login page
      return 1;
      }
      }else{
      return 1;
      }
      }
      //these functions bellow is from http://socketo.me/docs/hello-world,
      public function onOpen(ConnectionInterface $conn) {

      parse_str($conn->httpRequest->getUri()->getQuery(), $token);
      $key_a = $token['key_1'];
      $key_b = $token['key_2'];
      $psswd = $token['key_3'];

      //check if the query strings is not empty and if the function
      //userData() anything that is != 1
      if(!empty($key_a) && !empty($key_b) && !empty($psswd)){
      if(userData($key_a, $key_b, $psswd) != 1){
      $this->clients->attach($conn);
      echo "New connection! ({$conn->resourceId})n";
      }
      }

      }
      //because this function onMessage() is triggered on every message
      //he does not need to reload the page to be "blocked" from the chat
      public function onMessage(ConnectionInterface $conn, $msg) {

      parse_str($conn->httpRequest->getUri()->getQuery(), $token);
      $key_a = $token['key_1'];
      $key_b = $token['key_2'];
      $psswd = $token['key_3'];

      if(!empty($key_a) && !empty($key_b) && !empty($psswd)){

      $get_data = userData($key_a, $key_b, $psswd, $msg);

      //if userData() returns anything that is != 1 he is allowed to
      //send messages
      if($get_data != 1){
      foreach ($this->clients as $client) {
      $client->send($get_data);
      }
      }else{
      //if userData() returnn 1, remove the user from the current
      //conections, this way he cannot receive messages
      $this->clients->detach($conn);
      }
      }

      }


      I made some tests and this code is working perfectly, but i would like to know where i can improve it, and if there's any erros, because if someone find a way to bypass it, it will be hard for me to fix it because at my actual knowlegde i'm not seeing any breachs in this code.









      share









      $endgroup$




      In my chat system users are allowed to report spammers, I'm using the Rachet Websocket library from http://socketo.me/docs/hello-world, I was searching for a way to use the $_SESSION variables from Apache server on Websocket server, the only way (easy way) i found was put the data from the $_SESSION variables in the websocket url connection:



      //this is on the Apache server
      var conn = new WebSocket('ws://localhost:8080?key_1='+jsonKey.key_1+'&key_2='+jsonKey.key_2+'&key_3='+jsonKey.key_3);


      This way i can identify users and check if he are flagged as spammer, and also retrive infomation fom my table to use in the chat (user name, avatar...etc) But only this is not enough because he could put this code bellow on the developer tools and send menssages to everyone as he wish:



      var conn = new WebSocket('ws://localhost:8080');
      data = {msg: 'hello'};
      conn.send(JSON.stringify(data));


      To prevent it i also added a password on the query string to send to the websocket server.



      Because the connection to the websocket is in javascript i had to do some workaround, I'm sure that there's a better way to do it, example: i saw on the Ratchet website that i can use the Symfony Library to use sessions http://socketo.me/docs/sessions, but it seems to be much complicated, i have never used this library, and to learn how to use it would be really tiring.



      register_account.php:



      //code used to generate the user's tokens, i know that it does
      //not generate a unique token, but i have a sql query to check if
      //the generated token already exist in my table, if exist i do a
      //redirect to a error page, it's not the best way but was the bestest
      //that i found
      $a_uniq_token = md5(mt_rand(10, 1000000000));
      $b_uniq_token = md5(mt_rand(10, 1000000000));

      $a_l_hidden_token = md5(mt_rand(10, 1000000000));
      $a_r_hidden_token = md5(mt_rand(10, 1000000000));
      $b_l_hidden_token = md5(mt_rand(10, 1000000000));
      $b_r_hidden_token = md5(mt_rand(10, 1000000000));


      index.php:



      //in this ajax i get my password and the unique token that
      //is used to identify the user
      $.ajax({
      type:'post',
      url:siteURL+'/check_user.php',
      success:function(data){
      var jsonKey = JSON.parse(data);
      var conn = new WebSocket('ws://localhost:8080?key_1='+jsonKey.key_1+'&key_2='+jsonKey.key_2+'&key_3='+jsonKey.key_3);
      .
      .
      .
      }
      })


      check_user.php:



      if(!isset($_SESSION))session_start();
      if($_SERVER['REQUEST_METHOD'] != 'POST' || empty($_SESSION['user_id'])){
      session_unset();
      session_destroy();
      die();
      }

      //this function might be kinda usless because i have a password
      //but i would like to keep it

      //I used two more tokens to hide the real token, i made it
      //because since only me knows the token length, it will be
      //really hard to guess the token from another user, and it's
      //to confuse his mind because he would probably think that it's a
      //72 token length
      //My first idea was to use bin2hex(random_bytes(150)), but
      //i failed to find a way to use this hex token in a SELECT query
      //I'm not sure about this one bellow but I think it's safe atleast
      function hideToken($hidden_left, $hidden_right, $real_token){
      $a = substr($hidden_left,0,15);
      $b = substr($hidden_right,0,25);
      $c = $real_token;
      return base64_encode($a.$c.$b);
      }

      $a_l = $_SESSION['a_l_hidden_token'];
      $a_r = $_SESSION['a_r_hidden_token'];
      $c_a = $_SESSION['a_uniq_token'];

      $b_l = $_SESSION['b_l_hidden_token'];
      $b_r = $_SESSION['b_r_hidden_token'];
      $c_b = $_SESSION['b_uniq_token'];

      $token_a = hideToken($a_l, $a_r, $c_a);
      $token_b = hideToken($b_l, $b_r, $c_b);

      require 'websocket_password.php';
      //here i used password_hash() to encrypt my password and send through
      //the query string, and because a string encrypted with password_hash()
      //can't be decrypt it's perfect for my case
      $token_passw_crypt = password_hash($token_passw, PASSWORD_BCRYPT);
      $crypt = base64_encode($token_passw_crypt);

      echo json_encode(['key_1' => $token_a, 'key_2' => $token_b, 'key_3' => $crypt]);


      websocket_password.php:



      //obviously it's not my real password, just a example
      $token_passw = 'h41j55@5G1.@/2hU>$5F1hm1.$#d5g2Blh#0g.vw;we/#55wch74jtwdw';


      websocket_chat.php:



      namespace MyApp;
      require dirname(__DIR__) . '/vendor/autoload.php';
      use RatchetMessageComponentInterface;
      use RatchetConnectionInterface;

      function userData($a_uniq_token, $b_uniq_token, $token_crypt, $msg = NULL){

      require dirname(__DIR__).'/websocket_password.php';
      //check the password, and if it returns false he
      //won't be able to connect and send menssages to another user
      if(password_verify($token_passw, base64_decode($token_crypt))){

      //extract the tokens from the query string
      $a_token_decode = substr(base64_decode($a_uniq_token), 15);
      $b_token_decode = substr(base64_decode($b_uniq_token), 15);
      $a_token = substr($a_token_decode, 0, 32);
      $b_token = substr($b_token_decode, 0, 32);

      require dirname(__DIR__).'/data_base_config.php';

      $get_data = $conn_db->prepare("SELECT `linkN`, `username`, `avatarUP` FROM `users` WHERE `a_uniq_token` = :a_uniq_token AND `b_uniq_token` = :b_uniq_token");
      $get_data->bindParam(":a_uniq_token", $a_token, PDO::PARAM_STR);
      $get_data->bindParam(":b_uniq_token", $b_token, PDO::PARAM_STR);
      $get_data->execute();
      $data = $get_data->fetch(PDO::FETCH_ASSOC);

      //check if the user is flagged as spammer
      $linkN = $data['linkN'];
      if(!empty($linkN)){
      $abuso_verbal = 5;
      $spam = 5;
      $check_report = $conn_db->prepare("SELECT count(link_id) FROM `report_public_chat` WHERE `link_id` = :link_id AND (`abuso_verbal` > :abuso_verbal OR `spam` > :spam)");
      $check_report->bindParam(":link_id", $linkN, PDO::PARAM_INT);
      $check_report->bindParam(":abuso_verbal", $abuso_verbal, PDO::PARAM_INT);
      $check_report->bindParam(":spam", $spam, PDO::PARAM_INT);
      $check_report->execute();
      $rst_report = $check_report->fetchColumn();

      if($rst_report == 0){
      if(!empty($msg)){
      try{
      $msg_data = json_decode($msg);
      $msgPC = $msg_data->msgPC ?? NULL;
      $imgShare = $msg_data->imgShare ?? NULL;
      $ytUrl = $msg_data->ytUrl ?? NULL;

      $data = '{//json here, to send the message data}';

      //if everything is right, retrun the $data
      //else, return 1 and he won't be able to do
      //anything
      return $data;
      }catch (Exception $e){
      return 1;
      }
      }else{
      //return 0 because the variable $msg will be
      //empty when i use this function to allow the
      //conection to the webscoket in the function
      //onOpen()
      return 0;
      }
      }else{
      return 1;
      }
      }else{
      //return 1 if everything is right unless the user token,
      //it can happen because i could have deleted the user's
      //account while he is online (for some reason), and it
      //will return 1 till he reloads the page and be redirected
      //to the login page
      return 1;
      }
      }else{
      return 1;
      }
      }
      //these functions bellow is from http://socketo.me/docs/hello-world,
      public function onOpen(ConnectionInterface $conn) {

      parse_str($conn->httpRequest->getUri()->getQuery(), $token);
      $key_a = $token['key_1'];
      $key_b = $token['key_2'];
      $psswd = $token['key_3'];

      //check if the query strings is not empty and if the function
      //userData() anything that is != 1
      if(!empty($key_a) && !empty($key_b) && !empty($psswd)){
      if(userData($key_a, $key_b, $psswd) != 1){
      $this->clients->attach($conn);
      echo "New connection! ({$conn->resourceId})n";
      }
      }

      }
      //because this function onMessage() is triggered on every message
      //he does not need to reload the page to be "blocked" from the chat
      public function onMessage(ConnectionInterface $conn, $msg) {

      parse_str($conn->httpRequest->getUri()->getQuery(), $token);
      $key_a = $token['key_1'];
      $key_b = $token['key_2'];
      $psswd = $token['key_3'];

      if(!empty($key_a) && !empty($key_b) && !empty($psswd)){

      $get_data = userData($key_a, $key_b, $psswd, $msg);

      //if userData() returns anything that is != 1 he is allowed to
      //send messages
      if($get_data != 1){
      foreach ($this->clients as $client) {
      $client->send($get_data);
      }
      }else{
      //if userData() returnn 1, remove the user from the current
      //conections, this way he cannot receive messages
      $this->clients->detach($conn);
      }
      }

      }


      I made some tests and this code is working perfectly, but i would like to know where i can improve it, and if there's any erros, because if someone find a way to bypass it, it will be hard for me to fix it because at my actual knowlegde i'm not seeing any breachs in this code.







      php security validation authorization websocket





      share












      share










      share



      share










      asked 6 mins ago









      nobodynobody

      576




      576






















          0






          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214813%2fwebsocket-chat-get-session-data-from-apache%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214813%2fwebsocket-chat-get-session-data-from-apache%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          is 'sed' thread safeWhat should someone know about using Python scripts in the shell?Nexenta bash script uses...

          How do i solve the “ No module named 'mlxtend' ” issue on Jupyter?

          Pilgersdorf Inhaltsverzeichnis Geografie | Geschichte | Bevölkerungsentwicklung | Politik | Kultur...