Discord and Security UI Patterns

20 Jun 2020

I've been using web browser cookie-based login for Discord. Recently my main laptop crashed. Now using an old standby laptop, I visit Discord and am prompted for password. No problem, I have it in my password safe that is backed up regularly. Password ok, now prompted for 2FA. Hmmm, 2FA fails...

Right, seems I have been using cookie-based login for so long that, during that time, I bought a new phone and sold the old phone. For 2FA, I use Duo Mobile, and it is phone-specific:

Since Duo Mobile is tied to a specific device's hardware security module (HSM), you will need to reinstall and reactivate Duo Mobile on a new phone.

No biggie, this is only Discord. I'll make a new account. Ok done. Login again. Discord repeatedly says, for my new account, "We've detected something out of the ordinary going on. To continue using Discord, we will need you to verify your account." And the single option presented is to verify by phone. That's an easy decision: No Discord, you are not getting my mobile phone number.

A few things to think about, in no particular order, from both user and system engineering perspectives:

  • I am willing to use cookie-based login for Discord. Probably need not have enabled 2FA. If a user enables cookie login, perhaps prompt to turn off 2FA, or do it automatically?

  • With a password safe, my Discord password is randomly generated gibberish. Is that, combined with good integration of safe and browser, better than using cookie-based login? Am I applying resume-padding thinking here?

  • As a user, RTF2FAM. As a system engineer, expect no user to.

  • The corporate IT world practises periodic security credentials review. Overkill for an individual to do it like they do, but this situation has motivated me to relook at my password safe, Duo Mobile accounts and a few other things.

  • Think hard about asking for people's mobile phone numbers. If you do it, don't 'explain' it with weasel words like Discord has done. Yeah yeah, I'm not paying $$ to use Discord, therefore they want me to pay with my personal data. I get that. I say no.

  

Tags: security

Updating OpenSSL for Pharo

06 Jun 2020

Pharo is transitioning from OpenSSL 1.0.x to OpenSSL 1.1.1. There are C API changes between the two OpenSSL versions that break many tests, basic things like XXX_create() becoming XXX_new(), XXX_init() becoming XXX_reset() etc. As such, I've created the branches openssl_1_0 and openssl_1_1 to match the versions used by Pharo.

To load, for OpenSSL 1.0.x:

Metacello new
  baseline: 'OpenSSL';
  repository: 'github://PierceNg/OpenSSL-Pharo:openssl_1_0/src-st';
  load.

To load, for OpenSSL 1.1.x:

Metacello new
  baseline: 'OpenSSL';
  repository: 'github://PierceNg/OpenSSL-Pharo:openssl_1_1/src-st';
  load.
Tags: cryptography, OpenSSL, security

More Secure Cookie Auto Login for TF-Login

14 Jan 2020

I've implemented a more secure cookie-based auto-login in TF-Login 'password' branch to replace the existing simple and insecure cookie scheme.

To load, start with fresh Pharo 7 image:

"First load Seaside."
Metacello new 
    baseline: 'Seaside3'; 
    repository: 'github://SeasideSt/Seaside:v3.3.3/repository'; 
    load. 
    
"Then load TF-Login."
Metacello new 
    baseline: 'TFLogin'; 
    repository: 'github://PierceNg/TF-Login:password/src'; 
    load.

Start Test Runner to run TF-Login's tests. All 78 tests should pass. The class TLTest runs "scripted interactive" tests on the TLTester Seaside application. TLTest's testLoginLogout and testLoginThenAutomaticLogin methods exercise the cookie-based auto-login functionality.

Auto-login is also implemented in the TLTestApp demo Seaside application. Here's a screenshot of the cookie stored in Chromium upon logging into TLTestApp.

TF-Login cookie in Chromium

The original cookie-based auto-login stores username and the SHA1-hashed password in client cookies. This replacement implementation is based on Paragon Initiative's blog post on "remember me" cookies.

Tags: Seaside, security, TF-Login

PBKDF2-HMAC-SHA1 password hashing for TF-Login

17 Nov 2019

I've implemented PBKDF2-HMAC-SHA1 in TF-Login 'password' branch to replace the existing simple and insecure SHA1-based password hashing scheme.

To load, start with fresh Pharo 7 image:

"First load Seaside."
Metacello new 
    baseline: 'Seaside3'; 
    repository: 'github://SeasideSt/Seaside:v3.3.3/repository'; 
    load. 
    
