the probability that changeme is actually valid base64 encoding must be very low
On the contrary, any 8 char alphanumeric string is valid base64. All such strings with a length divisible by 4, in fact, as those strings are guaranteed not to need trailing padding.
I remember with distinct horror the first time I realize that rot13(base64(data)) is also valid base64, and that there’s probably a developer out there that was using this…
Better yet: do not use dummy values. Force your users to set the values that are required.
If you don’t, you’ll end up with default values for things such as keys and salts and put your users at risk.
You don’t want to hardcode a ThisTokenIsNotSoSecretChangeIt in your configuration, because no one will actually change it.
Create values that raise an error when it is attempted to be used:
class ChangeMe:
def __init__(self, name):
self.name = name
def __str__(self):
raise ValueError(f"Please configure {self.name}.")
# In configuration:
SOME_VALUE = ChangeMe("SOME_VALUE")
# In your library code:
some_operation(str(SOME_VALUE)) # The error will automatically bubble.
You could also use Python’s descriptor system by storing your configuration inside a Config object and having ChangeMe define __get__ to raise an error. Other languages may have other ways but Python provides these sorts of niceties.
Use a language that can express optional values in the type system:
data Config f = Config
{ foo :: f Text
, bar :: f Int
}
type PartialConfig = Config Maybe
type FullConfig = Config Identity
completeConfig :: PartialConfig -> Maybe FullConfig
“Not using dummy values” -comment aside, I found this article delightfully genuine and fun to read. Do a thing with your code and then lose hours or days looking for problems, when the problem is a simple typo or a forgotten // TODO: implement this :)
Refreshing to see it happening to others :)
Reminds me of how we solved a JavaScript hacking challenge in university by doing the reverse. Generating a specific string by calling base64-encode (btoa) on a binary blob.
On the contrary, any 8 char alphanumeric string is valid base64. All such strings with a length divisible by 4, in fact, as those strings are guaranteed not to need trailing padding.
I remember with distinct horror the first time I realize that
rot13(base64(data))
is also valid base64, and that there’s probably a developer out there that was using this…Any alphanumeric string with a length that is a multiple of 4 is valid Base64 string.
Since
+
and/
are also used as symbols in Base64 encoding (for binary 111110 and 111111, respectively), we also have:Better yet: do not use dummy values. Force your users to set the values that are required.
If you don’t, you’ll end up with default values for things such as keys and salts and put your users at risk.
You don’t want to hardcode a
ThisTokenIsNotSoSecretChangeIt
in your configuration, because no one will actually change it.Create values that raise an error when it is attempted to be used:
You could also use Python’s descriptor system by storing your configuration inside a
Config
object and havingChangeMe
define__get__
to raise an error. Other languages may have other ways but Python provides these sorts of niceties.Use a language that can express optional values in the type system:
“Not using dummy values” -comment aside, I found this article delightfully genuine and fun to read. Do a thing with your code and then lose hours or days looking for problems, when the problem is a simple typo or a forgotten
// TODO: implement this
:) Refreshing to see it happening to others :)Lately I always grep for TODOs before I run things.
Great idea for a pre-commit hook right there
If your language generates warnings when you call deprecated code, then you can make a “deprecated” function that crashes the program when called.
Reminds me of how we solved a JavaScript hacking challenge in university by doing the reverse. Generating a specific string by calling base64-encode (
btoa
) on a binary blob.