Simple Invoices logo
    • CommentAuthorcaver
    • CommentTimeApr 4th 2007 edited
     permalink
    Do I understand this correctly:

    // check if the user id and password combination exist in database
    $sql = "SELECT user_id
    FROM si_users
    WHERE user_email = '$userEmail' AND user_password = md5('$password')";


    Does that mean that the password is sent "in the clear" to Simple Invoices????

    May I suggest this:
    http://pajhome.org.uk/crypt/md5

    it allows the MD5 hashing to occur on the client side so that only the hash is sent........................ AND for the super paranoid:

    IF you give each login a unique number, THEN hash the already hashed password on the server, and the Unique Number....

    ON the client side.... Hash the password, then the hashed password with the unique number,

    Compare those two hashs with eachother, along with validating the Unique number hasn't already been used before, even if someone gets that hash it's no good anymore (the number's been used), and that's How the login should work......................

    Any chance of this happening???

    If not I've done it before......... I'm sure I could get it to work with Simple Invoices.............. but I have NO IDEA how svn works, and I'm not sure when i'd have the time............. are you interested (I guess I'm talking to justin)???


    I use my neighbors unsecured WIFI connection to get online.......... hence I worry that someone will packet sniff out my info.......... I think it's very important to get this working........

    Any comments??? You think you can do it or do you want me to work on it???

    Thanks,
    Chris
    • CommentAuthorjustin
    • CommentTimeApr 4th 2007 edited
     permalink
    Hey Chris,

    re "Does that mean that the password is sent "in the clear" to Simple Invoices????"
    - i doubt it - its a pretty common php/mysql solution - though im no security expert - it maybe the case?
    -- can you try packet sniffing and see if you can get the password in clear text

    re http://pajhome.org.uk/crypt/md5 />- this is a javascript based solution and ive had issues with javascript - let me know if you can find a purely php solution

    Cheers

    Justin
    • CommentAuthordanfloun
    • CommentTimeApr 4th 2007 edited
     permalink
    Hi

    I'm no security/php expert but heres my 2 cents.

    At this point in the script the password is in plain text...
    $password = $_POST['pass'];

    At this point in the script it is hashed so it is not...
    WHERE user_password = md5('$password')";

    So i guess the answer is.... I DONT KNOW! :D

    Unless the password could be hashed in the form before it appears in the $_POST variable I don't see how more safe it could be!

    Hey Justin... can you not do this instead!

    WHERE user_password = md5('$_POST[pass]')";

    and remove the
    $password = $_POST['pass'];

    Not sure whether that will work or not but it saves keeping the plain text password in the $password variable if it does??

    The only other issue is whether the password variable is cleared once the form is submitted! I assume these are once the page changes... is that correct?

    Excuse me if that's dum, I ain't all that up on php.

    Danny
    • CommentAuthorcaver
    • CommentTimeApr 5th 2007 edited
     permalink
    13:57:07 - 04.04.2007 Protocol: TCP Service: HTTP
    Source Address: 10.15.20.10 Destination Address: 64.247.42.189
    Source Port: 1612 Destination Port: 80
    45 00 00 c3 4c d9 40 00 80 06 23 8f 0a 0f 14 0a 40 f7 E L @ # @
    2a bd 06 4c 00 50 d3 6d 9c 41 1c 0a 1f d8 50 18 80 52 * L P m A P R
    ec 17 00 00 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 Content-Type:
    61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 77 77 77 2d application/x-www-
    66 6f 72 6d 2d 75 72 6c 65 6e 63 6f 64 65 64 0d 0a 43 form-urlencoded C
    6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 38 34 0d ontent-Length: 84
    0a 0d 0a 61 63 74 69 6f 6e 3d 6c 6f 67 69 6e 26 63 6f action=login&co
    6f 6b 69 65 76 65 72 69 66 79 3d 26 72 65 64 69 72 65 okieverify=&redire
    63 74 3d 26 75 73 65 72 3d 54 68 69 73 69 73 61 74 65 ct=&user=Thisisate
    73 74 25 34 30 63 61 68 62 69 6c 6c 69 6e 67 2e 63 6f st%40cahbilling.co
    6d 26 70 61 73 73 3d 50 61 73 73 77 6f 72 64 m&pass=Password
    • CommentAuthorcaver
    • CommentTimeApr 5th 2007 edited
     permalink
    So above was my packet sniffing adventure.......... the user I tested was "Thisisatest@cahbilling.com" and the password I used was "Password" you can see that both are there...

    Like danny was saying........... Once PHP has it it's already been sent accross the internet.

    So to make it more secure you have to Hash it on the client side........ that's why you NEED to use javascript (or some other CLIENT side scripting)...

    Anything you do in PHP has to be given to the server first.... to give it to the server you have to send it clear text across the internet...

    I'll play with it more later...
    TTFN,
    Chris
    • CommentAuthorjustin
    • CommentTimeApr 5th 2007 edited
     permalink
    was your password "Password"?
    -- oops you bet me to post
    • CommentAuthorjustin
    • CommentTimeApr 5th 2007 edited
     permalink
    Thanks guys,

    can some of you guys read up on the web on the best way to do this in php

    problem
    login.php uses $_POST[] to pass the 'password' - and the $_POST can be read

    solution:
    encrypt the $_POST before its send, etc.. or something

    can https/ssl solve this?

    note:
    javascript only as last resort

    refer:
    http://www-128.ibm.com/developerworks/opensource/library/os-php-encrypt/
    http://www.onlamp.com/pub/a/php/2001/07/26/encrypt.html

    Cheers

    Justin
    • CommentAuthorcaver
    • CommentTimeApr 5th 2007 edited
     permalink
    I posted this the same time you posted your links about the PHP-Encyption..... Let me have a look at that to see if it's a better solution before I push javascript some more....


    You know what I really want to make this happen with the Javascript..........

    I don't know SVN.............

    If I made the change and made sure that basically it worked.......... (IE tested, but god knows I'm not perfect)....

    Then I posted a detailed log of what I changed up here would you (Justin) put it up in the current SVN version???? Or is there something here with the javascript/MD5 passwords that is totally not inline with this project????
    • CommentAuthorjustin
    • CommentTimeApr 5th 2007 edited
     permalink
    Hey Chris,

    if you do the code, just post here what you did - you can attach the files to a new bug in our issues system
    http://code.google.com/p/simpleinvoices/issues/list

    Cheers

    Justin
    • CommentAuthorjustin
    • CommentTimeApr 5th 2007 edited
     permalink
    thanks a pure php solution is preferred
    • CommentAuthorcaver
    • CommentTimeApr 5th 2007 edited
     permalink
    neither of those articles really cover what we're talking about....... (I find that strange because their titles would lead you to believe they would....)

    One article does state:

    "One final very important note to make about PHP and encryption is that any data transmitted between the server and the client (and vice-versa) is not secure while in transit! PHP is a server-side technology, and can do nothing to prevent snoopers from watching this data in transit. Therefore, if you are interested in implementing a complete security application, I would suggest checking out Apache-SSL, or any of the other reputable secure-server implementations."

    Yes he also mentions Apache-SSL.... but then I'd have to pay more for my hosting :(

    I'll make changes later this week (maybe even tonight) and post them...

    Thanks for everyones (Danny and justin) comments,
    Chris
    • CommentAuthorjustin
    • CommentTimeApr 5th 2007 edited
     permalink
    Thanks again Chris

    i think the real solution is https, if you do do the javascript can you make is able to be turned on/off, ie have a config setting to control it - this way for people who dont have javascript they can still login

    Cheers

    Justin
    • CommentAuthoraplysia
    • CommentTimeApr 5th 2007 edited
     permalink
    I also think the only real solution is with https. It's nice to login with a encrypted password. But then all the other transfer isn't encrypted. So if someone is sniffing, he can catch all the other stuff, even if he hasn't the password...
    • CommentAuthordanfloun
    • CommentTimeApr 5th 2007 edited
     permalink
    Well I think you have three options.

    1. Use https where possible.
    2. Use javascript where possible
    3. Leave it as is, or use all three (configurable).

    Justin! Why is javascript a problem for you when all the form validations are javascript based?

    Anyway, using the script from the site caver supplied. Simply do this to add MD5 hashing to the password before it's sent.

    Sorry Justin it's a javascript thing!

    1. Download this file and stick it in the /includes folder.

    [url=http://pajhome.org.uk/crypt/md5/md5.js]http://pajhome.org.uk/crypt/md5/md5.js[/url]

    2. Include the script in the <head> section of the login.php page i.e.

    <script type="text/javascript" src="include/md5.js"></script>

    3. Change the following code in your login.php!

    Line 37: Change from this
    [code] WHERE user_email = '$userEmail' AND user_password = md5('$password')";[/code]

    Line 37: To this
    [code] WHERE user_email = '$userEmail' AND user_password = ('$password')";[/code]

    Line 100: Change from this
    [code]<input name="pass" type="password" id="pass"/>[/code]

    Line 100: To this
    [code]<input name="password" type="text" id="password"/>
    <input name="pass" type="hidden" id="pass"/>[/code]

    Line 108: Change from this
    [code]<input type="submit" value="login" />[/code]

    Line 108: To this
    [code]<input type="submit" value="login" onclick="pass.value = hex_md5(password.value)" />[/code]

    Ok I think that's everything. I've tried it and it seems to work okay.
    It's far from perfect but should be a lot better than before.
    Basically the onclick uses javascript (client-side) to hash whatever value you enter into the password input field and stores it in the 'pass' variable which is then processed by the php script.

    Make sure you remove the md5 from md5('$password') on line 37 else the the password will be hashed twice meaning a different value!

    Oh and I haven't aloud for normal non-javascript login with these changes so javascript MUST be enabled for this to work. The hasing could also be enabled on the username field for extra security I guess!!

    Only other option is to make it a config option as Justin suggested.
    However I have no need for this hashing myself as I'm using SI locally.

    Caver maybe you would like to sniff out this way to make sure it's working as it should!! Careful where you sniff though...

    Regards

    Danny
    • CommentAuthordanfloun
    • CommentTimeApr 5th 2007 edited
     permalink
    Possibly another option if are running apache is to disable the login in SI and then create a .htaccess file on the server for the SI directory.

    You could make the .htaccess file as strict as you want.

    Danny
    • CommentAuthorjustin
    • CommentTimeApr 6th 2007 edited
     permalink
    Hey All,

    re .htacess
    -- unfortunately PDF stops working if you use .htaccess to password protect Simple Invoices :(
    --- note .htaccess for mod_rewrite stuff is OK though

    re Aplysia
    - very good point

    re Danny - javascript
    - thanks for posting that, much appreciated!!
    -- re javascript to validate
    --- this is soon to be removed - were going back to a php solution
    -- re javascript
    --- its not that i dont like javascript - its just been causing me pain recently with certain browsers not liking certain javascript, when you change 1 thing it works OK in firefox but breaks another browser etc. etc.. whereas all browsers like normal PHP, even IE and Safari :)

    - i'll look at adding the javascript login stuff - but no promises - might just add instructions to the wiki for the security paranoid people on how to enable this

    Caver - any chance you can test out the javascript stuff and see if you can still sniff the password?

    Thanks again everyone!!!!

    Conclusion: the real solution to security is SSL and HTTPS but if you cant do that for some reason Danny's javascript work is a great workaround

    I'll document this properly and add it to the wiki for future reference - link to come soon

    Cheers

    Justin
    • CommentAuthorcaver
    • CommentTimeApr 8th 2007 edited
     permalink
    Like I said I really want this to be in the Official release, So I did it with an option........ Hopefully justin will add it....

    Also if you just use MD5's that's good.......... but if you add a challenge system that's better (Because the MD5ed Password doesn't just become the "New" Password With a challenge system the clear MD5 is never sent, so you can't get it sniffing, and without either the md5 of the password, or the password itself you can't get access)...

    SO...................

    First change add MD5.js to include folder

    2nd change: Add two Config Variables to Config.php

    /*If you want JavaScript MD5 hashing to occur so that you can run Simple Invoices on a Non-Https Server with better security Turn Uncomment MD5Auth, Generally if you do that you should turn on ChallengeLife too. ChallengeLife sets how long before a Challenge leaving the server expires in minutes (480 is a good number I think). Defaults to Off (Please don't use Simple invoices with this off, on an non- https internet server) */
    $MD5Auth = FALSE;
    $ChallengeLife = 0;

    3rd change: We need a new table in the database to monitor Challenges (comment in Login.php):

    CREATE TABLE `si_challenges` (
    `challenges_key` INT( 11 ) NOT NULL ,
    `challenges_timestamp` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
    );

    4th change: Rework login.php


    If you need explanation on why I did certain things just ask... Mostly I tried not to mess with justins flow, and I tried to make sure if you left both of my config options at False and 0 the program would generally behave like it used to....

    I still haven't tested it throughly but I did make sure that with True and 480 it works....
    Here's what my login.php looks like:

    [code]<?php
    // we must never forget to start the session
    /*
    CREATE TABLE si_users (
    user_id int(11) NOT NULL auto_increment,
    user_email VARCHAR(100) NOT NULL,
    user_name VARCHAR(100) NOT NULL,
    user_group VARCHAR(10) NOT NULL,
    user_domain VARCHAR(10) NOT NULL,
    user_password CHAR(32) NOT NULL,

    PRIMARY KEY (user_id)
    );

    INSERT INTO si_users (user_id, user_email, user_name, user_group, user_domain, user_password) VALUES ('','guest@simpleinvoices.org','guest','1','1', md5('guest'));
    INSERT INTO si_users (user_id, user_email, user_name, user_group, user_domain, user_password) VALUES ('','demo@simpleinvoices.org','demo','1','1', md5('demo'));
    INSERT INTO si_users (user_id, user_email, user_name, user_group, user_domain, user_password) VALUES ('','admin@simpleinvoices.org','admin','1','1', md5('admin'));

    CREATE TABLE `si_challenges` (
    `challenges_ key` INT( 11 ) NOT NULL ,
    `challenges_ timestamp` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
    );

    */

    include 'config/config.php';
    include "lang/$language.inc.php";
    include "include/hmacmd5.php";
    session_start();

    $errorMessage = '';
    if (isset($_POST['user']) && isset($_POST['pass'])) {

    $conn = mysql_connect( $db_host, $db_user, $db_password);
    mysql_select_db( $db_name, $conn);

    $userEmail = $_POST['user'];
    if ($_POST['pass'] == $_POST['md5']){
    $password = $_POST['pass'];
    }
    else {
    if($MD5Auth==True){
    $NoJSonClient=True;
    }
    $password = md5($_POST['pass']);
    }
    if ($ChallengeLife>0){
    $ChallengeKeySubmitted = $_POST['ChallengeKey'];
    }

    // Grab Password from database
    $sql = "SELECT *
    FROM si_users
    WHERE user_email = '$userEmail' ";

    $result = mysql_query($sql, $conn) or die('Query failed. ' . mysql_error());
    $credentials = mysql_fetch_array($result);
    $storedPassword=$credentials[user_password];



    if ($ChallengeLife>0) {
    $DeleteOldChallenges = 'DELETE FROM `si_challenges` WHERE `challenges_timestamp` < DATE_SUB(now(),INTERVAL $ChallengeLife Minute)';
    mysql_query($DeleteOldChallenges, $conn);
    $sql = "SELECT *
    FROM si_challenges
    WHERE challenges_key = '$ChallengeKeySubmitted' ";
    $result = mysql_query($sql, $conn) or die('Query failed. ' . mysql_error());
    # echo "Found or not the key in DB";
    if (mysql_num_rows($result) >= 1) {
    //Challenge was valid
    # echo $ChallengeKeySubmitted;
    $DeleteUSEDChallenge = 'DELETE FROM `si_challenges` WHERE `challenges_key` = `$ChallengeKeySubmitted`limit 1';
    mysql_query($DeleteUSEDChallenge, $conn);
    # echo "Deleted Used Key $ChallengeKeySubmitted";
    if($password==hmac_md5($ChallengeKeySubmitted, "$storedPassword")){
    $_SESSION['db_is_logged_in'] = true;
    // after login we move to the main page
    header('Location: .');
    exit;
    } else {
    # echo $ChallengeKeySubmitted;
    $DB=hmac_md5($ChallengeKeySubmitted, "$storedPassword");
    $errorMessage = "Sorry, wrong user / password";
    }
    } else {
    $errorMessage = 'Sorry, the login timed out. Please try again';
    }
    }elseif ($password==$storedPassword){
    $_SESSION['db_is_logged_in'] = true;
    // after login we move to the main page
    header('Location: .');
    exit;
    }else {
    $errorMessage = 'Sorry, wrong user / password';
    }
    }

    if($ChallengeLife>0) {
    $Challenge_Key=Rand(0,99999999999);
    # $Challenge_Key=1;
    $conn = mysql_connect( $db_host, $db_user, $db_password);
    mysql_select_db( $db_name, $conn);
    mysql_query("INSERT INTO si_challenges (challenges_key) VALUES ($Challenge_Key)",$conn);
    }

    ?>
    <html>
    <head>

    <?php if($MD5Auth==True){?>

    <script src="include/md5.js"></script>
    <script language="JavaScript"><!--

    function login(f) {

    <?php if ($ChallengeLife>0){?>
    f['md5'].value = hex_md5(f['pass'].value);
    f['pass'].value = hex_hmac_md5(f['ChallengeKey'].value, f['md5'].value);
    f['md5'].value = hex_hmac_md5(f['ChallengeKey'].value, f['md5'].value);
    <?php } else {?>
    f['md5'].value = hex_md5(f['pass'].value);
    f['pass'].value = hex_md5(f['pass'].value);
    <?php }?>

    return true;

    }

    //--></script>

    <?php }?>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Simple Invoices Login</title>
    <link rel="stylesheet" type="text/css" href="src/include/css/login.css">

    </head>

    <body class="login" >
    <div class="Container">
    <?php if($MD5Auth==True){?>
    <noscript>
    <p align="center"><strong><font color="#990000">JavaScript must be enabled for MD5 login.</font></strong></p>
    </noscript>

    <?php
    }
    if ($errorMessage != '') {
    ?>
    <p align="center"><strong><font color="#990000"><?php echo $errorMessage; ?></font></strong></p>
    <?php
    }
    ?>
    <div id="Dialog">
    <!--
    <div align=center id="disclaimerbox">
    <img src="./images/common/important.png"></img>
    <strong>Annoucement<br /></strong><br>This is an important annoucement
    <hr></hr>
    </div>
    -->
    <h1>Simple Invoices</h1>
    <!--
    <div id="loginbox" class="hasDisclaimer" >

    <div id="formbox">
    -->

    <form action="" method="post" name="frmLogin" id="frmLogin" <?php if($MD5Auth==True){?>onSubmit="return login(this);"<?php }?>>
    <input type="hidden" name="action" value="login" />
    <input type="hidden" name="cookieverify" value="" />
    <input type="hidden" name="redirect" value="" />

    <?php if($MD5Auth==True){?>
    <input type="hidden" name="md5" value="">
    <?php }?>
    <?php if($ChallengeLife>0){?>
    <input type="hidden" name="ChallengeKey" value="<?php echo $Challenge_Key;?>">
    <?php }?>

    <dl>
    <dt>Email:</dt>
    <dd><input name="user" type="text" id="user" /></dd>

    <dt>Password:</dt>
    <dd>
    <input name="pass" type="password" id="pass" />
    <!--
    <span>(<a href="login.php">I forgot my password/username</a>)</span>
    -->
    </dd>

    <dd><input type="checkbox" name="remember_me" /> Remember me on this computer</dd>
    <dd> <input type="submit" value="login" /></dd>
    <!-- <dd><input type="submit" value="Sign in" /></dd> -->
    <!--
    <label for="username">Username</label>
    <input name="user" type="text" id="user"/>
    <BR>
    <label for="password">Password</label>
    <input name="pass" type="password" id="pass"/>
    -->
    <!--
    <label for="language">Language</label>
    <select id="language" name="language">
    <option value="en" SELECTED="yes">English (United States)</option>

    </select>
    -->
    <!--
    <div class="form_actions">
    <dd> <input type="submit" value="login" /></dd>
    </div>
    -->
    </dl>
    </form>

    </div>


    </div>





    <!--
    <form action="" method="post" name="frmLogin" id="frmLogin">
    <table width="400" border="1" align="center" cellpadding="2" cellspacing="2">
    <tr>
    <td width="150">User Id</td>
    <td><input name="txtUserId" type="text" id="txtUserId"></td>
    </tr>
    <tr>
    <td width="150">Password</td>
    <td><input name="txtPassword" type="password" id="txtPassword"></td>
    </tr>
    <tr>
    <td width="150">&nbsp;</td>
    <td><input name="btnLogin" type="submit" id="btnLogin" value="Login"></td>
    </tr>
    </table>
    </form>
    -->

    </body>
    </html>
    [/code]

    And my packet sniffing Results (2 successful login attempts below, notice how the Password changes because of the challenge):


    12:41:33 - 08.04.2007 Protocol: TCP Service: HTTP
    Source Address: 10.15.20.10 Destination Address: 64.247.42.189
    Source Port: 3919 Destination Port: 80
    45 00 01 20 f2 66 40 00 80 06 7d a4 0a 0f 14 0a 40 f7 E f@ } @
    2a bd 0f 4f 00 50 ed a5 87 d8 f6 5c e5 ed 50 18 80 52 * O P \ P R
    aa 23 00 00 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 # Content-Type:
    61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 77 77 77 2d application/x-www-
    66 6f 72 6d 2d 75 72 6c 65 6e 63 6f 64 65 64 0d 0a 43 form-urlencoded C
    6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 31 37 36 ontent-Length: 176
    0d 0a 0d 0a 61 63 74 69 6f 6e 3d 6c 6f 67 69 6e 26 63 action=login&c
    6f 6f 6b 69 65 76 65 72 69 66 79 3d 26 72 65 64 69 72 ookieverify=&redir
    65 63 74 3d 26 6d 64 35 3d 34 62 37 62 33 61 63 34 31 ect=&md5=4b7b3ac41
    65 65 33 31 35 38 36 39 32 63 37 34 36 30 36 63 30 31 ee3158692c74606c01
    37 30 65 37 30 26 43 68 61 6c 6c 65 6e 67 65 4b 65 79 70e70&ChallengeKey
    3d 31 32 30 33 30 31 31 33 36 34 26 75 73 65 72 3d 63 =1203011364&user=c
    61 76 65 72 25 34 30 63 6f 6d 70 75 74 65 72 61 75 74 aver%40computeraut
    68 6f 72 69 74 79 68 61 77 61 69 69 2e 63 6f 6d 26 70 horityhawaii.com&p
    61 73 73 3d 34 62 37 62 33 61 63 34 31 65 65 33 31 35 ass=4b7b3ac41ee315
    38 36 39 32 63 37 34 36 30 36 63 30 31 37 30 65 37 30 8692c74606c0170e70


    12:43:36 - 08.04.2007 Protocol: TCP Service: HTTP
    Source Address: 10.15.20.10 Destination Address: 64.247.42.189
    Source Port: 3922 Destination Port: 80
    45 00 01 1f f3 0d 40 00 80 06 7c fe 0a 0f 14 0a 40 f7 E @ | @
    2a bd 0f 52 00 50 3e a1 b7 05 fb bd 5b 52 50 18 7f cd * R P> [RP 
    a7 33 00 00 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 3 Content-Type:
    61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 77 77 77 2d application/x-www-
    66 6f 72 6d 2d 75 72 6c 65 6e 63 6f 64 65 64 0d 0a 43 form-urlencoded C
    6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 31 37 35 ontent-Length: 175
    0d 0a 0d 0a 61 63 74 69 6f 6e 3d 6c 6f 67 69 6e 26 63 action=login&c
    6f 6f 6b 69 65 76 65 72 69 66 79 3d 26 72 65 64 69 72 ookieverify=&redir
    65 63 74 3d 26 6d 64 35 3d 39 36 35 33 37 38 36 38 62 ect=&md5=96537868b
    34 61 66 34 38 30 63 35 38 61 65 66 31 63 37 35 30 37 4af480c58aef1c7507
    33 39 64 39 65 26 43 68 61 6c 6c 65 6e 67 65 4b 65 79 39d9e&ChallengeKey
    3d 33 35 34 37 32 35 35 33 35 26 75 73 65 72 3d 63 61 =354725535&user=ca
    76 65 72 25 34 30 63 6f 6d 70 75 74 65 72 61 75 74 68 ver%40computerauth
    6f 72 69 74 79 68 61 77 61 69 69 2e 63 6f 6d 26 70 61 orityhawaii.com&pa
    73 73 3d 39 36 35 33 37 38 36 38 62 34 61 66 34 38 30 ss=96537868b4af480
    63 35 38 61 65 66 31 63 37 35 30 37 33 39 64 39 65 c58aef1c750739d9e

    (sorry for taking so long... You know.... Real Life and all.... But I did it within the week I gave myself)


    Chris
    • CommentAuthordanfloun
    • CommentTimeApr 8th 2007 edited
     permalink
    Thats great. I saw the challenge system, but frankly I never had the interest to take it further. :D

    What happens if javascript is disabled in the browser?

    If in the config it is set to use javascript, there should also be a check to verify java is enabled in browser! else reverts back to old system.

    Danny
    • CommentAuthorcaver
    • CommentTimeApr 8th 2007 edited
     permalink
    Something like that..........

    If config is set to use it, but javascript isn't on in the browser, it displays a message in the browser stating that "JavaScript must be enabled for MD5 login." It then basically reverts to the old system.

    There may be a small problem if javascript is ON in the browser but it can't use the MD5 file... (I don't see how but if the browser tried to do the javascript, but botched it and sent in the un-evaulated string of "hex_hmac_md5(f['ChallengeKey'].value, f['md5'].value)" or something) that would (obviously) cause problems...

    But Firefox, IE, safari, and Konqueror all liked the script before (I haven't tested it on anything but Firefox, since about errr a year ago)... It's also a relatively simple script, so it shouldn't be a problem....


    Chris
    • CommentAuthorjustin
    • CommentTimeApr 9th 2007 edited
     permalink
    Thanks guy for all your work!!!!

    i'll look at this over the next few days - ive been away for easter

    Cheers

    Justin
    • CommentAuthorjustin
    • CommentTimeApr 14th 2007 edited
     permalink
    Hey Caver,

    just looking add your posts now (note: my attention span is limited so it took awhile to get to reading all the posts correctly :) ), awesome work on the challenge system!!!!!!!

    question:
    if i set $MD5Auth = FALSE; in config.php does that mean the current (non js) login work is used instead of the new js based one
    - if so thats great and i'll add it into Simple Invoices - just gotta think what if some people dont have javscript enabled etc.. just thinking about PDAs, mobile internet handhelds etc (that may not have js) that i would like Simple Invoices to work with in the long run.

    Cheers

    Justin
    • CommentAuthorcaver
    • CommentTimeApr 15th 2007 edited
     permalink
    Correct, If $MD5Auth = FALSE; and $ChallengeLife = 0; it works basically the way it did before*.

    If $ChallengeLife > 0 but $MD5Auth = FALSE upon another look at my code fails every login... :( (I'll post a fix soon)

    No matter what, when $MD5Auth = TRUE; if javascript is turned off in the browser it reverts to the old system of not using javascript.

    The only time the changes could be a problem is if javascript is ON in the browser, $MD5Auth=TRUE and the browser attempts to but fails at executing the javascript. If that happens you can either make $MD5Auth=FALSE and it will be using the old system, or you can turn javascript off in the browser and (assuming the browser doesn't have some kind of "no turning off javascript" bug/feature) it'll work the way it used to.

    * When I say it will work the way it used to I'm saying that it will accept a non-md5 hashed password, and let php md5 hash it.... Then check it against the database... The code itself has been changed to accept the hashes and works slightly different then the old code.

    If you really care the difference is the old code Searched the database for a username and password that basically matched the submitted values... My code Searches the database for a username that matches the submitted variables, if it exists, stores the password for that username in a variable, then dependent on the configuration (MD5Auth, ChallengeLife, as well as weather the javascript looks like it ran) compares the submitted password to what php calculates the database has stored for that username.

    So leave them both at their defaults it works the same way as before, Change MD5Auth = TRUE and it's doing MD5 Hashing on the client end protecting from Sniffing, Set the ChallengeLife = <something Bigger then 0> and even if they sniff the Hashed password they can't use that either....

    Later,
    Chris
    • CommentAuthorjustin
    • CommentTimeApr 15th 2007 edited
     permalink
    Thanks Chris,

    Once you post your fix for
    If $ChallengeLife > 0 but $MD5Auth = FALSE upon another look at my code fails every login... (I'll post a fix soon)


    i'll put this code into Simple Invoices, Thanks again

    also as you seem to be security concerned (im not :) ) can you check thought the Simple Invoices authentication system to see if theres any security holes - it would be a great help!!!

    Cheers

    Justin
    • CommentAuthorjustin
    • CommentTimeApr 17th 2007 edited
     permalink
    • CommentAuthorjustin
    • CommentTimeApr 17th 2007 edited
     permalink
    Hey Chris,

    Just adding this code into svn for testing but notice the reference to a new file
    include(include/hmacmd5.php)

    is this required? if so can you post it to the forum as well

    Cheers

    Justin
    • CommentAuthorjustin
    • CommentTimeApr 17th 2007 edited
     permalink
    Hey Chris,

    got this from squirrelmail code, is this the same code as in your include(include/hmacmd5.php)


    /**
    * Creates a HMAC digest that can be used for auth purposes.
    * See RFCs 2104, 2617, 2831
    * Uses mhash() extension if available
    *
    * Squirrelmail has this function in functions/auth.php, and it might have been
    * included already. However, it helps remove the dependancy on mhash.so PHP
    * extension, for some sites. If mhash.so _is_ available, it is used for its
    * speed.
    *
    * This function is Copyright (c) 1999-2003 The SquirrelMail Project Team
    * Licensed under the GNU GPL. For full terms see the file COPYING.
    *
    * @param string $data Data to apply hash function to.
    * @param string $key Optional key, which, if supplied, will be used to
    * calculate data's HMAC.
    * @return string HMAC Digest string
    */
    function hmac_md5($data, $key='') {
    // See RFCs 2104, 2617, 2831
    // Uses mhash() extension if available
    if (extension_loaded('mhash')) {
    if ($key== '') {
    $mhash=mhash(MHASH_MD5,$data);
    } else {
    $mhash=mhash(MHASH_MD5,$data,$key);
    }
    return $mhash;
    }
    if (!$key) {
    return pack('H*',md5($data));
    }
    $key = str_pad($key,64,chr(0x00));
    if (strlen($key) > 64) {
    $key = pack("H*",md5($key));
    }
    $k_ipad = $key ^ str_repeat(chr(0x36), 64) ;
    $k_opad = $key ^ str_repeat(chr(0x5c), 64) ;
    /* Heh, let's get recursive. */
    $hmac=hmac_md5($k_opad . pack("H*",md5($k_ipad . $data)) );
    return $hmac;
    }


    Cheers

    Justin
    •  
      CommentAuthorxurizaemon
    • CommentTimeJun 30th 2007 edited
     permalink
    Javascript MD5 will not really help us secure the traffic, because MD5 is not secure.

    Anyone who knows how to use a packet sniffer will have no trouble taking your "encrypted" md5 hash off to read it at md5lookup.com ... they probably already have a browser plugin for exactly that ;)

    If you want to prevent this, you need to look into encrypting all your traffic, which requires SSL. Client-side MD5 is just sweeping your password under the rug.

    Chris, no disrespect intended to the obvious effort you've put into this one, but MD5 is not really going to help secure things. SSL will.
    • CommentAuthorstuey
    • CommentTimeAug 19th 2007 edited
     permalink
    My big question is this:

    If your using this over the wire, then why aren't you using SSL, that encrypts the content point to point, involves little changes on the part of simple invoices. Its is pure and simple the only way to go is SSL.

    At the end of the day you hold all this information out there on the internet, so all the security in the world wont help if your server gets hacked. I run xampp off a USB stick take a backup every Sunday and all is well. All of the feature which are in Simple invoices work fine and nothings at risk, even if I lost the Key, I have a password manager on there:)

    my 2 cents