"Then load TF-Login."
Metacello new 
    baseline: 'TFLogin'; 
    repository: 'github://PierceNg/TF-Login:password/src'; 
    load.

As originally implemented, TF-Login also supports cookie-based auto-login, which works by storing username and the SHA1-hashed password in client cookies. This scheme is certainly not secure by current standards and can't be used together with PBKDF2-HMAC-SHA1 password hashing.

Possible future work on TF-Login password management:

  • OAuth2, to replace the existing insecure cookie-based auto-login

  • 2FA

Tags: cryptography, Seaside, security, TF-Login

[ANN] TF-Login for Seaside 3.3 for Pharo 7

15 Nov 2019

I've ported TF-Login to Seaside 3.3 and Pharo 7.

To load, start with fresh Pharo 7 image:

Metacello new 
    baseline: 'Seaside3'; 
    repository: 'github://SeasideSt/Seaside:v3.3.3/repository'; 
    load. 
    
Metacello new 
    baseline: 'TFLogin'; 
    repository: 'github://PierceNg/TF-Login:pharo7/src'; 
    load.

The baseline doesn't load Seaside, in case you want to load it into an image that already has Seaside.

Start Test Runner and run the TF-Login tests. All 62 tests should pass.

Tags: Seaside, security, TF-Login

TF-Login for Seaside

14 Nov 2019

TF-Login is a package that provides basic user authentication, registration, and account management for Seaside. It was originally developed on Pharo 1 by Tony Fleig, and ported to Pharo 2 by sergio101.

I am attempting to make TF-Login work with Seaside 3.3.x on Pharo 7. For now, I've reorganized the packages and fixed TLMultiFileDatabase to pass its tests.

Collaborators are welcome.

Tags: Seaside, security, TF-Login

Updated README for PasswordCrypt

26 Jan 2019

I gave myself a 1Q2019 target to write proper READMEs for my Github repos. First up is PasswordCrypt. I reproduce the README here.

PasswordCrypt

PasswordCrypt is a library for Pharo Smalltalk to handle passwords salted and hashed by SHA-256/SHA-512. Its primary components are PCPasswordCrypt, PCAuthenticator and PCBasicAuthenticator.

PCPasswordCrypt

At its core, PCPasswordCrypt provides the following class-side messages:

  • sha512crypt:withSalt:
  • sha256crypt:withSalt:

An example:

PCPasswordCrypt sha256crypt: 'secret' withSalt: 'andPepperToo'
"'$5$andPepperToo$5p0MWgRMT6l6EA6dYDlFhuQKi.tfCXNd35T99HxbsTD'"

The result is a string in modular crypt format (MFC). $5 on the left of the string indicates that the hashing algorithm is SHA-256. For SHA-512, the indicator is $6.

On the instance side, PCPasswordCrypt generates the salt randomly if one is not supplied:

PCPasswordCrypt new sha256crypt: 'secret'
"'$5$5bUAI5i2$iIdIXcQGhZfNF0HQFG592Ut1I6UtuO/smBPJkKBrRzC'"

PCAuthenticator

PCAuthenticator builds on PCPasswordCrypt to provide username/password management. PCAuthenticator operates as a singleton object to persist its data in the Pharo image across restarts.

Example usage:

| appName auth newUser userToValidate |

appName := 'myApp'.

"Initialize the authenticator for my application."
auth := PCAuthenticator uniqueInstance.
auth initializeDatabaseFor: appName.

"Add a user."
newUser := PCUserCredential
  appname: appName;
  username: 'testuser';
  password: 'secret';
  yourself.
auth insertUserCredential: newUser.

"Create another user object and validate its password."
userToValidate := PCUserCredential
  appname: appName;
  username: 'testuser';
  password: 'secret';
  yourself.
auth validateUserCredential: userToValidate
"If the passwords match, userToValidate is returned; otherwise, nil is returned."

PCAuthenticatorUI is a simple Spec-based user interface to upsert new usernames/passwords into PCAuthenticator. I wrote it because I simply abhor code snippets containing clear-text passwords, except for demonstration as above. To run PCAuthenticatorUI:

PCAuthenticatorUI new openWithSpec

PCBasicAuthenticator

