POST Cannot Be Redirected

Illustration

Few days ago I’ve found a bug in a program of mine. As I have feedback built-in in most programs, I decided to use it for once. And failed. All I’ve got was an error message.

A bit of troubleshooting later and I’ve narrowed the problem down. It would work perfectly well over HTTPS but it would fail on HTTP. Also it would fail when redirected from my old domain, whether it was HTTP or HTTPS. And failure was rather unusual error code 418. That was an error I’m often using to signal something wrong with redirects. A bit of a digging later, I’ve noticed I was using POST method for my error reporting (duh!).

You cannot redirect POST requests. And I was doing server-side redirecting (or trying to) from my old domain to a new one and from HTTP to HTTPS.

At the end I’ve changed all my programs to use HTTPS, temporarily disabled redirecting to allow HTTP-only connections, and I’ve had to re-enable same script on my old site so I can get error reports from old versions without update. I knew this last domain move has gone too smooth…

How to Secure Memory?

Sometime you might want to protect your data in memory - the greatest example is when dealing with anything related to passwords. It is simply not smart to keep that data around in a plain-text.

In .NET there are multiple methods you can use for this purpose, starting with SecureString, ProtectedMemory, and my favorite ProtectedData.

Each of these has its advantages and disadvantages and definitely each can find its place in a security toolbox. However, I prefer ProtectedData because it doesn’t require any Win32 API magic to read (as SecureString), nor it has any limitations on block length (as ProtectedMemory). As long as you are ok dealing with byte arrays, you can use it almost as a transparent storage.

Most of the times I end up having something like this (the most basic form):

private static RandomNumberGenerator Rnd = RandomNumberGenerator.Create();
private byte[] RawDataEntropy = new byte[16];
private byte[] RawData = null;

internal byte[] Data {
    get {
        if (this.RawData == null) { return new byte[0]; } //return empty array if no value has been set so far
        return ProtectedData.Unprotect(this.RawData,
                                       this.RawDataEntropy,
                                       DataProtectionScope.CurrentUser);
    }
    set {
        Rnd.GetBytes(this.RawDataEntropy); //new entropy every save
        this.RawData = ProtectedData.Protect(value,
                                             this.RawDataEntropy,
                                             DataProtectionScope.CurrentUser);
    }
}

On each write we let Windows encrypt the data using a random entropy (in addition to its standard encryption) while on every read we simply decrypt the data and return a copy of it. Care should be taken to delete copies lying around, i.e. when you set the property and encrypt data, you should delete the original. Best practice for delete is to use Array.Clear, e.g.:

Array.Clear(value, 0, value.Length);

I will leave it for reader’s exercise why that might be preferred to a simpler value = null.

PS: Note that, as soon as you convert bytes to a string (e.g. to show it to the user), you have signed capitulation as now you have an unencrypted copy of the protected data in memory. Yes, sometime you need to do it, but keep it brief.

Bimil and Summae

Illustration

After using it myself for last five years, I finally decided to give my password manager a version 1.00 designator.

It is a simple password manager using Password Safe database format. Unlike Password Safe, it allows for storage of credit cards and two-factor authentication keys. Give it a try and see whether you like it.

Other application that got slight version bump is Summae. It now supports per user context menu settings. On other hand, you cannot install it on Windows Vista and below. If you are using Windows 7 you are good. If not, upgrade. :)

Going Big With FAT32

Illustration

FAT32 is an aging file system with many faults. However, it does have one great advantage. It has been with us long enough that every OS supports it. Whether it is smallest IOT device or big mainframe (anybody uses those?), it will just simply work.

Because of that ubiquity I always keep one FAT32 formatted drive with me. It used to be 8 GB, then 4 GB, and now whooping 128 GB. And it is those 128 GB that posed a curious problem - Windows will allow you to format FAT32 only on disks 32 GB and less.

Mind you, that restriction doesn’t come from FAT32 design itself. If you use whooping 512 KB sectors and maximum count of 4,177,918 clusters, you can reach 2 TB. But, in order to keep backward compatibility with its NT-inherited 16-bit setup, Windows XP decided to drop sector size to 32 KB and inexplicably to limit total partition size to 32 GB (my guess is to promote NTFS). Mind you, it will read even bigger FAT32 volumes if they are already formatted. However, as soon as you try to reformat it first time, it will refuse to do so.

Solution is simple. Either go to ancient Windows 98 that actually supported FAT32 up to 127 GB (ok, that is a bit unrealistic), use pretty much any Linux distribution, or get a Windows application that will do formatting for you.

My go-to application is FAT32 Format. It is simple, free, works on any Windows version you throw at it, doesn’t require installation, and it has acceptable UI. For something one might need just once in a while, a perfect choice.

Not All EOLs Are Created Equal

As I was playing with the Wordpress shortcode methods, I came upon an interesting problem.

I wanted to change text in the particular line of the shortcode content and thus standard PHP explode and implode methods seemed like a best bet:

add_shortcode('something', 'something_callback');

function snippet_pre_shortcode_callback($atts, $content = null) {
    $lines = **explode('\n', $content)**;
    $lines[1] = "My line 2";
    return **implode('\n', $lines)**;
}

Nice and simple solution that didn’t work. The big content string I was sure had some lines, wouldn’t split. It took me a while to notice the error - single quote in PHP does not specify character but string with a minimal escaping. Most of the time they behave same as the double quotes which actually allow for much richer escaping.

Most annoying was that I knew this “feature” from before. However, too much work in the proper programming languages kinda made me overlook this trivial error multiple times while debugging. After taking a “frustration break” and coming back after 5 minutes, mistake was obvious.

The easy solution would be to swap one quotes for another. However, in this case a bit nicer solution exists - use the damn PHP_EOL constant:

function snippet_pre_shortcode_callback($atts, $content = null) {
    $lines = **explode(^^PHP_EOL^^, $content)**;
    $lines[1] = "My line 2";
    return **implode(^^PHP_EOL^^, $lines)**;
}

PHP, who wouldn’t love you… :/