LUC #17: Essential Practices for Handling and Storing Sensitive Data
Plus, HTTP status codes, important Git commands, and SQL count function explained
Welcome back, coding enthusiasts! We're excited to share another issue of Level Up Coding’s newsletter with you.
In today’s issue:
Read time: 7 minutes
Approaches to Safeguarding Sensitive Data
When we trust systems with our sensitive data, we expect them to keep them secure and protected. A data breach can have a devastating impact on both an organization and its customers, ranging from financial losses to reputational damage. There are several techniques that companies can use to protect their customers' sensitive data, but before we explore them let's first define what sensitive data is.
When unauthorized access to information compromises the privacy or security of an individual or organization, that information is considered sensitive. This includes personally identifiable information such as social security numbers, financial data such as credit card numbers, proprietary business information, and any other confidential data such as personal health information.
It’s key to identify the sensitive data that runs through your system as it helps you specify the scope of your security efforts. Most data protection techniques come with considerable overhead which is why it isn’t ideal to implement security efforts on data and systems that don’t need it. Moreover, thoroughly audit your stored data and avoid storing sensitive information that isn't necessary such as those that can be fetched from third-party services; this reduces your security requirements.
Encryption is a typical strategy for data protection. It is done at rest (when the data is stored in a database), and in transit (when sent across networks) using protocols such as TSL. Even if the data was breached or intercepted, encryption makes it unreadable to anyone other than those who are authorized to see it.
Cryptography is heavily used in almost every data-protection strategy. It is implemented in encryption, key management, digital signatures, and much more. When using cryptographic algorithms, it is best to rely on established and well-maintained libraries such as OpenSSL than to build your own. To mitigate against brute-force attacks, key derivation functions that are intentionally slow should be used. Additionally, introducing random data, or "salt", to hash functions makes it significantly more challenging for attackers to decrypt.
Strong access control is critical. Keys used for encryption should be periodically rotated, all requests should be authenticated, and access to sensitive data should be limited using the principle of least privilege.
Just like encryption, tokenization protects data by replacing it with data that is unusable to unauthorized parties rather than limiting access to it. It does this by replacing sensitive data with placeholders, or "tokens". These tokens have no intrinsic value and can't be reversed to their original form without access to the specific tokenization system. Tokenization is a common practice in FinTech to avoid sharing credit card information between services.
Backup systems have the tendency to slip through the cracks when it comes to data protection initiatives. It is important to ensure that the security strategies implemented on the primary database are also implemented on backup storage systems.
It's essential to carry out regular audits, ensuring that the system aligns with the latest and most efficient security practices. With ongoing monitoring, technical teams can identify and address potential vulnerabilities before they become major threats. Moreover, continuous training and education are crucial not only to enhance the skills of technical teams but also to stay informed about emerging security threats.
Protecting sensitive data is far from a "set and forget" task, it requires an ongoing process with a commitment to security across the board. Highly secure systems tend to have one thing in common — their technical teams have security embedded into their culture; from how they design solutions to how they undergo code reviews.
HTTP Status Codes (recap)
When a server receives a request from a client, it provides a response that includes a 3-digit status code that communicates the request’s outcome or status. HTTP status codes are divided into five categories, each identified by the first digit of the code:
🟣 Informational (1xx): The request was received, and the process is continuing.
🟢 Success (2xx): The request was successfully received, understood, and accepted.
🔵 Redirection (3xx): The request needs further action to be completed.
🔴 Client Error (4xx): The request contains incorrect syntax or cannot be fulfilled by the server.
🟠 Server Error (5xx): The server failed to fulfill a valid request.
SQL Count Function (recap)
SQL count function is an aggregate function that returns the number of rows that match a specified condition. Below are the most common ways COUNT() is used:
𝗖𝗢𝗨𝗡𝗧(*): Returns the total number of rows, regardless of NULL values in any of the columns.
𝗖𝗢𝗨𝗡𝗧(𝗰𝗼𝗹𝘂𝗺𝗻_𝗻𝗮𝗺𝗲): Returns the total number of values where the value is not NULL.
🔸 With the 𝗚𝗥𝗢𝗨𝗣 𝗕𝗬 clause: Returns the total count for each value of the specific column.
Best practices for optimizing performance
🔹 Use WHERE clauses: Filter to count on only the data you need, this makes queries run faster, especially on large datasets.
🔹 Leverage indexed columns: Counting on an indexed column can speed queries significantly.
🔹 Avoid using it in subqueries: This can lead to performance issues, try redesigning the query where possible.
🔹 Use DISTINCT to count unique values: Useful function, although it can be resource-intensive on large datasets.
Important Git Commands (recap)
🔸 git add: moves changes to staging, ready for the next commit
🔸 git reset: the opposite of git add; it moves changes from staging back into the working directory so they are not included in the next commit. Be careful with this command as it can be destructive!
🔸 git commit: takes all changes in staging and moves them into the local repository as a commit.
Saving changes for later
🔸 git stash: saves changes that you don’t want to work with or commit into a stash.
🔸 git stash apply: moves stashed changes back into the working directory.
🔸 git stash pop: moves stashed changes back into the working directory and deletes the stash.
Working with remote
🔸 git pull: retrieves changes from the remote repository and saves them into your current branch which updates your working directory.
🔸 git push: sends your local repository to the remote repository.
🔸 git fetch: updates your local remote branch tracking with the current state of the remote repository.
🔸 git merge: merges another branch into your current branch. If there are any merge conflicts, it will appear in your working directory for you to fix. Otherwise, it will automatically commit the changes and update your local repository.
That wraps up this week’s issue of Level Up Coding’s newsletter!
Join us again next week where we’ll explore MVC vs MVP architecture, Python list methods, and what is Kafka.