PCBasicAuthenticator subclasses ZnBasicAuthenticator, the HTTP basic authentication handler in ZincHTTPComponents. It uses PCAuthenticator so that

  • usernames and passwords are persistent,
  • it is feasible to use PCAuthenticatorUI for a small number of users, such as during development and testing.

Installation

To install the Pharo code:

Metacello new
  baseline: 'PasswordCrypt';
  repository: 'github://PierceNg/PasswordCrypt/src-st';
  load.

PCPasswordCrypt is an FFI to the C library libshacrypt, built from the source files shacrypt256.c and shacrypt512.c in the directory src-c. To build the C library:

% cd src-c
% make

The generated shared library is libshacrypt.so on Linux and libshacrypt.dylib on OSX/macOS. It must be placed where the Pharo VM can find it at run time. My practice is to place the shared library file together with the Pharo VM's plugins. On macOS, suppose Pharo is installed in /Users/pierce/Pharo.app, then libshacrypt.dylib goes into /Users/pierce/Pharo.app/Contents/MacOS/Plugins/.

Possible Future Work

  • Store/retrieve usernames/passwords in htpasswd files.

References

Licenses

  • MIT license for PasswordCrypt
  • sha256crypt.c and sha512crypt.c are public domain
Tags: cryptography, security

OpenSSL RIPEMD160

18 Mar 2018

I've just added RIPEMD160 to the EVP interface in OpenSSL-Pharo. This post serves as a HOWTO.

OpenSSL's C interface defines RIPEMD160 thusly:

const EVP_MD *EVP_ripemd160(void);

Create LcLibCrypto>>apiEvpRIPEMD160 for it:

apiEvpRIPEMD160
  ^ self ffiCall: #(EVP_MD* EVP_ripemd160 ())
    module: self library

Next, create LcEvpRIPEMD160 as a subclass of LcEvpMessageDigest:

LcEvpMessageDigest subclass: #LcEvpRIPEMD160
  instanceVariableNames: ''
  classVariableNames: ''
  package: 'OpenSSL-EVP'

LcEvpRIPEMD160>>initialize
  super initialize.
  handle := LcLibCrypto current apiEvpRIPEMD160.
  self errorIfNull: handle

Add class-side accessors:

LcEvpRIPEMD160 class>>blocksize
  ^ 64

LcEvpRIPEMD160 class>>hashsize
  ^ 20

And that's it! Using the test vectors from the RIPEMD160 home page and RFC 2286, the unit tests verify that we can now use RIPEMD160 for hashing and HMAC from within Pharo:

LcEvpRIPEMD160Test>>testDigest1
  | msg result |

  msg := ''.
  result := ByteArray readHexFrom: '9c1185a5c5e9fc54612808977ee8f548b2258d31' readStream.
  self assert: (md hashMessage: msg) equals: result

LcEvpRIPEMD160Test>>testHMAC1
  | msg result expectedResult |

  msg := 'Hi There'.
  key := ByteArray readHexFrom: '0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b' readStream.
  expectedResult := ByteArray readHexFrom: '24cb4bd67d20fc1a5d2ed7732dcc39377f0a5668' readStream.
  result := (HMAC on: LcEvpRIPEMD160)
    key: key;
    digestMessage: msg asByteArray.
  self assert: result equals: expectedResult
Tags: cryptography, OpenSSL, security

OpenSSL for Pharo on Github

21 Dec 2017

I've migrated OpenSSL-Pharo to Github.

Metacello new
  baseline: 'OpenSSL';
  repository: 'github://PierceNg/OpenSSL-Pharo:master/src-st';
  load.
Tags: cryptography, OpenSSL, security

OpenSSL for Pharo on Windows

20 Dec 2017

OpenSSL-Pharo now works on Windows. Tested on Windows 10 with a fresh 32-bit Pharo 6.1 zip package downloaded from pharo.org. On Windows this library uses libeay.dll which is bundled with the Pharo VM.

Metacello new
  baseline: 'OpenSSL';
  smalltalkhubUser: 'PierceNg' project: 'OpenSSL-Pharo';
  load.
Tags: cryptography, OpenSSL, security

OpenSSL wrapper for Pharo

29 Oct 2017

I've put up the beginnings of a wrapper for OpenSSL on STH:

Metacello new
  baseline: 'OpenSSL';
  smalltalkhubUser: 'PierceNg' project: 'OpenSSL-Pharo';
  load.

Verified on Pharo 6 32- and 64-bit.

