User authentication is a critical part of any web system. This is especially true when developing a system whose source code is publicly accessible. In open-source systems, it is generally considered an advantage that the source code is transparent, as well-intentioned developers and security researchers can more easily identify security vulnerabilities.
Security through obscurity Link to heading
Although not a good practice, the security of the system can somewhat be enhanced if the outside world cannot learn about the implementation details. In this way, bugs are often discovered only after costly trial and error. This process can be so expensive that it is not worth dedicating time and energy to it—regardless of whether the attacker is a well-intentioned security researcher or someone with malicious intent hoping to exploit vulnerabilities.
Actual Security Link to heading
If your code is open source, you cannot rely on the security through obscurity hiding your implementation flaws. Instead, you are forced to develop truly secure solutions that protect your users and your own data.
Stay Informed! Link to heading
Keep up with what types of attacks are currently popular and may affect the application you are developing. Rust is a safe language and enforces many safety requirements, making your program more secure, but it will not protect you from logical errors!
Review It Again! Link to heading
During development, you inevitably encounter new things, learn new concepts, and find useful libraries that improve your code quality. Therefore, it is worth reviewing your code periodically because with this new knowledge, you can significantly improve its security and/or functionality.
Automate it! Link to heading
If every change requires you to recheck all security and other functions, you’ll quickly reach a point where you prefer not to touch parts that already worked. Re-testing everything is costly and time-consuming. Modern software is expected to continually meet new challenges and demands, so rarely does one write code that requires no further modifications. Continuous testing helps prevent new security gaps or bugs from being introduced during these inevitable changes.
Why am I writing all this? Link to heading
Recently, I started revisiting the user authentication part of my web application and restructured the code so that JWT validation is performed in a central place, avoiding multiple implementations across different parts of the code. One consequence of this was that I could write much easier tests for this logic, which I did (see here).
During testing, I discovered that the library I am using for JWT generation does not, with its default validator, check
the nbf
(not before) field of the JWT, which is meant to verify that the token cannot be used before the the
application sets. In my case, this isn’t of much significance, but since I am using this field, it should work properly.
What does matter is that with these tests, if someone asks how I know that token generation and validation work in my system, I can point to these tests: they automatically run every time before release, testing this continuously.
Stay safe, even if you develop an open-source system!
If you read this post, please email me to let me know—currently, I have no traffic monitoring on this site! :))