Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8136ce5

Browse files
committed
chore: clearup major typos
1 parent ef9180c commit 8136ce5

16 files changed

+322
-119
lines changed

public/blogs/bootcamp-ripoff.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
2-
title: Hi, I'm a "React" developer
3-
seoTitle: Bootcamps flooded the market with mediocre talent, Hi I'm a React developer.
4-
summary: No, you're another victim of bootcamps, flooding the market with mediocre talent
2+
title: Bootcamps
3+
seoTitle: Bootcamps flooded the market with mediocre talent.
4+
summary: The root cause of developer skill-issues ?
55
isReleased: true
66
isSequel: false
77
lastModDate: 2024-04-01T09:15:00-0401

public/blogs/csrf-mitigation.mdx

Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
---
2+
title: CSRF Mitigation
3+
seoTitle: CSRF Mitigation techniques
4+
summary: If you're vulnerable to XSS, none of this will work
5+
isReleased: true
6+
isSequel: false
7+
lastModDate: 2022-09-04T09:15:00-0401
8+
firstModDate: 2022-09-04T09:15:00-0401
9+
minutesToRead: 7
10+
tags:
11+
- 'csrf'
12+
- 'cybersec'
13+
---
14+
15+
<C>
16+
If you don't rely on a framework to do the heavy lifting for you, or a third party library. As I always say: you have to [understand]() the subject before you abstract it. Here's how to do it manually, but first note thhat none of the techniques below will work if you're already [XSS]() vulnerable
17+
</C>
18+
<H2>Where Did The Request Come From?</H2>
19+
<C>
20+
If you do not trust the request's origin, block it.
21+
</C>
22+
<H3>"Origin" Header</H3>
23+
<C>
24+
Since the `Origin` header is being added automatically by browsers as part of the [`CORS`]() mechanism, you can check and validate the header, to check if the request that is coming in, actually comes from you site, block it if it doesn't
25+
</C>
26+
<Code
27+
code={`if r.Header.Get("Origin") != "https://my-actual-site.com" {
28+
http.Error(w, "Bad Request", http.StatusBadRequest)
29+
return
30+
}`}
31+
language="go"
32+
showLineNumbers={false}
33+
/>
34+
<H3>"Sec-Fetc-" Headers</H3>
35+
36+
<C>
37+
Fetch Metadata headers, [introduced]() in 2019 to provide additional context about the resource request. But all you have to know for now is you can use it to to check the origin
38+
</C>
39+
<Code
40+
code={`if secFetchSite := r.Header.Get("Sec-Fetch-Site");
41+
secFetchSite != "" && secFetchSite != "same-origin" {
42+
http.Error(w, "Bad Request", http.StatusBadRequest)
43+
return
44+
}
45+
`}
46+
language="go"
47+
showLineNumbers={false}
48+
/>
49+
<C>
50+
Learn more about `Sec-Fetch` headers [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Mode) and [here](https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-site-header)
51+
</C>
52+
<C>
53+
You can use a combo of these two, just to make sure, if one doesn't exist is altered the other might be used. But solely relying on headers is not sufficient, headers could potentially be tampered with or omitted due to certain browser vulnerabilities, network configurations or proxies misconfigurations. So other techniques should be employed too, like
54+
</C>
55+
56+
<H2>Anti-CSRF tokens</H2>
57+
58+
<C>
59+
CSRF tokens are a common and effective technique to prevent Cross-Site Request Forgery attacks, they are cryptographically secure pseudorandom characters or digits, and they basically work like this:
60+
</C>
61+
<C>
62+
When a client makes a request, the server verifies the token's existence and validity against the token stored in the user's session (the mechanism of which the user session is stored might differ). If the token is missing or doesn't match, the request is rejected as potentially malicious.
63+
</C><C>
64+
There are two main ways to implement anti-CSRF tokens:
65+
</C>
66+
<H3>Stateless Services</H3>
67+
<C>
68+
As in, user sessions can be managed without a database by storing session information as a [JWT]() or [JWE]() within a [cookie](). To defend against CSRF attacks in this setup, use the "Signed Double Submit Cookie Method.":
69+
</C><C>
70+
This method involves generating a unique and cryptographically secure random value, typically a UUID, when a user first authenticates. This UUID is then embedded within both the payload of the JWT/JWE and the CSRF token. To ensure the integrity and authenticity of the CSRF token, use an [HMAC](https://datatracker.ietf.org/doc/html/rfc2104.html), which you combine a secret key (used for signing/encrypting the JWT/JWE) with a hash function like [Blake3](https://github.com/BLAKE3-team/BLAKE3) or SHA256 (make sure it's not computationally intensive but secure enough) , to produce a fixed-size hash value representing the message's integrity. The HMAC message includes two parts: a new random value for collision avoidance and the shared UUID between the JWT/JWE and the CSRF token.
71+
</C><C>
72+
The idea might **Go** like this
73+
</C>
74+
<Code
75+
code={`package main
76+
77+
import (
78+
"crypto/hmac"
79+
"crypto/rand"
80+
"crypto/sha256"
81+
"encoding/hex"
82+
"fmt"
83+
"os"
84+
85+
"github.com/google/uuid"
86+
)
87+
88+
func main() {
89+
// Gather the values
90+
91+
// Both HMAC and JWT/JWE secret key
92+
secret := getSecretKey("CSRF_SECRET")
93+
uuid := generateUUID()
94+
95+
// Random value for collision purposes
96+
randomValue := generateAntiCollisionValue()
97+
98+
// Create the CSRF Token
99+
100+
// HMAC message payload
101+
message := fmt.Sprintf("%s!%s", uuid, randomValue)
102+
// Generate the HMAC hash
103+
hmacValue := generateHMAC(secret, message)
104+
// Combine HMAC hash with message to generate the token
105+
csrfToken := fmt.Sprintf("%s.%s", hmacValue, message)
106+
107+
fmt.Println("CSRF Token:", csrfToken)
108+
}
109+
110+
111+
func getSecretKey(name string) string {
112+
return os.Getenv(name)
113+
}
114+
115+
func generateUUID() string {
116+
ns := uuid.Nil
117+
name := "some-arbitrary-name"
118+
return uuid.NewSHA1(ns, []byte(name)).String()
119+
}
120+
121+
func generateAntiCollisionValue() string {
122+
b := make([]byte, 16)
123+
rand.Read(b)
124+
return hex.EncodeToString(b)
125+
}
126+
127+
func generateHMAC(secret, message string) string {
128+
key := []byte(secret)
129+
h := hmac.New(sha256.New, key)
130+
h.Write([]byte(message))
131+
return hex.EncodeToString(h.Sum(nil))
132+
}`}
133+
language="go"
134+
showLineNumbers={false}
135+
/>
136+
<C>
137+
On the server side, when handling incoming requests, the server decodes or decrypts the JWT or JWE to extract the UUID. Simultaneously, it decodes the HMAC-CSRF token, verifies its integrity using the stored secret key, if the integrity was not preserved, the server blocks, else it extracts the UUID. If the extracted UUIDs do not match, there is a potential indication of tampering or unauthorized access, the server blocks.
138+
</C>
139+
140+
<H3>Stateleful Services</H3>
141+
<C>
142+
As in, you use a database to store a user's session, the cookie is just a reference to the user session, like an ID. Use the Synchronizer Pattern:
143+
</C>
144+
<C>
145+
When a user session is initiated on the server, a unique, secret, and unpredictable CSRF token is generated and associated with that session. This token is then transmitted to the client as part of the response payload. This transmission can occur by embedding the token within HTML forms as a hidden field, including it in JSON responses, or setting it as a custom HTTP header for AJAX requests.
146+
</C><C>
147+
Subsequently, when the client makes further requests to the server, it includes this CSRF token with each request. By doing so, the server can verify that the request originated from its own legitimate pages and was not initiated by a malicious third-party site attempting a CSRF attack.
148+
</C><C>
149+
Here's an AJAX example
150+
</C>
151+
<Code
152+
code={`<!doctype html>
153+
<html lang="en">
154+
<head>
155+
<meta charset="UTF-8" />
156+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
157+
<title>AJAX Request with CSRF Token</title>
158+
</head>
159+
<body>
160+
<div id="ajaxResponse"></div>
161+
<script>
162+
document.addEventListener('DOMContentLoaded', () => {
163+
createCSRFTokenContainer();
164+
document
165+
.getElementById('makeRequestButton')
166+
.addEventListener('click', () => {
167+
// Make an AJAX request when the button is clicked, it should
168+
// show a successful message when no CSRF attack is made
169+
var xhr = new XMLHttpRequest();
170+
171+
var csrfToken = getCSRFTokenFromClient();
172+
173+
xhr.open('POST', '/protected', true);
174+
175+
xhr.setRequestHeader('CSRF-Token', csrfToken);
176+
177+
xhr.onreadystatechange = () => {
178+
if (xhr.readyState === XMLHttpRequest.DONE) {
179+
// The server validates the token sent in the header,
180+
// if it matches the one stored on the server,
181+
// it sends an OK response.
182+
// else it blocks the request
183+
if (xhr.status === 200) {
184+
// allow
185+
document.getElementById('ajaxResponse').innerText =
186+
"You're allowed, come in";
187+
} else {
188+
// BLOCK! Possible forgery
189+
document.getElementById('ajaxResponse').innerText =
190+
"You're blocked, the CSRF Token has been tampered with";
191+
console.error('AJAX request failed:', xhr.status);
192+
}
193+
}
194+
};
195+
});
196+
});
197+
198+
199+
200+
function createCSRFTokenContainer() {
201+
var csrfToken = 'CSRF_TOKEN' // use a template engine,
202+
// or whatever framework you're using
203+
// to render this value.
204+
// div element to hold the hidden token
205+
var csrfDiv = document.createElement('div');
206+
csrfDiv.id = 'csrfTokenDiv';
207+
// hidden input field and set its value to the generated CSRF token
208+
var input = document.createElement('input');
209+
input.type = 'hidden';
210+
input.name = 'CSRFToken';
211+
input.value = csrfToken;
212+
csrfDiv.appendChild(input);
213+
}
214+
215+
function getCSRFTokenFromClient() {
216+
var csrfTokenDiv = document.getElementById('csrfTokenDiv');
217+
218+
if (csrfTokenDiv) {
219+
var inputField = csrfTokenDiv.querySelector(
220+
'input[type="hidden"][name="CSRFToken"]'
221+
);
222+
223+
if (inputField) {
224+
return inputField.value; // The CSRF token value
225+
}
226+
}
227+
}
228+
</script>
229+
   <button id="makeRequestButton">Make AJAX Request</button>
230+
</body>
231+
</html>
232+
`}
233+
language="html"
234+
showLineNumbers={false}
235+
/>
236+
<C>
237+
If you want to see a framework implementation of the synchronized pattern , check out [`Django`]()'s implementation with the CSRF mitigation middleware, you can read the source code [here]().
238+
</C>
239+
<H2>Cookies</H2>
240+
<C>
241+
Avoid setting cookies with a specific domain to minimize security risks. When a cookie is domain-specific, all subdomains share that cookie, which can pose risks if subdomains are linked to external domains through CNAME records.
242+
</C><C>
243+
For session cookies, ensure they are protected by:
244+
</C><C>
245+
- \- Using the `HttpOnly` attribute to prevent client-side scripts from accessing cookies, enhancing security against XSS attacks.
246+
- \- Setting the `SameSite` attribute to `Lax` or `Strict` to control cookie behavior in cross-site requests, more [below]().
247+
- \- Avoid specifying a domain (`Domain=None`) to prevent cookies from being sent in cross-origin requests.
248+
- \- Using the `Secure` attribute to ensure that cookies are only sent over HTTPS connections.
249+
</C><C>
250+
Also, for enhanced security measures, consider cookie prefixes like `__Host-` and `__Secure-`, read more [here]()
251+
</C>
252+
<H3>About "SameSite" Cookies</H3>
253+
<C>
254+
Use the `SameSite` cookie attribute to set your users sessions (older browsers do not support this)
255+
</C>
256+
<Code
257+
code={`Set-Cookie: SID=xxxxx; SameSite=Strict`}
258+
language="http"
259+
showLineNumbers={false}
260+
/>
261+
<C>
262+
Or
263+
</C>
264+
<Code
265+
code={`Set-Cookie: SID=xxxxx; SameSite=Lax`}
266+
language="http"
267+
showLineNumbers={false}
268+
/>
269+
<C>
270+
Read about [`Lax`]() and [`Strict`]() from the official [RFC](). Here's is basically what they do:
271+
</C>
272+
<C>
273+
**``Strict``:** This value prevents cookies from being sent in all cross-site browsing contexts, including regular links. For example: You're logged in your banking account, which means you have a session cookie. If this banking website employs the Strict ``SameSite`` value for its session cookies, and you click on a link to perform a banking transaction from an external website (like a forum or email) say https://scam-me-please.com , the banking website won't receive the session cookie due to the ``Strict`` setting. Consequently, the user won't be able to complete the transaction because the session information is not sent with the request.
274+
</C><C>
275+
**``Lax``:** The default value of ``SameSite`` is Lax ( since Chrome version 80, in February 2020) , which provides a balance between security and usability. Cookies are allowed when following regular links from external sites but are blocked in CSRF-prone requests such as POST methods. Only cross-site requests that are considered safe (like top-level navigations) are allowed in Lax mode.
276+
</C><C>
277+
**``None``:** Using the ``None`` value means the cookie is sent with all cross-site requests, which can potentially expose users to CSRF attacks. Simply don't use this.
278+
</C>
279+
<H2>User Interaction-Based CSRF Defense</H2>
280+
281+
<C>
282+
Requiring users to authenticate using their password, biometric data, security questions, or [OTP]() is a highly effective security measure. However, it can significantly impact user experience, so it's typically used only for critical operations like changing passwords or conducting financial transactions. Avoid using CAPTCHA for this purpose, as it's primarily aimed at preventing automated bot attacks and doesn't provide the necessary level of security for these sensitive activities.
283+
</C>
284+
<H2>HTTP Methods</H2>
285+
<C>
286+
And oh yeah, this is obvious but, For any state changing request, DON'T USE [safe methods]().
287+
</C>

public/blogs/framer-motion.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: Framer Motion
33
seoTitle: Supercharge Animations in React with Framer Motion
44
summary: Supercharge animations in React
5-
isReleased: true
5+
isReleased: false
66
isSequel: false
77
lastModDate: 2020-02-17T09:15:00-0401
88
firstModDate: 2020-02-17T09:15:00-0401

public/blogs/gsap-just-got-better.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: GSAP
33
seoTitle: Using the newly added useGSAP() hook as a drop-in replacement for UseEffect()
44
summary: GSAP just added useGSAP() hook for React
5-
isReleased: true
5+
isReleased: false
66
isSequel: false
77
lastModDate: 2024-01-19T09:15:00-0401
88
firstModDate: 2024-01-19T09:15:00-0401

public/blogs/management-skill-issues.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
---
22
title: Team Motivation
33
seoTitle: Why is your software team losing or have no motivation
4-
summary: Why is your software team slacking big time ?
4+
summary: Free perks and forced fun won't make your team work harder
55
isReleased: true
66
isSequel: false
7-
lastModDate: 2024-01-19T09:15:00-0401
8-
firstModDate: 2024-01-19T09:15:00-0401
7+
lastModDate: 2023-10-10T09:15:00-0401
8+
firstModDate: 2023-10-10T09:15:00-0401
99
minutesToRead: 8
1010
tags:
1111
- 'management'

public/blogs/micro-management.mdx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
---
2-
title: Are You a Micromanager ?
3-
seoTitle: If you tend to micromanage people, here's how to fix it
4-
summary: If you are, here's the fix
2+
title: Micromanagement
3+
seoTitle: If you have to micromanage people, here's how to fix it
4+
summary: Modern problems, require ancient solutions
55
isReleased: true
66
isSequel: false
77
lastModDate: 2023-07-14T09:15:00-0401
88
firstModDate: 2023-07-14T09:15:00-0401
99
minutesToRead: 2
1010
tags:
11-
- 'testing'
11+
- 'management'
12+
- 'skill-issues'
1213
---
1314

1415
<C>

public/blogs/param-spec.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
---
2-
title: ParamSpec for @decorators
3-
seoTitle: How to use ParamSpec to type decorators, for the impatient.
4-
summary: How to use ParamSpec to type decorators, for the impatient.
5-
isReleased: true
2+
title: ParamSpec
3+
seoTitle: How to use ParamSpec to type @decorators, for the impatient.
4+
summary: How to use ParamSpec to type @decorators, for the impatient.
5+
isReleased: false
66
isSequel: false
77
lastModDate: 2021-10-02T09:15:00-0401
88
firstModDate: 2021-10-02T09:15:00-0401

public/blogs/python-protocols.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ showLineNumbers={false}
128128
</C>
129129
<H3>Ok we know all that, what's special</H3>
130130
<C>
131-
Consider a case where you have various classes representing different request or response objects, possibly from different libraries. You aim to consolidate these diverse objects and their methods into a unified class or adapter. You might expect these classes to inherit from a common base class. However, using protocols, you can define a protocol that outlines the expected behavior of response objects with an abstracted one. This enables disparate classes to conform to the same structure without requiring a shared ancestry.
131+
Let'say you have various classes representing different request or response objects, possibly from different libraries. You aim to consolidate these diverse objects and their methods into a unified class or adapter. You might expect these classes to inherit from a common base class. However, using protocols, you can define a protocol that outlines the expected behavior of response objects with an abstracted one. This enables disparate classes to conform to the same structure without requiring a shared ancestry.
132132
</C>
133133
<Code
134134
code=

public/blogs/react-object-destructuring.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: React Object Destructuring
33
seoTitle: Stop Object Destructuring in React with TypeScript It's an Anti-Pattern
4-
summary: Is an anti-paterrn with TypeScript, and you should stop using it
4+
summary: My eyes hurt when I see it, stop it, it's an anti-pattern
55
isReleased: true
66
isSequel: false
77
lastModDate: 2021-12-27T09:15:00-0401

public/blogs/redis-instances-local-testing.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: Test Redis with Docker
33
seoTitle: Automated Containerized Approach For Testing Redis Connections In CI pipelines
44
summary: Automated containerized approach to test Redis in CI
5-
isReleased: true
5+
isReleased: false
66
isSequel: false
77
firstModDate: 2020-04-12T09:15:00-0400
88
lastModDate: 2020-04-12T09:15:00-0400

0 commit comments

Comments
 (0)