My near term goal is to wrap enough libcrypto functionality to implement the client-side of Let's Encrypt.

I meant to put it up on GH, for the ease of forking and PRs, but I couldn't get Iceberg to work, and gitfiletree also failed to load, so STH it is for now.

Collaboration welcome.

Tags: cryptography, OpenSSL, security

SHA256/512 Password Hashing for Pharo 5

18 Feb 2017

I've updated my SHA256/512 password hashing library to Pharo 5's FFI and moved it from SS3 to GH.

In the GH repo, C source files are in the src-c directory. Compile with the Makefile there. Move the .so or .dylib file to where the VM can find it.

To load the Smalltalk code, in a Pharo playground:

Metacello new 
  baseline: 'PasswordCrypt'; 
  repository: 'github://PierceNg/PasswordCrypt/src-st'; 
  load.

Run the tests in TestRunner. Provided the Pharo VM can find the shared library, all 12 tests should pass.

This version adds an authentication database that uses in-image persistence, accessed programmatically via the PCAuthenticator uniqueInstance, and a very simple user interface invoked thusly:

PCAuthenticatorUI new openWithSpec

Currently PCAuthenticator hardcodes to SHA256. It should be straightforward to make the hashing algorithm pluggable, including from other shared libraries. Hosting on GH makes it easier for forks and PRs.

Tags: cryptography, security

NBSQLite3 with SQLcipher

24 Dec 2015

SQLcipher "is an open source extension to SQLite that provides transparent 256-bit AES encryption of database files." SQLcipher provides the same API as the SQLite Encryption Extension (SEE) by D Richard Hipp, the original developer of SQLite.

I've added SQLcipher/SEE's API to NBSQLite3. By convention, on Unix, SQLcipher produces a shared library named libsqlcipher.so, while the SQLite shared library is named libsqlite3.so. NBSQLite3 switches between the two libraries based on the messages #beSQLcipher and #beSQLite to the NBSQLite3FFI class.

Here's a demonstration code snippet using the keying pragma in SQL:

| dbf db rs row |

Transcript open; clear.	
NBSQLite3FFI beSQLcipher.
dbf := FileReference newTempFilePrefix: 'cipher-' suffix: '.cdb'.

db := NBSQLite3Connection openOn: dbf fullName.
Transcript show: 'Creating an encrypted database with some data.'; cr.
[   db basicExecute: 'pragma key = "test"'.
    db basicExecute: 'create table if not exists x (xk integer primary key, iv integer, tv text);'.
    db beginTransaction.
    [  rs := db execute: 'insert into x values (NULL, ?, ?)' with: #(1 'two') ] ensure: [ rs close ].
    db commitTransaction
] ensure: [ db close ].

db := NBSQLite3Connection openOn: dbf fullName.
Transcript show: 'Opening the encrypted database.'; cr.
[   db basicExecute: 'pragma key = "test"'.
    [   rs := db execute: 'select * from x'.
        row := rs next.
        Transcript show: (row at: 'xk'); cr.
        Transcript show: (row at: 'iv'); cr.
        Transcript show: (row at: 'tv'); cr.
    ] ensure: [ rs close ]
] ensure: [ db close ].

dbf delete.

NBSQLcipherExample class>>examplePragma contains a longer version of the above snippet that includes reopening the encrypted database file without the keying pragma and using the SQLite library.

Tested on Linux Mint. Code updated in Smalltalk Hub. Some refactoring to be expected, because the above snippet using the keying pragma is the only test I've done.

I've placed a copy of libsqlcipher.so here; it is built on my Linux Mint 17.x laptop from the source here, linking in LibreSSL 2.2.4's libcrypto.a statically.

For good measure, I've also put up a copy of sqlcipher built at the same time. It requires readline.

Tags: cryptography, security, SQLite

LibreSSL and Pharo/Squeak SSL plugin

22 Oct 2015

According to its documentation, on Unix, the Pharo VM's SSL plugin, libSqueakSSL.so, links into OpenSSL libraries dynamically. On my 64bit Ubuntu Trusty machine, OpenSSL is provided by the libssl1.0.0:i386 package.

$ ldd libSqueakSSL.so
    linux-gate.so.1 =>  (0xf77a9000)
    libssl.so.1.0.0 => /lib/i386-linux-gnu/libssl.so.1.0.0 (0xf7727000)
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7579000)
    libcrypto.so.1.0.0 -> /lib/i386-linux-gnu/libcrypto.so.1.0.0 (0xf73cb000)
    /lib/ld-linux.so.2 (0xf77a9000)
    libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xf73c6000)

