Saturday, March 21, 2015

C# Chat Client v2

In this post I want to present a somewhat improved version of the chat client of the previous post, which uses instead of the PHP class mysql the class mysqli and thus prevents SQL-injections through prepared statements.
The PHP scripts now look as follows:

register.php (http://bloggeroliver.bplaced.net/Chat/Secure/register.php):

<?php
include("connect.php");

$username = $_POST["username"];
$password = $_POST["password"];
$hashedpw = md5($password);

$stmt = $conn->prepare("SELECT username FROM Users WHERE username = ?");
$stmt->bind_param("s", $username);
$stmt->execute();

$stmt->store_result();
$num_rows = $stmt->num_rows;

if ($num_rows > 0) {
     echo "Existing";
}
else {
     $stmt = $conn->prepare("INSERT INTO Users (username, password) VALUES (?, ?);");
     $stmt->bind_param("ss", $username, $hashedpw);
     $stmt->execute();
     echo "Success";
}
?>

login.php (http://bloggeroliver.bplaced.net/Chat/Secure/login.php):

<?php
session_start();

include("connect.php");

$username = $_POST["username"];
$password = $_POST["password"];
$hashedpw = md5($password);

$stmt = $conn->prepare("SELECT password FROM Users WHERE username = ? LIMIT 1");
$stmt->bind_param("s", $username);
$stmt->execute();

$stmt->bind_result($rowpassword);
$row = $stmt->fetch();

if($rowpassword == $hashedpw) {
    $_SESSION["username"] = $username;
    echo "LoginGood";
}
else {
    echo "LoginBad";
}
?>

send.php (http://bloggeroliver.bplaced.net/Chat/Secure/send.php):

<?php
session_start();

include("connect.php");

$Recipient = $_POST["Recipient"];
$Message = $_POST["Message"];
$Sender = $_SESSION['username'];

if(!isset($_SESSION['username'])) {
     echo "Login first.";
     exit;
}  

$stmt = $conn->prepare("INSERT INTO Messages () VALUES (?, ?, ?);");
$stmt->bind_param("sss", $Sender, $Recipient, $Message);
$stmt->execute();
    
?>

receive.php (http://bloggeroliver.bplaced.net/Chat/Secure/receive.php):

<?php

session_start();

include("connect.php");

if(!isset($_SESSION['username']))
   {
   echo "Bitte erst login";
   exit;
   }   
    
$Recipient = $_SESSION['username'];

$stmt = $conn->prepare("SELECT Sender, Message FROM Messages WHERE Recipient = ?");
$stmt->bind_param("s", $Recipient);
$stmt->execute();
    
$stmt->bind_result($sender, $message);
while($row = $stmt->fetch())
   {
          echo "$sender<br />";
          echo "$message<br />";
          $stmt->bind_result($sender, $message);
   }

$stmt = $conn->prepare("DELETE FROM Messages WHERE Recipient = ?");
$stmt->bind_param("s", $Recipient);
$stmt->execute();
?>

In the code of the C# client only one line has to be changed, which is the variable ServerUrl. It has to be set to the new location of the script folder:
string ServerUrl = "http://bloggeroliver.bplaced.net/Chat/Secure/";

The complete source code can be downloaded here, the complete chat program set to my server can be installed via this link.
Also in this chat I am called bloggeroliver and am looking forward to your messages!

Now I here want to discuss the general security of this chat. Roughly speaking I see 2 security issues:

  • On login the password is transmitted unencrypted. An attacker, who has access to the network, could read this out or simply send the same message again to log in. I will handle this problem in the next post. One possibility would be the usage of, for example, TLS / SSL to encrypt the connection. For this though a (probably not free) certificate has to be acquired, I would like to solve this using "C# means" only. Therefor I will implement a Challenge / Response Authentification with a public key.
  • Further the messages are transmitted unencrypted as well, so the same problem as above occurs, every attacker with access to the network could read the messages. Further the database owner could read everything. But I would not call this a vulnerability (and also if, less important than the first one), just a feature. If no encryption of the messages is desired, one can leave it like this (then not directly the security of the whole system is endangered, just no confidentiality is ensured), otherwise implement an encryption (which is of course recommended). In the overnext post I will solve also this with a Public key method.

No comments:

Post a Comment