diff --git a/src/routes/blog/author/aditya-oberai/+page.markdoc b/src/routes/blog/author/aditya-oberai/+page.markdoc new file mode 100644 index 0000000000..7e00767a1e --- /dev/null +++ b/src/routes/blog/author/aditya-oberai/+page.markdoc @@ -0,0 +1,11 @@ +--- +layout: author +slug: aditya-oberai +name: Aditya Oberai +role: Developer Advocate +bio: Hackathons, communities, developer relations, and open source +avatar: /images/avatars/aditya.png +twitter: https://x.com/adityaoberai1 +github: https://github.com/adityaoberai +linkedin: https://www.linkedin.com/in/adityaoberai1 +--- diff --git a/src/routes/blog/post/make-open-source-healthier/+page.markdoc b/src/routes/blog/post/make-open-source-healthier/+page.markdoc new file mode 100644 index 0000000000..7dc0dc074d --- /dev/null +++ b/src/routes/blog/post/make-open-source-healthier/+page.markdoc @@ -0,0 +1,79 @@ +--- +layout: post +title: Make open source healthier by being a better contributor +description: How you can improve community health of an open-source project through healthy contribution practices +date: 2023-10-23 +cover: /images/blog/make-open-source-healthier.png +timeToRead: 5 +author: aditya-oberai +category: opensource +--- + +For the last few years, every single time Hacktoberfest comes, one challenge that has constantly been discussed is how to make open source healthier for everyone. This isn’t to say that open source is an unhealthy space; rather, it has a much larger positive impact than most people can imagine. However, Hacktoberfest sees the entry of a flurry of new contributors trying their hands at getting in their first Pull Requests. This period is a particularly impressionable phase for new contributors to open source, and gaining a better understanding of how contributors should participate in a healthy manner only makes for a better, more welcoming community. Therefore, in this blog, we will explore what community health means in the context of open-source communities and the role contributors play in making it better. + +## Understanding what community health in open source means + +In the context of open-source communities, **community health** refers to the overall well-being, sustainability, and effectiveness of the community working on a project. It involves various factors that contribute to a productive and supportive environment, encouraging collaboration, inclusivity, and growth. + +A healthy open-source community typically has the following characteristics: + +- **Active participation** and **continuous engagement** +- An **inclusive** and **open environment** for everyone, regardless of their backgrounds, skills, etc. +- **Effective communication channels**, such as mailing lists, forums, or chat rooms +- **Transparent decision-making** about the project's direction, priorities, and governance +- **Strong leadership** to guide the community, set the vision, and help resolve conflicts +- A well-defined **code of conduct** to establish expectations for behavior +- Well-maintained **documentation** for the project and its processes +- **Recognition** and **appreciation** of contributors' efforts +- **Collaboration** and **teamwork** among members +- **Opportunities** to **learn** and **grow** as a professional + +While some of these characteristics, like strong leadership, transparent decision-making, and creating a code of conduct, are responsibilities primarily held by maintainers, most of these are shared between maintainers and contributors. + +## Building a healthy set of contribution practices + +Having discussed what community health means, it is necessary to then discuss what contributors can do to improve the community experience for everyone involved in the contribution process. Here are some practices I recommend from my experience as a contributor and maintainer: + +- **Wait till you’re assigned** an issue + +The majority of open-source projects have processes of selecting what issue is necessary to work on and who works on what issue. This is why it is important to ensure that your raised issue is either selected or you’re assigned to work on one. Not doing so before you start contributing may cause you to repeat someone else’s work. + +- Make **objectively valuable** contributions + +When making a contribution, it is important to ensure that your contribution is objectively valuable and not subjective. Only then does it create value for everyone in the community and not a specific group only. For example, fixing spelling mistakes in documentation is objectively valuable, but changing a paragraph from active to passive voice is not. + +- **Focus on quality** rather than quantity + +Rather than making too many contributions quickly and carelessly, it is better to focus on a smaller number and ensure they’re in the best shape possible. This way, your work leads to lesser maintenance debt and more positive value addition. + +- **Review** previously merged contributions + +Looking through past accepted contributions gives you a better idea of the project's development practices and communication processes. Better clarity on these makes it much easier for you to integrate within the operations of the projects. + +- **Don’t call dibs** on issues + +There’s plenty of work to go around for every person in the community, whether around code, documentation, maintenance, etc. Let’s make sure we don’t end up adding more barriers in the process by spamming requests to get assigned on every issue we find. + +- **Wait for a couple of days** before you ask for an issue to be **reassigned** + +When contributing to open source, it is necessary to remember that most people participate here outside of their day-to-day lives. With everything else in our lives, with work, academics, families, etc., sometimes people can’t prioritize open source immediately. A little patience here goes a long way for everyone. + +- **Communicate your progress** with the maintainers + +After you are assigned an issue, it’s good to update the project’s maintainers at regular intervals. This way, everyone in the process can track progress and challenges, thus keeping transparency for the community. + +- **Be patient** with the maintainers + +Most open-source work is unpaid and voluntary. Maintainers do it out of their love for the technology and community. And as lovely as maintaining their project can be, as the communities around their projects grow, it can very easily become overwhelming. Therefore, if your contribution has been under review for a while, patience goes a long way. + +- **Help** with Pull Request **reviews** + +Most open-source projects tend to have a much higher ratio of contributors to maintainers. Therefore, once you know what maintainers look for in changes, you can leave appropriate feedback for the project to help make life easier for everyone. + +- Give and accept **feedback** **constructively** and **humbly** + +The beauty of open source is that you could end up collaborating with people from drastically different places, walks of life, or knowledge levels. You never know whether the person you’re working with is a college sophomore or a veteran software engineer. Giving constructive feedback means that you enable others to learn and grow from your experiences. Accepting it with humility enables you to achieve the same. + +## Going forward + +Ensuring that open source remains healthy for everyone is a proactive effort across maintainers and contributors. As long as we all take the necessary steps, we can keep this community welcoming for new and experienced individuals alike in the coming times. \ No newline at end of file diff --git a/src/routes/blog/post/password-hashing-algorithms/+page.markdoc b/src/routes/blog/post/password-hashing-algorithms/+page.markdoc new file mode 100644 index 0000000000..806835baee --- /dev/null +++ b/src/routes/blog/post/password-hashing-algorithms/+page.markdoc @@ -0,0 +1,105 @@ +--- +layout: post +title: Demystifying password hashing algorithms +description: What are password hashing algorithms and how they help secure user credentials in your application +date: 2023-10-20 +cover: /images/blog/password-hashing-algorithms.png +timeToRead: 7 +author: aditya-oberai +category: authentication, security +--- + +In today's digital world, securing sensitive information such as passwords is of paramount importance. Password hashing algorithms play a crucial role in protecting user credentials and ensuring the integrity of authentication systems. In this blog, we will delve into the intricacies of password hashing algorithms, explore their key characteristics, and discuss some of the most widely used and secure algorithms to help you make informed decisions when implementing password storage and verification in your applications. + +## What is a password hashing algorithm? + +**Password hashing algorithms** are specialized mathematical functions that transform plaintext passwords into unique, fixed-size outputs, known as hashes, which are then stored in databases. Through the use of techniques such as salting, adjustable work factors, and memory hardness, modern password hashing algorithms are designed to thwart attacks and keep user data secure. + +The mathematical process of password hashing involves applying a hash function to a combination of a password and a salt, iterating the process based on a work factor, and, in some cases, incorporating memory hardness to increase the computational complexity. + +This function would operate as follows: + +`hash_result = HashFunction(Iterate(Combine(password, salt), work_factor), memory_hardness)` + +Where: + +- **`Combine(password, salt)`**: Combines the password and salt, possibly using concatenation or a more complex operation. +- **`Iterate(data, n)`**: Repeatedly applies a hash function 'n' times to 'data' to increase computational complexity. +- **`HashFunction(data, memory_hardness)`**: Applies the primary hash function to the data and optionally incorporates memory hardness. + +The result is a fixed-size hash that is unique, deterministic, and resistant to reverse engineering, ensuring the secure storage and verification of passwords. For example, inputting a string `loremipsum` into a hashing function that uses the SHA-256 algorithm would output `5245a52778d684fa698f69861fb2e058b308f6a74fed5bf2fe77d97bad5e071c`. + +### Characteristics of password hashing algorithms + +Password hashing algorithms have certain characteristics: + +- **One-way function** +Password hashing algorithms should be one-way functions, making it computationally infeasible to reverse-engineer the original password from the hash output, preventing attackers from trying to retrieve user passwords from the stored hashes. +- **Deterministic** +A password hashing algorithm must always produce the same hash output for a given input to ensure consistency and reliability. +- **Fixed-size output** +Password hashing algorithms must produce a fixed-size output (hash) regardless of the input size. This is necessary when verifying the password inputted by comparing it with its hash. +- **Slow computation** +Unlike general hashing algorithms, which prioritize fast computation, password hashing algorithms should be intentionally slow to compute. This characteristic makes it more time-consuming and resource-intensive for attackers to perform brute-force attacks or attempt to guess passwords using a large number of inputs. +- **Avalanche effect** +A small change in the input should result in a significant change in the hash output, making the new output appear uncorrelated with the old output. This property makes it difficult for attackers to predict the input based on the output or find two different inputs that produce the same output (collision). For example, the SHA-256 hash for `eight` is `c195d2d8756234367242ba7616c5c60369bc25ced2dcb5b92808d31b58ef217a`, but for `right` is `27042f4e6eca7d0b2a7ee4026df2ecfa51d3339e6d122aa099118ecd8563bad9`, despite having only one character different. +- **Pseudorandomness** +The output of a password hashing algorithm should appear random and uniformly distributed, making it difficult for attackers to predict patterns or relationships between inputs and their corresponding hash outputs. +- **Resistance to side-channel attacks** +Password hashing algorithms should be designed to resist side-channel attacks, such as timing attacks, where an attacker attempts to gain information about the password or hash by analyzing the time taken to compute the hash. +- **Adjustable work factor** +A good password hashing algorithm should allow for an adjustable work factor, also known as a cost factor or iteration count. This increases the algorithm's computational complexity over time as hardware capabilities improve, ensuring that the password hashing process remains secure and resource-intensive for attackers. +- **Memory hardness** +Some modern password hashing algorithms are designed to be memory-hard, meaning that they require a significant amount of memory to compute the hash. This characteristic makes it more difficult for attackers to perform parallel attacks using specialized hardware, such as GPUs or ASICs, which have limited memory resources. +- **Wide adoption and peer review** +A reliable password hashing algorithm should have a proven track record, be widely adopted, and have undergone extensive peer review and analysis by the cryptographic community. This ensures that the algorithm has been tested for vulnerabilities and is considered secure for password storage and verification. + +## Examples of password-hashing algorithms + +Here are some modern password-hashing algorithms and their concise descriptions: + +- **Bcrypt** +Bcrypt is a widely used password hashing algorithm based on the Blowfish cipher. It incorporates a salt and an adjustable work factor to slow down the hashing process, making brute-force attacks more time-consuming. Bcrypt is designed to be resistant to side-channel attacks and is considered secure for password storage. +- **Scrypt** +Scrypt is a memory-hard password hashing algorithm that requires a significant amount of memory to compute the hash, making it more difficult for attackers to perform parallel attacks using specialized hardware. It also supports adjustable work factors and salt usage. Scrypt was specifically designed to protect against hardware-based attacks, such as those using GPUs or ASICs. +- **Argon2** +Argon2 is a modern, memory-hard password hashing algorithm that won the Password Hashing Competition in 2015. It offers adjustable work factors for both time (computation) and memory usage, providing a balance between security and performance. Argon2 supports salting and has three main variants: + - `Argon2i`: optimized for resistance to side-channel attacks + - `Argon2d`: optimized for resistance to time-memory trade-off (TMTO) attacks + - `Argon2id`: a hybrid version of both of the above +- **PBKDF2 (Password-Based Key Derivation Function 2)** +PBKDF2 is a widely-used password hashing algorithm that iteratively applies a pseudorandom function, such as HMAC, to the input password and salt. It supports an adjustable work factor, increasing the number of iterations to make the hashing process slower and more resistant to attacks. While PBKDF2 is considered secure, it is not memory-hard and may be more susceptible to hardware-based attacks compared to `scrypt` or `Argon2`. These modern password hashing algorithms are designed to provide increased security for password storage and verification by incorporating features like salting, adjustable work factors, memory hardness, and resistance to various types of attacks. + +## Password hashing and Appwrite + +Appwrite Authentication also leverages password hashing algorithms to allow developers to secure their users’ passwords via password hashing algorithms. Appwrite uses the `Argon2id` algorithm to hash the password when a user creates an account from a client-side application. Appwrite’s SDKs offer a simple abstraction for the Appwrite Accounts API to let developers implement this, like the following example: + +```js +import { Client, Account, ID } from "appwrite"; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject(''); + +const account = new Account(client); + +const user = await account.create(ID.unique, 'email@example.com', 'password'); +``` + +When a developer implements account creation on a server-side application, however, the Appwrite Users API allows them to input a password that has been hashed using any of the following hashing algorithms: + +- Argon2 +- Bcrypt +- MD5 +- Scrypt +- Scrypt Modified +- PHPass +- SHA + +An additional side-benefit this offers is that it allows a developer to migrate users from other platforms, such as Firebase, Supabase, and Nhost, using [Appwrite Migrations](https://appwrite.io/docs/advanced/migrations). + +## Recap + +In summary, password hashing algorithms are essential tools for securing sensitive user data, particularly passwords, in modern applications. By understanding these algorithms, developers can make informed decisions when implementing password storage and verification systems. and ensure the security and integrity of their users' data. + +If you want to implement an authentication system that leverages the power of hashing algorithms simply and quickly, try [Appwrite](https://appwrite.io). \ No newline at end of file diff --git a/src/routes/blog/post/password-protection/+page.markdoc b/src/routes/blog/post/password-protection/+page.markdoc new file mode 100644 index 0000000000..73e6a9d01a --- /dev/null +++ b/src/routes/blog/post/password-protection/+page.markdoc @@ -0,0 +1,75 @@ +--- +layout: post +title: "Password protection for developers: importance and best practices" +description: Why it is necessary to implement strong password protection policies in your app and best practices to follow +date: 2023-10-11 +cover: /images/blog/password-protection.png +timeToRead: 6 +author: aditya-oberai +category: authentication, security +--- + +Today, our lives are more digitally connected than ever. The internet has brought us a plethora of benefits, making day-to-day activities, such as shopping, banking, and communication, easier for society. This convenience does come at a cost, however. Every important activity we perform on the internet is associated with a digital identity, and this identity is only as secure as we make it. + +Unfortunately, as seen across multiple incidents in recent history, not everyone’s digital identity on the internet has been maintained securely. The primary culprit in these incidents, such as the [LinkedIn Data Breach](https://www.cbsnews.com/news/linkedin-2012-data-breach-hack-much-worse-than-we-thought-passwords-emails/) in 2012, the [Yahoo Data Breach](https://www.nytimes.com/2017/10/03/technology/yahoo-hack-3-billion-users.html) in 2012-13, or the [GoDaddy Data Breach](https://techcrunch.com/2021/11/22/godaddy-breach-million-accounts/) in 2021, is weak passwords. + +As software developers, it is essential to remember that our applications’ data is only as secure as the people who use them. Identity verification carries the utmost importance here, which leads us to discuss the necessity of using passwords to secure access to data and resources in our software, or as we say in short, “password protection.” In this blog, let’s learn why strong password protection is essential and what best practices we can keep in mind while implementing the same. + +## Why strong password protection is necessary to implement + +There are numerous reasons why we as developers must implement password protection in our software: + +- **Safeguard User Data** +Developers are responsible for protecting sensitive user information such as personal data, financial details, and other private information. Proper password protection ensures unauthorized individuals cannot access this data, helping maintain user trust and privacy. + +- **Protect Application Integrity** +Weak password protection can lead to unauthorized access, resulting in data breaches, application functionality tampering, and other malicious activities. By implementing robust password protection measures, developers can maintain the integrity of their applications and minimize the risk of cyberattacks. + +- **Prevent Unauthorized Access** +A strong password protection system helps prevent unauthorized users from gaining access to restricted areas of an application, such as admin panels or user accounts. This ensures that only authorized users can access and modify data, reducing the chances of data leaks and minimizing possible attack vectors. + +- **Reduce Support and Incident Response Costs** +A secure password protection system can reduce the number of support requests and incidents related to compromised accounts. This, in turn, reduces the time and resources spent on handling these issues, allowing developers to focus on improving the application and delivering new features. + +- **Compliance with Regulations** +Various data protection regulations and standards, such as GDPR, HIPAA, and PCI DSS, require developers to implement secure authentication mechanisms, including strong password protection. Failing to comply with these regulations can lead to legal penalties, fines, and reputational damage. + +- **Preserve Brand Reputation** +Data breaches and security incidents severely impact a company’s reputation, leading to a loss of user trust and potential financial losses. Developers can help protect their company’s brand and maintain customer confidence by implementing proper password protection measures. + + +## Best practices to implement password protection + +Now that we have discussed the importance of password protection, let’s learn about some best practices to remember as you implement password protection policies for your software: + +- **Enforce strong password policies** +Encourage users to create strong, unique passwords by enforcing password requirements such as keeping minimum length, having a mix of uppercase and lowercase letters, numbers, and special characters, and removing personal information such as their name, date of birth, or email address. You can use libraries like `zxcvbn` to estimate password strength and provide suggestions for improvement. + +- **Maintain password dictionary** +Utilize a password dictionary that contains commonly used weak passwords to check for when any user sets their password. This prevents any user from choosing a password that can be easily cracked in scenarios such as brute-force attacks. + +- **Enforce maximum password age policy and password history** +Enforce a maximum password age to ensure all users periodically update their passwords. Maintaining password history prevents compromised passwords from being used to attack a system or application beyond a limited time frame. + +- **Implement multi-factor authentication (MFA)** +Add an extra layer of security by requiring users to provide a second form of verification (or more), such as a one-time password sent via email or SMS to their mobile device generated by an authenticator app like Google Authenticator or Twilio Authy. + +- **Secure password resets** +Implement password reset functionality using a secure token that expires after a short period. Send the token via a secure communication channel like email or SMS, and require users to enter the token with their new password to ensure the individual is authorized to update the password. + +- **Hash and salt passwords** +Always store hashed and salted passwords instead of plain text. Hashing is a one-way function that transforms a password into a fixed-length string of characters, while salting adds a random value to the password before hashing to prevent precomputed attacks like rainbow tables. Use modern hashing algorithms like `bcrypt`, `scrypt`, or `Argon2`, which are designed to be slow and computationally expensive, making brute-force attacks more difficult. + +- **Use rate limiting and account lockout mechanisms** +Prevent brute-force attacks by temporarily locking accounts or requiring users to complete a captcha after a certain number of failed login attempts. Implement rate limiting to limit the number of authentication attempts within a specific time frame. This will also give your team time to investigate and prevent attacks before damage is caused. + +- **Monitor and audit** +Regularly monitor and audit your authentication system for suspicious activity and maintain logs to help with incident response and forensic analysis. + +- **Educate your users** +Please help your users understand why setting strong passwords is necessary and how password managers like LastPass, 1Password, or Bitwarden can help them generate and manage their passwords. + + +## Moving Forward + +Security is a shared responsibility between developers and users. Collaborating with them in this process is essential to implement better password protection and keep your applications secure. As a developer, by the way, if you would like to try an authentication solution that implements better password protection policies out-of-the-box, look at [Appwrite](https://appwrite.io/docs/products/auth). With various features such as password hashing, session limits, a strong permissions system, password history, a password dictionary, and personal data checks in passwords, [Appwrite Authentication](https://appwrite.io/docs/products/auth) offers an easy-to-implement yet robust authentication system for you to build with. diff --git a/static/images/blog/make-open-source-healthier.png b/static/images/blog/make-open-source-healthier.png new file mode 100644 index 0000000000..14446c0037 Binary files /dev/null and b/static/images/blog/make-open-source-healthier.png differ diff --git a/static/images/blog/password-hashing-algorithms.png b/static/images/blog/password-hashing-algorithms.png new file mode 100644 index 0000000000..78aee9fb68 Binary files /dev/null and b/static/images/blog/password-hashing-algorithms.png differ diff --git a/static/images/blog/password-protection.png b/static/images/blog/password-protection.png new file mode 100644 index 0000000000..becbbbfb88 Binary files /dev/null and b/static/images/blog/password-protection.png differ