(By the way, the SSH2 plugin libssh2.so.1.0.1 requires libcrypto too.)

According to packages.ubuntu.com, Trusty's libssl1.0.0 is built from openssl_1.0.1f.orig.tar.gz plus successive upstream patches.

From the OpenBSD developers, LibreSSL is "a version of the TLS/crypto stack forked from OpenSSL in 2014, with goals of modernizing the codebase, improving security, and applying best practice development processes." LibreSSL also comes with libtls, "a new TLS library, designed to make it easier to write foolproof applications".

Let's see how we go about linking libSqueakSSL.so with LibreSSL.

First, download and unpack LibreSSL. Modify the configure script at lines 2287 and 2289 so that LIBCRYPTO_VERSION and LIBSSL_VERSION both say 1:0:0 instead of 35:0:0. Then build LibreSSL:

$ CFLAGS=-m32 LDFLAGS=-m32 ./configure --disable-asm
$ make

I'm building on a 64bit OS, hence "-m32". Without "--disable-asm", the build fails. To get the assembler version, which is recommended for serious usage, either set up a 32bit build environment or muck around with autoconf/configure. I suspect the former is easier. :-)

The output files are $SRC/crypto/.libs/libcrypto.so.1.0.0 and $SRC/ssl/.libs/libssl.so.1.0.0. The shared object files have the "1.0.0" suffix because I modified configure above. Alternatively, I could've played around with autoconf, or built the shared objects with the "35.0.0" suffix and sym/hard-link them for the "1.0.0" versions. TIMTOWTDI.

Next, remove the OpenSSL package:

$ sudo apt-get remove libssl1.0.0:i386
$ ldd libSqueakSSL.so
    linux-gate.so.1 =>  (0xf7718000)
    libssl.so.1.0.0 => not found
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7540000)
    /lib/ld-linux.so.2 (0xf7718000)

Finally, put the LibreSSL shared object files into the right place. Where this right place is depends on your environment. TIMTOWTDI. I choose to put them in the Pharo VM directory with its other plugins, and arrange to start Pharo with LD_LIBRARY_PATH set appropriately. Going by the output of ldd again, the following is required:

$ ln libcrypto.so.1.0.0 libcrypto.so.1

After which:

$ ldd libSqueakSSL.so
    linux-gate.so.1 =>  (0xf7709000)
    libssl.so.1.0.0 => /pkg/pharovm/libssl.so.1.0.0 (0xf7696000)
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf74c7000)
    libcrypto.so.1 -> /pkg/pharovm/libcrypto.so.1 (0xf72b8000)
    /lib/ld-linux.so.2 (0xf770a000)

Launch the Pharo 4.0 image and run the Zodiac tests. All tests should pass. Well, except testGetPharoVersion, which looks for a file that apparently no longer exists.

Incidentally, Squeak 5.0-All-in-One's SSL plugin appears to have linked its crypto/SSL libraries in statically, so the only way to upgrade is to build a new plugin.

$ ldd SqueakSSL
    linux-gate.so.1 =>  (0xf7736000)
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7310000)
    /lib/ld-linux.so.2 (0xf7737000)
Tags: cryptography, deployment, Linux, security

UnQLite Jx9

29 Jun 2015

I'm playing with Masashi Umezawa's PunQLite wrapper for unQLite. UnQLite provides both a key-value store and, interestingly, a JSON document store based on an embedded programming language named Jx9.

Here's an example Jx9 program:

if (db_exists("students")) {
  db_drop_collection("students");
}
db_create("students");
$s = { name: "james", age: 26 };
db_store("students", $s); 
$sid = $s.__id;

And here's Smalltalk code to execute the above Jx9 program:

| j db |

j := '...'. "Above Jx9 program."

db := PqDatabase openOnMemory.
[   db jx9Do: [ :exe |
        exe compile: j.
        exe execute.
        Transcript show: exe @ 'sid' asString; cr ]
] ensure: [ db close ]

PunQLite supports extracting values from an executed Jx9 program, as in "exe @ 'sid'" above. PunQLite currently does not support UnQLite's APIs for exchanging JSON objects between Smalltalk and an Jx9 program which provide functionality similar to parameter binding in SQL APIs. That means Jx9 programs, including data to be stored, has to be constructed from strings... As OWASP says about NoSQL injection:

