Adding an "Other" enum value to an API often seems like a flexible solution for unknown future cases, but it creates significant problems. It weakens type safety, forcing consumers to handle an undefined case and potentially misinterpret data. It also makes versioning difficult, as any new enum value must be mapped to "Other" in older versions, obscuring valuable information and hindering analysis. Instead of using "Other," consider alternatives like an extensible enum, a separate field for arbitrary data, or designing a more comprehensive initial enum. Thorough up-front design reduces the need for "Other" and leads to a more robust and maintainable API.
The Okta bcrypt incident highlights crucial API design flaws that allowed attackers to bypass account lockout mechanisms. By accepting hashed passwords directly, Okta's API inadvertently circumvented its own security measures. This emphasizes the danger of exposing low-level cryptographic primitives in APIs, as it creates attack vectors that developers might not anticipate. The post advocates for abstracting away such complexities, forcing users to interact with higher-level authentication flows that enforce intended security policies, like lockout mechanisms and rate limiting. This abstraction simplifies security reasoning and reduces the potential for bypasses by ensuring all authentication attempts are subject to consistent security controls, regardless of how the password is presented.
Several commenters on Hacker News praised the original post for its clear explanation of the Okta bcrypt incident and the proposed solutions. Some highlighted the importance of designing APIs that enforce correct usage and prevent accidental misuse, particularly with security-sensitive operations like password hashing. The discussion touched on the tradeoffs between API simplicity and robustness, with some arguing for more opinionated APIs that guide developers towards best practices. Others shared similar experiences with poorly designed APIs leading to security vulnerabilities. A few commenters also questioned Okta's specific implementation choices and debated the merits of different hashing algorithms. Overall, the comments reflected a general agreement with the author's points about the need for more thoughtful API design to prevent similar incidents in the future.
Summary of Comments ( 61 )
https://news.ycombinator.com/item?id=43193160
HN commenters largely agree with Raymond Chen's advice against adding "Other" enum values to APIs. Several commenters share their own experiences of the problems this creates, including difficulty in debugging, versioning issues as new enum members are added, and the loss of valuable information. Some suggest using an associated string value alongside the enum for unexpected cases, or reserving a specific enum value like "Unknown" for situations where the actual value isn't recognized, which provides better forward compatibility. A few commenters point out edge cases where "Other" might be acceptable, particularly in closed systems or when dealing with legacy code, but emphasize the importance of careful consideration and documentation in such scenarios. The general consensus is that the downsides of "Other" typically outweigh the benefits, and alternative approaches are usually preferred.
The Hacker News post "API design note: Beware of adding an "Other" enum value" discussing Raymond Chen's blog post about the pitfalls of adding "Other" to enums generated a moderate amount of discussion with 27 comments. Many commenters concurred with Chen's points, sharing their own experiences and expanding on the potential problems.
Several compelling comments highlighted the cascading issues caused by "Other" enum values. One commenter pointed out how this practice forces consumers of the API to implement awkward workarounds, often involving string parsing or custom data structures to handle the "Other" cases. This can lead to increased code complexity and maintenance burdens, especially as the API evolves. They emphasized how this negates the benefits of using enums in the first place, which are meant to provide type safety and clarity.
Another commenter elaborated on the difficulties in versioning APIs with "Other" enums. When new enum values are introduced in later versions, existing clients using the "Other" category may become incompatible or require significant refactoring to handle the updated values. This can create backward compatibility challenges and complicate the upgrade process for developers. This commenter also pointed out how the use of
Other
often masks genuine bugs where an appropriate enum value should have been defined but wasn't.Some commenters suggested alternative strategies to avoid using "Other". One popular suggestion was to provide an extensible enum mechanism, allowing consumers to define their own values if needed. Another commenter proposed using a dedicated "Unknown" value instead of "Other", signifying that the value is not recognized by the current version of the API but might be handled gracefully in future versions. The use of "Unknown" implies a future where the unknown values will be given proper meaning as opposed to "Other," which implies something outside the intended domain of the enum.
A few comments also focused on the importance of careful API design and communication between API providers and consumers. They highlighted the need for thorough documentation and clear guidelines on how to handle unexpected or unknown values. One commenter stressed the importance of using a versioning strategy that allows clients to adapt gracefully to changes in the API.
In summary, the comments generally agreed with Chen's premise and provided further evidence and anecdotes supporting the avoidance of "Other" in enums. They discussed the practical challenges and offered alternative solutions for API designers. The discussion reinforced the importance of thoughtful API design, versioning, and communication to prevent issues caused by the ambiguous nature of "Other" values.