From 47ec4bc368e67a3dd7b4c94d5eb39aae07419f89 Mon Sep 17 00:00:00 2001
From: Rob van Son
+There are four default accounts present: testip, test, testchallenge, and +admin. The former three have password testing, the latter has password +There is no password like more password. The admin +account is disabled by default. You can enable it with a new password +using the --managelogin option. All four accounts are limited to local +(localhost) requests. When present, testip, test, and +testchallenge are reactivated with the default password testing +whenever a new SALT is automatically generated. It is adviced that the test +accounts are removed when setting up a site. +
The session authentication mechanism is based on the exchange of ticket @@ -1722,7 +1733,7 @@ and Client, a man in the middle attack (MITM), could change the code to reveal the plaintext password and other information. There is no real protection against this attack without end-to-end encryption and authentication. A simple, but rather cumbersome, way to check for such -attacks would be to store known good copys of the pages (downloaded +attacks would be to store known good copies of the pages (downloaded with a browser or automatically with curl or wget) and then use other tools to download new pages at random intervals and compare them to the old pages. For instance, the following line would remove the diff --git a/CGIscriptor.pl b/CGIscriptor.pl index 7d818bd..077ba40 100755 --- a/CGIscriptor.pl +++ b/CGIscriptor.pl @@ -1946,6 +1946,16 @@ if(grep(/\-\-help/i, @ARGV)) # password='NewPassword' \ # Private/.Passwords/newuser # +# There are four default accounts present: testip, test, testchallenge, and +# admin. The former three have password 'testing', the latter has password +# 'There is no password like more password'. The admin +# account is disabled by default. You can enable it with a new password +# using the --managelogin option. All four accounts are limited to local +# (localhost) requests. When present, testip, test, and +# testchallenge are reactivated with the default password testing +# whenever a new SALT is automatically generated. It is adviced that the test +# accounts are removed when setting up a site. +# # # Implementation # @@ -2031,7 +2041,7 @@ if(grep(/\-\-help/i, @ARGV)) # reveal the plaintext password and other information. There is no # real protection against this attack without end-to-end encryption and # authentication. A simple, but rather cumbersome, way to check for such -# attacks would be to store known good copys of the pages (downloaded +# attacks would be to store known good copies of the pages (downloaded # with a browser or automatically with curl or wget) and # then use other tools to download new pages at random intervals and compare # them to the old pages. For instance, the following line would remove diff --git a/CGIservlet.html b/CGIservlet.html index 2d0cc08..a6eb795 100644 --- a/CGIservlet.html +++ b/CGIservlet.html @@ -23,7 +23,7 @@ SIMPLICITY, and not mileage.
Note that a HTTP server can be accessed on your local machine WITHOUT -internet access (but WITH a DNS?): +internet access: use "http://localhost[:port]/[path]" or "http://127.0.0.1[:port]/[path]" as the URL. It is also easy to restrict access to the servlet to localhost users (i.e., the computer running the servlet). diff --git a/JavaScript/CGIscriptorSession.js b/JavaScript/CGIscriptorSession.js index fbc3fd4..ce7220c 100644 --- a/JavaScript/CGIscriptorSession.js +++ b/JavaScript/CGIscriptorSession.js @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * - * Copyright 2012-2013 Rob van Son + * Copyright 2012-2014 Rob van Son * email: R.J.J.H.vanSon@gmail.com * NKI-AVL Amsterdam */ @@ -138,7 +138,7 @@ function eraseCookie(name) { }; // Combine the PASSWORD with the site SERVERSALT and hash it -// Combine this Hash iwth the extra SERVERSALT, and hash them +// Combine this Hash with the extra SERVERSALT, and hash them function HashPassword(extsalt) { var hash = HashSessionSeed(extsalt); var password = document.getElementById('PASSWORD'); @@ -185,7 +185,7 @@ function SetSecretKey() { return secretkey; }; -// Hash(sessionseed+hash(password+username.toLowerCase()+salt)) +// Hash(hash(password+username.toLowerCase()+salt) + sessionseed) function HashSessionSeed(sessionseed) { var hash1 = ""; var hash2 = ""; diff --git a/Private/.Passwords/admin b/Private/.Passwords/admin index 79490f1..b796fb6 100644 --- a/Private/.Passwords/admin +++ b/Private/.Passwords/admin @@ -1,11 +1,11 @@ Type: INACTIVE PASSWORD Username: admin -Password: 51ec9f11628b4f81ba7130b12db5a36a46a5b13c3ae4fac95f2cebd05b3bae92 +Password: cd014d8507c205cd0b714579317f823934e702659242c6cbaba7a7a144ec9f2d IPaddress: 127.0.0.1 AllowedPaths: ^/Private/ AllowedPaths: ^/Private/?$ Capabilities: CreateUser -Salt: 9cdfb6f8563110aaf9271d950f47ed84fe343374e96a7970227d21826fb65808 +Salt: 29ea92e1a4c20911a30dd7657c33ea763bcef1738c9abea6f367c18f60086a45 Session: CHALLENGE Signature: 864bbfab09292e6cb085adf92eb412831e3cc9057d859c24e0e2d12456edc66c Comment: 1 Replace 'INACTIVE PASSWORD' by 'PASSWORD' diff --git a/Private/.Passwords/test b/Private/.Passwords/test index 9180856..d057fdc 100644 --- a/Private/.Passwords/test +++ b/Private/.Passwords/test @@ -1,12 +1,12 @@ Type: PASSWORD Username: test -Password: 133668d577cd420efb4c0915f1a69057775f2e071a9f088a391a79371f8807b3 +Password: ee7a489e52f849be495eda54b032b5d88167fc5e18471b0737137e7843bee506 IPaddress: 127.0.0.1 AllowedPaths: ^/Private/CreateUser\.html AllowedPaths: ^/Private/index\.html$ AllowedPaths: ^/Private/[^/]+\.html$ AllowedPaths: ^/Private/?$ -Salt: 9cdfb6f8563110aaf9271d950f47ed84fe343374e96a7970227d21826fb65808 +Salt: 29ea92e1a4c20911a30dd7657c33ea763bcef1738c9abea6f367c18f60086a45 Session: SESSION Signature: 42ab80fc6bff6dd62589f571407e902fff16080442df642790a1048e3a1b6189 MaxLifetime: +12h diff --git a/Private/.Passwords/testchallenge b/Private/.Passwords/testchallenge index ffc16db..2c53115 100644 --- a/Private/.Passwords/testchallenge +++ b/Private/.Passwords/testchallenge @@ -1,12 +1,12 @@ Type: PASSWORD Username: testchallenge -Password: bd27324f1b2c9c7ec6eb161369ce1a1ee591f1c359c56c49619da568ea28b7fc +Password: bcca16fd21f0dcb404d6379464539819cdd105b4b1920deb932b32dd4f0b2cb0 IPaddress: 127.0.0.1 AllowedPaths: ^/Private/index\.html$ AllowedPaths: ^/Private/[^/]+\.html$ AllowedPaths: ^/Private/?$ Capabilities: VariableREMOTE_ADDR -Salt: 9cdfb6f8563110aaf9271d950f47ed84fe343374e96a7970227d21826fb65808 +Salt: 29ea92e1a4c20911a30dd7657c33ea763bcef1738c9abea6f367c18f60086a45 Session: CHALLENGE Signature: 993b7ac9d14cc7eaee0f9bd01635728d6b0684e052afaf1e0960b255d3f850f3 MaxLifetime: +45m diff --git a/Private/.Passwords/testip b/Private/.Passwords/testip index 5a09743..8aec866 100644 --- a/Private/.Passwords/testip +++ b/Private/.Passwords/testip @@ -1,12 +1,12 @@ Type: PASSWORD Username: testip -Password: 8681965d479becc4f89f18f30aacd7408a119e5da4d80bace488f87b935cad5d +Password: 1454c53156a36db35ddd7acc2a41940ed7395022ef802ecb01d2fda6f136d884 IPaddress: 127.0.0.1 AllowedPaths: ^/Private/index.html$ AllowedPaths: ^/Private/[^/]+.html$ AllowedPaths: ^/Private/?$ DeniedPaths: ^/Private/CreateUser.html.*$ -Salt: 9cdfb6f8563110aaf9271d950f47ed84fe343374e96a7970227d21826fb65808 +Salt: 29ea92e1a4c20911a30dd7657c33ea763bcef1738c9abea6f367c18f60086a45 Session: IPADDRESS Signature: 56ecb2bea845af9f7a7f46896ae3c018a2682b1282fff229a8b501269fc93de2 MaxLifetime: +6h diff --git a/Private/Login.html b/Private/Login.html index 0240b78..24f516e 100644 --- a/Private/Login.html +++ b/Private/Login.html @@ -19,7 +19,7 @@
Simple and very unsafe example login page for CGIscriptor.pl. The password is first hashed with the - site specific salt (as it is used to store the password on-site). Then it is hashed with a random, + username and site specific salt (as it is used to store the password on-site). Then it is hashed with a random, one-time salt. Effectively, creating a one-time password. Only the last value is send to the server. The server has both salt values stored. It will ignore anything except the username, hashed password, and loginticket. @@ -72,7 +72,7 @@ There is no real protection against this attack without end-to-end encryption an authentication. See the Manual (login required).
Example Login page for CGIscriptor.pl
- Copyright © 2012-2013 R.J.J.H. van Son
+ Copyright © 2012-2014 R.J.J.H. van Son
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
diff --git a/Private/manual.html b/Private/manual.html
index 1d65aa6..51a6057 100644
--- a/Private/manual.html
+++ b/Private/manual.html
@@ -99,12 +99,12 @@ Accounts can include a maximal lifetime for session tickets (MaxLifetime).
A Login page should create a LOGIN ticket file locally and send a
server specific salt, a Random salt, and a LOGIN ticket
identifier. The server side compares the username and hashed password,
-actually hashed(hashed(password+serversalt)+Random salt) from the client with
-the values it calculates from the stored Random salt from the LOGIN
-ticket and the hashed(password+serversalt) from the PASSWORD ticket. If
-successful, a new SESSION ticket is generated as a (double) hash sum of
-the LOGIN ticket and the stored password, i.e.
-LoginTicket = hashed(hashed(password+serversalt)+REMOTE_HOST+Random salt) and
+actually hashed(hashed(password+username+serversalt)+ REMOTE_ADDR + Random salt)
+from the client with the values it calculates from the stored Random salt from
+the LOGIN ticket and the hashed(password+username+serversalt) from the
+PASSWORD ticket. If successful, a new SESSION ticket is generated as a (double)
+hash sum of the LOGIN ticket and the stored password, i.e.
+LoginTicket = hashed(hashed(password+username+serversalt)+Random salt) and
SessionTicket = hashed(hashed(LoginTicket).LoginTicket).
This SESSION ticket should also be generated by the client and stored as
sessionStorage and cookie values as needed. The Username, IP address and
@@ -224,6 +224,17 @@ hash function (SHA256) is used to create a one-way hash sum "encryption".
A new password must be decrypted. New passwords are encryped by XORing
them with the old password.
+There are four default accounts present: testip, test, testchallenge, and +admin. The former three have password testing, the latter has password +There is no password like more password. The admin +account is disabled by default. You can enable it with a new password +using the --managelogin option. All four accounts are limited to local +(localhost) requests. When present, testip, test, and +testchallenge are reactivated with the default password testing +whenever a new SALT is automatically generated. It is adviced that the test +accounts are removed when setting up a site. +
If you only could see what you are typing
@@ -267,17 +278,41 @@ and Client, a man in the middle attack (MITM), could change the code to reveal the plaintext password and other information. There is no real protection against this attack without end-to-end encryption and authentication. -A solution for the MITM attack problem to protect at least the password input -would be to run a trusted copy of the web page from local storage to handle password input. -An example of such a solution has been implemented for IPADDRESS sessions and -plain SESSION ticket only. This Login.html page has four comment lines saying:+A simple, but rather cumbersome, way to check for such +attacks would be to store known good copies of the pages (downloaded +with a browser or automatically with curl or wget) and +then use other tools to download new pages at random intervals and compare +them to the old pages. For instance, the following line would remove the +variable ticket codes and give a fixed SHA256 sum for the original +Login.html page+code: +
+curl http://localhost:8080/Private/index.html | sed 's/=\"[a-z0-9]\{64\}\"/=""/g' | shasum -a 256 ++A simple diff command between old and new files should give +only differences in half a dozen lines, where only hexadecimal salt +values will actually differ. + +
+A sort of solution for the MITM attack problem that might protect at +least the plaintext password would be to run a trusted web +page from local storage to handle password input. The solution would be +to add a hidden iFrame tag loading the untrusted page from the URL and +extract the needed ticket and salt values. Then run the stored, trusted, +code with these values. It is not (yet) possible to set the required session storage inside the browser, so this method only works -for IPADDRESS sessions and plain SESSION tickets, not for the CHALLENGE sessions. +for IPADDRESS sessions and plain SESSION tickets. There are many security +problems with this "solution".
- ++If you are able to ascertain the integrity of the login page using any +of the above methods, you can check whether the IP address seen by the +login server is indeed the IP address of your computer. The IP address +of the REMOTE_HOST (your visible IP address) is part of the login +"password". It is stored in the login page as a CLIENTIPADDRESS. It can +can be inspected by clicking the "Check IP address" box. Provided the +MitM attacker cannot spoof your IP address, you can ensure that the login +server sees your IP address and not that of an attacker. +