Because these NoSQL injection attacks may execute within a procedural
language, rather than in the declarative SQL language, the potential
impacts are greater than traditional SQL injection. 
Tags: NoSQL, security

One Time Passwords

26 Mar 2015

I bought a Yubikey device and am going to write a Pharo library for it. Meanwhile, I discovered that Richard Prinz has an implementation of RFC 6536 Time-based One Time Passwords for Pharo.

Tags: cryptography, security

SHA256/512 Password Hashing for Pharo

17 Nov 2013

Recently, Adobe was hacked, resulting in, among other breakages, the loss of 130 million passwords. It was revealed that the passwords were encrypted using ECB, electronic cookbook mode, which is a rather poor way of securing passwords.

The MacRumors forum site was also hacked recently. The site runs the vBulletin forumware, which protects passwords using md5crypt.

md5crypt is a password hashing scheme devised by Poul-Henning Kamp in 1995. The hashed password takes the format $1$$. The hash is designed to be expensive to compute, to slow down attacks. In 2012, Poul-Henning announced that md5crypt was no longer considered safe, in view of advances in computing power.

sha-crypt, from Ulrich Depper, is a public domain implementation of SHA-256/512-based password hashing, which works similarly to md5crypt, using SHA-256/512 and allowing an arbitrary number of rounds through the hashing algorithm.

The following commands build and run sha(256|512)crypt.c as self-test programs:

$ cc -DTEST -std=c99 -m32 sha256crypt.c
$ ./a.out
all tests OK
$ cc -DTEST -std=c99 -m32 sha512crypt.c
$ ./a.out
all tests OK

Next, build shared library:

$ cc -std=c99 -m32 -fPIC -c sha256crypt.c
$ cc -std=c99 -m32 -fPIC -c sha512crypt.c
linux$ cc -m32 -shared -o libshacrypt.so *.o
osx$ cc -m32 -shared -o libshacrypt.dylib *.o

Move the .so or .dylib file to where your plugins are.

PCPasswordCrypt is a Smalltalk interface to libshacrypt using NativeBoost. It is very simple to use:

PCPasswordCrypt sha256Crypt: 'Hello world!' withSalt: 'saltstring'.
'$5$saltstring$5B8vYYiY.CVt1RlTTf8KbXBH3hsxY/GNooZaBBGWEc5'

Tested on OSX (Mountain Lion) and Linux (Mint 14). The C programs work on FreeBSD, but my self-built FreeBSD Cog VM doesn't have NativeBoost.

The C programs are found here. Once I figure out how, I'll put them on GitHub. PCPasswordCrypt is published on SqueakSource3.

Tags: cryptography, security

Cryptographic Libraries for Pharo and Squeak

13 Nov 2013

NaCl (pronounced "salt") is a new, easy to use high-speed software library for network communication, encryption, decryption, signatures, etc. It uses elliptic curve cryptography. libsodium is a portable fork of NaCl. Crypto-Nacl is a Pharo/Squeak interface to libsodium. It uses FFI. As is, the library should be named liblibsodium.dylib when used with Crypto-Nacl on OSX.

SqueakSSL is a plugin to the platform-native SSL/TLS facility. The plugin is bundled with the Cog VM. Zodiac is an open source, cross-Smalltalk implementation of regular and secure socket streams. Zodiac uses SqueakSSL. Webclient also uses SqueakSSL to support HTTPS.

The Cryptography package has been around for a while. It now lives on SmalltalkHub. It has plugins for DES, DSA, MD5 and SHA256. At this time, this package doesn't look viable for real-world use.

Tags: cryptography, security

A Simple Secret-Splitting Password Store

11 Aug 2013

Online examples of SQL database APIs tend to go like this:

spec := DBConnectionSpec new
  key: 'mysql'; 
  host: 'localhost'; port: 3306; 
  user: 'testuser'; password: 'testpass';
  yourself.	

And this:

settings := DBXConnectionSettings
  host: 'localhost'
  port: '3306'
  database: 'sodbxtest'
  userName: 'sodbxtest'
  userPassword: 'sodbxtest'.

Perhaps fine for pedagogical material, and I do the same during development. However, I don't want that for production - hardcoding a database (or any) password in application code simply offends my sensibilities.

