A Stateless Quiz System

by Arne Sommer

A Stateless Quiz System with Raku - Part 2: Security

[250.2] Published 18. August 2023

[ Index | Introduction | Security | The Program | Notes | RakuConf ]

Security by Obscurity

The question IDs must be randomly selected from a pretty large pool of possible IDs to choose from, so that it is impossible - or at least very hard - to cheat.

The following program will give us random IDs.

File: mkid
#! /usr/bin/env raku

unit sub MAIN ($length = 16);       # [1]

my @chars = ('a'..'z', 0..9).flat;  # [2]

say @chars.pick($length).join;      # [3]

[1] The default ID length is 16, but you can specify any other length.

[2] The alphabet to choose from. The result is a list with two elements; the two ranges (given by ..). So we apply flat to get a one dimentional list.

See docs.raku.org/routine/flat for more information about flat.

[3] Use pick to pick the required number of characters, join them together as a string, and print the result.

See docs.raku.org/routine/pick for more information about pick.

Running it:

$ ./mkid    # -> 2jrfemlx9zup71gb
$ ./mkid    # -> 0ur2t1ixlaky9p6s
$ ./mkid    # -> 0pbjuol2e58f3vha
$ ./mkid 20 # -> 8len6fsok24tdv5rwmjz

Even more Security by Even More Obscurity

You may have noticed (or gathered from reading the documentation; yes, that is the main reason for the inclusion of those links in my articles) that the examples do not have duplicate characters in the IDs. That is courtesy of pick, and the result is a slightly reduced number of possible combinations.

We can use roll instead, to avoid this problem.

Let us add the upper case letters at the same time:

File: mkid-roll
#! /usr/bin/env raku

unit sub MAIN ($length = 16);

my @chars = ('a'..'z', 'A'..'Z', 0..9).flat;

say @chars.roll($length).join;

See docs.raku.org/routine/roll for more information about roll.

Running it (possibly several times) shows that duplicate characters can uccur:

$ ./mkid-roll  # -> gosu2ccNUeVZb00Y
$ ./mkid-roll  # -> OZcgVWwW5fbhtsPD

But, does it actually matter?

The number of possibilities:

Command Combinations Number Code
$ ./mkid 16 36 * 35 * ... * 22 * 21 152901072685905223680000 [*](26 ... 21)
roll 36 ^ 16 7958661109946400884391936 36 ** 16
$ ./mkid-roll 16 62 ^ 16 47672401706823533450263330816 62 ** 16

Yes, it does matter. Allowing duplicates (the second row) increases the number of possibilities quite alot. Adding the uppercase letters into the mix increases it even more. But the first number is so high in the first place, that it should not be a problem in practice. An industrious person trying to brute force the IDs would probably crash the application server before getting at a legal ID, or at least slow it down considerable by the heavy load.

But you should not use this Quiz system to give out expensive rewards anyway. The reward for hacking the web server would be high...

Note that sending the Question IDs as part of the URL makes them readable by anyone with access to the networks that the requests pass through, or the web server log.

[ Index | Introduction | Security | The Program | Notes | RakuConf ]