दिन 26: Security और Clean Code
✅ आज आप सीखेंगे
- XSS: attackers scripts कैसे डालते हैं – और कैसे रोकें
- सुरक्षित rendering: textContent, escaping, sanitising
- CSP, HTTPS, cookies और third-party scripts
- Secrets और “client पर कभी भरोसा नहीं” (prices, discounts)
- Clean code: naming, छोटे functions, comments, एकरूपता
🏢 असली दुनिया में
छोटी Indian e-commerce sites का असली pattern: product review box reviews को innerHTML से render करता था। किसी ने ऐसा “review” डाला जिसमें script थी जो हर visitor का session token copy करती थी। दूसरी site discount JavaScript में गिनती थी – customer ने DevTools में price बदला और gift box के ₹1 दिए। दोनों front-end ग़लतियाँ आज के बाद आप कभी नहीं करेंगे।
XSS: front-end की नंबर एक कमज़ोरी
<p>A customer review (imagine it came from the database):</p>
<div id="unsafe" style="border:2px solid #dc2626;padding:8px;border-radius:8px"></div>
<div id="safe" style="border:2px solid #16a34a;padding:8px;border-radius:8px;margin-top:8px"></div>
<p id="alarm" style="color:#b91c1c;font-weight:700"></p>
<script>
const review = 'Tasty! <img src="x" onerror="document.querySelector(\'#alarm\').textContent=\'⚠️ Attacker code ran – it could have stolen your login!\'">';
document.querySelector('#unsafe').innerHTML = '❌ innerHTML: ' + review; // executes the attacker’s code
document.querySelector('#safe').textContent = '✅ textContent: ' + review; // shown as harmless text
</script>| Sink (ख़तरनाक) | सुरक्षित विकल्प |
|---|---|
| el.innerHTML = userText | el.textContent = userText |
| User data वाला template literal HTML | createElement + textContent, या हर value पर escape() |
| insertAdjacentHTML / document.write | आपके बनाए nodes append() |
| href = userUrl (javascript: URLs!) | सिर्फ़ http(s): new URL(u).protocol जाँच |
| eval(), new Function(), setTimeout("string") | User data के साथ कभी नहीं – functions और JSON.parse |
| Rich text (HTML editor content) | डालने से पहले DOMPurify से sanitise |
HTML strings बनानी ही हों तो escaping
function escapeHTML(value) {
return String(value)
.replaceAll('&', '&')
.replaceAll('<', '<')
.replaceAll('>', '>')
.replaceAll('"', '"')
.replaceAll("'", ''');
}
// a tagged template that escapes every ${value} automatically
function html(strings, ...values) {
return strings.reduce((out, str, i) => out + str + (i < values.length ? escapeHTML(values[i]) : ''), '');
}
const review = { name: 'Rahul <script>steal()</script>', text: 'Best "ghewar" ever & fresh' };
console.log(html`<li><b>${review.name}</b>: ${review.text}</li>`);
function safeLink(url) {
try {
const u = new URL(url, 'https://sharmasweets.in');
return ['http:', 'https:'].includes(u.protocol) ? u.href : '#';
} catch { return '#'; }
}
console.log(safeLink('https://maps.google.com/?q=Johari+Bazaar'), safeLink('javascript:alert(1)'));Client पर कभी भरोसा नहीं
सिर्फ़ browser में ❌
- JS से भेजा price और discount: { total: 1 }
- Coupon validity सिर्फ़ JS में
- Stock सिर्फ़ JS में
- localStorage में “isAdmin: true” flag
सही design ✅
- सिर्फ़ product ids और quantities भेजें
- Server prices देखे, coupons लगाए, stock जाँचे
- Customer जो देगा वह total server गिने
- हर server request पर permissions जाँचें
Day 20 में POST body में सिर्फ़ { id, qty } था – API ने ख़ुद prices देखे, sold-out items मना किए और delivery गिनी। Front-end validation user experience के लिए है; सच server के लिए।
Secrets, keys और tokens
| चीज़ | क्या front-end JS में हो सकती है? | क्यों |
|---|---|---|
| Payment gateway SECRET key | ❌ कभी नहीं | कोई भी आपका JS पढ़ सकता है (View Source, DevTools) |
| Database password | ❌ कभी नहीं | सिर्फ़ server पर |
| Payment PUBLIC/key-id (Razorpay key_id) | ✅ हाँ | Public होने के लिए बना; secret server पर |
| Google Maps browser key | ✅ Restrictions के साथ | Console में domain (HTTP referrer) से सीमित करें |
| Login session | HttpOnly cookie बेहतर | JS पढ़ नहीं सकता, तो XSS चुरा नहीं सकता |
| .env files | सिर्फ़ VITE_ prefix वाली values browser तक | इन्हें public मानें |
कई परतें: CSP, HTTPS और third-party scripts
Content-Security-Policy: default-src 'self'; script-src 'self' https://checkout.razorpay.com; img-src 'self' data: https:; style-src 'self' https://fonts.googleapis.com; font-src https://fonts.gstatic.com; connect-src 'self' https://codingeasily.in; frame-ancestors 'none' # Even if an attacker injects <script>, the browser refuses scripts not on the list.
- सब कुछ HTTPS पर; cookies Secure, HttpOnly और SameSite=Lax/Strict के साथ।
- हर third-party script (chat widgets, analytics, ad tags) आपका page पढ़ सकती है – सिर्फ़ भरोसेमंद जोड़ें, versions pin करें और CDN files के लिए Subresource Integrity (integrity="sha384-…") लें।
- npm packages updated रखें:
npm auditज्ञात कमज़ोरियाँ दिखाता है। - अविश्वसनीय sites के target="_blank" links पर rel="noopener noreferrer"।
Clean code: अगले developer के लिए लिखें
पहले
- function calc(a, b, c) { if (c) { return a*b - a*b*0.1 + (a*b > 1500 ? 0 : 60) } else { return a*b + (a*b>1500?0:60) } }
- Magic numbers 0.1, 1500, 60
- नाम कुछ नहीं बताता
- दोहराया logic
बाद में
- const COUPON_RATE = 0.10, FREE_DELIVERY_FROM = 1500, DELIVERY_FEE = 60;
- const subtotal = price * qty;
- const discounted = hasCoupon ? subtotal * (1 - COUPON_RATE) : subtotal;
- return discounted + (discounted >= FREE_DELIVERY_FROM ? 0 : DELIVERY_FEE);
| आदत | उदाहरण |
|---|---|
| नाम इरादा बताएँ | isDeliveryFree, getProductsByCategory, MAX_CART_ITEMS |
| Functions एक काम करें | validateOrder(), calculateTotal(), renderCart() – doEverything() नहीं |
| Early returns / guard clauses | if (!cart.length) return showEmpty(); |
| Magic numbers नहीं | const GST_RATE = 0.05 |
| Comments “क्यों” बताएँ, “क्या” नहीं | // Courier milk sweets नहीं लेता – रास्ते में ख़राब होती हैं |
| एक जैसी शैली | Save पर Prettier + ESLint (Day 21) |
| साफ़ messages वाले छोटे commits | “Fix: delivery fee shown on free orders” |
🏅 आज के Job Skills
Practice tasks
🏋️ Practice – ख़ुद करें
list.innerHTML += `<li>${comment.author}: ${comment.text}</li>`।Solution देखें
Quick quiz
🧠 Quick Quiz – ख़ुद को जाँचें
Interview corner
💼 Interview Corner
XSS क्या है और कैसे रोकें?
Cross-site scripting: attacker का data HTML/JS के रूप में render होकर दूसरे users के browsers में चलता है। Data को text मानें (textContent, framework escaping), HTML/attribute/URL contexts में escape करें, rich HTML sanitise करें (DOMPurify), URLs validate करें, eval से बचें, CSP और HttpOnly cookies लें।
Business नियम सिर्फ़ front end में क्यों न हों?
Client पूरी तरह user के नियंत्रण में है – code, requests और storage बदले जा सकते हैं। Prices, discounts, stock, permissions और payments server पर लागू हों; front end तेज़, दोस्ताना अनुभव के लिए सिर्फ़ उनकी नक़ल करता है।
सारांश
- User data textContent या escaping से render; rich HTML sanitise।
- Client पर भरोसा नहीं: prices, stock, permissions server पर।
- Front-end code में secrets नहीं; HTTPS, CSP, HttpOnly cookies, सावधान third parties।
- Clean code: साफ़ नाम, छोटे functions, constants, क्यों-comments, एक जैसी शैली।
Day 27: testing और interview तैयारी – automated tests लिखें और सबसे ज़्यादा पूछे JavaScript सवालों का अभ्यास करें।