Secret splitting divides a message into a number of pieces. In the simplest scheme, all the pieces are required to reconstruct the message. To split the message into, say, 5 pieces, generate 4 random strings, each of the same length as the message, then XOR the message and the random strings together. Save the random strings and the final XOR output. To reconstruct the message, XOR the 5 pieces of saved data.

I've written a package called SpsSplitPasswordStore that implements the simple secret splitting scheme described above. The motivation is to avoid both hardcoding the database password in application code and saving the password in clear text in a file.

The following saves a password:

SpsSplitPasswordStore split: 'testpass' into: 5 andWriteTo: 'sps1.dat'

The file 'sps1.dat' doesn't particularly look like it contains a password. (Yes, security through obscurity, I know.)

% strings sps1.dat
FUEL
FLGlobalClassCluster
OrderedCollection
ByteArray
FLPositive8SmallIntegerCluster
FLByteObjectCluster
E\E?
FLSimpleCollectionCluster

% od -X -N 64 sps1.dat 
0000000          4c455546        00001300        00090000        00000000
0000020          14040000        6c474c46        6c61626f        73616c43
0000040          756c4373        72657473        02000000        64724f11
0000060          64657265        6c6c6f43        69746365        42096e6f
0000100

This code reconstructs the password:

SpsSplitPasswordStore readFrom: 'sps1.dat'

Thus the database connection preparation code becomes like this:

spec := DBConnectionSpec new
  key: 'mysql'; 
  host: 'localhost'; port: 3306; 
  user: 'testuser'; 
  password: (SpsSplitPasswordStore readFrom: 'sps1.dat');
  yourself.	

The security claim I make for SpsSplitPasswordStore is that it is more secure than hardcoding your database username/password pair in your application code.

While convenience usually trumps security in the real world, in this case, SpsSplitPasswordStore also makes it more convenient to change the application's database password without requiring changes to the application.

Edit: Available at http://ss3.gemtalksystems.com/ss/SpsSplitPasswordStore.html.

Tags: secret splitting, security

Fuzzing with Zed Attack Proxy

08 Jun 2013

The OWASP Zed Attack Proxy, also known as ZAP, "is an easy to use integrated penetration testing tool for finding vulnerabilities in web applications."

Download, unpack, run "./zap.sh", and away we go attacking my blog search interface:

ZAP fuzzes the search parameter. And finds something interesting: "200 OK" is expected, as is "404 Not Found". But "500 Internal Server Error" isn't!

However, Pharo, Zinc and my blog server kept running though, so the 500 wasn't because the server crashed. Indeed, ZAP reports the response thusly:

HTTP/1.0 500 Internal Server Error
Content-Type: text/plain;charset=utf-8
Content-Length: 23
Date: Sat, 08 Jun 2013 14:15:19 GMT
Server: Zinc HTTP Components 1.0

Error: Result Code: 5

Aha! This is an SQLite error: "The database file is locked". Here is one possible StackOverflow explanation. I'll have to verify if that is indeed the cause.

ZAP also offers an SQL injection fuzzer with even more attacks:

Through all this, the server kept running. Although attacks like "insert into mysql.user (u..." and "exec sp_addlogin 'name'..." returned "Successful", my backend is SQLite and these don't apply.

Still, some time ago while doodling with SQLite, I manage to lock up an image such that it crashes instantly upon re-opening. I haven't found the reason. My conjecture is that it is related to my code's not doing FFI properly, although at this time I have no idea how to test this. I'll probably keep banging on the SQLite interface to see if it eventually kills the image.

Tags: fuzzing, security

Fuzzing

12 May 2013

I've previously written about StackOverflow full text indexing using SQLite. I've now loaded this site's small body of content into an SQLite FTS database, and have implemented a search interface for it. Before opening up the search interface to the big bad Internet, I reckon some testing is required.

Fuzzing "is a black box software testing technique which basically consists of finding implementation bugs using malformed/semi-malformed data injection in an automated fashion." This site runs as a Zinc server delegate in Pharo Smalltalk. In fuzzing the search interface, I will be fuzzing Zinc's input handling, my server delegate's input handling including its susceptibility to SQL injection, and possibly the CogVM FFI that hooks Pharo up with SQLite.

Of course, the Smalltalk image is not a black box. While fuzzing I will be able to view Zinc's source code, explore live objects, and check behaviour.

Tags: fuzzing, security