Node.js ও Express-এ XSS আক্রমণের প্রতিরোধের উপায়

Node.js ও Express অ্যাপ্লিকেশনে Helmet মিডলওয়্যার, কড়া Content Security Policy এবং DOMPurify স্যানিটাইজার দিয়ে XSS প্রতিরোধের গাইড।

Node.js ও Express এইচটিটিপি রেসপন্স স্ট্রিম এবং সিএসপি ফিল্টার নির্দেশক বিমূর্ত গ্রাফিক

Node.js এবং Express ব্যাকএন্ডে ডেভেলপাররা প্রায়ই EJS, Pug কিংবা Handlebars টেমপ্লেট ইঞ্জিনের মাধ্যমে সার্ভার-রেন্ডারড এইচটিএমএল তৈরি করেন অথবা সিঙ্গেল-পেজ অ্যাপের জন্য এপিআই সার্ভ করেন। যথাযথ স্যানিটাইজেশন এবং রেসপন্স হেডার কনফিগার না থাকলে অ্যাপ্লিকেশনটি মারাত্মক ক্রস-সাইট স্ক্রিপ্টিং (Cross-Site Scripting বা XSS) আক্রমণের শিকার হতে পারে।

আক্রমণের মূল ধারণা ও ধরণ বিশদ জানতে আমাদের ক্রস-সাইট স্ক্রিপ্টিং (XSS) পরিচিতি ও প্রতিরোধ নির্দেশিকা পড়ে নিতে পারেন। এছাড়া ডাটাবেস সিকিউরিটির জন্য Node.js ও Express-এ এসকিউএল ইনজেকশন প্রতিরোধ গাইড দেখতে পারেন।

এই টিউটোরিয়ালে Helmet মিডলওয়্যার, ননস-ভিত্তিক কড়া Content Security Policy (CSP), নিরাপদ টেমপ্লেট রেন্ডারিং এবং DOMPurify ব্যবহারের মাধ্যমে Express-এ পূর্ণাঙ্গ নিরাপত্তা কাঠামো গড়ে তোলার উপায় আলোচনা করা হয়েছে।

Helmet মিডলওয়্যার দিয়ে এইচটিটিপি হেডার সুরক্ষিত রাখা

Express অ্যাপ্লিকেশনে নিরাপত্তা নিশ্চিত করার প্রথম পদক্ষেপ হলো Helmet ব্যবহার করা, যা স্বয়ংক্রিয়ভাবে ব্রাউজারের জন্য প্রয়োজনীয় সিকিউরিটি হেডার সেট করে:

// নিরাপদ: ডাইনামিক ননসসহ Helmet ও CSP কনফিগারেশন
import express from 'express';
import helmet from 'helmet';
import crypto from 'node:crypto';

const app = express();

// প্রতি রিকোয়েস্টে ক্রিপ্টোগ্রাফিক ননস জেনারেট করা
app.use((req, res, next) => {
  res.locals.cspNonce = crypto.randomBytes(16).toString('base64');
  next();
});

// Helmet-এর মাধ্যমে কড়া CSP পলিসি প্রয়োগ
app.use((req, res, next) => {
  helmet({
    contentSecurityPolicy: {
      directives: {
        defaultSrc: ["'self'"],
        scriptSrc: ["'self'", `'nonce-${res.locals.cspNonce}'`],
        styleSrc: ["'self'", "'unsafe-inline'"],
        imgSrc: ["'self'", "data:", "https://images.unsplash.com"],
        connectSrc: ["'self'"],
        fontSrc: ["'self'"],
        objectSrc: ["'none'"],
        baseUri: ["'self'"],
        formAction: ["'self'"],
        frameAncestors: ["'none'"] // ক্লিকজ্যাকিং প্রতিরোধ করে
      }
    },
    crossOriginEmbedderPolicy: false
  })(req, res, next);
});

এই কনফিগারেশনের ফলে:

  • আক্রমণকারীর ইনজেক্ট করা ক্ষতিকর স্ক্রিপ্টে সার্ভারের সিক্রেট ননস না থাকায় ব্রাউজার তা এক্সিকিউট করতে অস্বীকৃতি জানায়।
  • অননুমোদিত থার্ড-পার্টি ডোমেইন থেকে স্ক্রিপ্ট লোড হওয়া স্বয়ংক্রিয়ভাবে বন্ধ থাকে।

অন্যান্য সিকিউরিটি হেডার ব্যবস্থাপনার জন্য আমাদের CORS কনফিগারেশন গাইড দেখতে পারেন।

নিরাপদ সার্ভার-সাইড টেমপ্লেট রেন্ডারিং

Express-এ টেমপ্লেট ইঞ্জিন ব্যবহারের সময় অটোমেটিক এস্কেপিং সিনট্যাক্স ব্যবহার করতে হবে এবং আন-এস্কেপড ট্যাগ পরিহার করতে হবে:

টেমপ্লেট ইঞ্জিন নিরাপদ অটো-এস্কেপড সিনট্যাক্স ঝুঁকিপূর্ণ র সিনট্যাক্স (পরিহার করুন)
EJS <%= userInput %> <%- userInput %>
Handlebars {{ userInput }} {{{ userInput }}}
Pug p= userInput বা #{userInput} p!= userInput বা !{userInput}
// ঝুঁকিপূর্ণ: EJS-এ সরাসরি এইচটিএমএল আউটপুট
// profile.ejs ফাইলে: <div class="bio"><%- user.bio %></div> <!-- Stored XSS-এর ঝুঁকি -->

// নিরাপদ: অটো-এস্কেপড ট্যাগ ব্যবহার
// profile.ejs ফাইলে: <div class="bio"><%= user.bio %></div>

সার্ভারে DOMPurify দিয়ে রিচ টেক্সট স্যানিটাইজেশন

ব্যবহারকারী যদি কমেন্ট বা আর্টিকেলে মার্কডাউন বা ফরম্যাটেড এইচটিএমএল জমা দেওয়ার সুযোগ পান, তবে ডাটাবেসে সেভ বা রেন্ডার করার আগে তা স্যানিটাইজ করা আবশ্যক।

Node.js সার্ভারে jsdom এবং DOMPurify ব্যবহার করে নিরাপদ স্যানিটাইজার তৈরির উপায়:

// নিরাপদ: DOMPurify দিয়ে সার্ভার-সাইড স্যানিটাইজেশন
import { JSDOM } from 'jsdom';
import DOMPurify from 'dompurify';
import { marked } from 'marked';

const window = new JSDOM('').window;
const purify = DOMPurify(window);

export function renderUserContent(rawMarkdown) {
  // ১. মার্কডাউন থেকে এইচটিএমএল রূপান্তর
  const rawHtml = marked.parse(rawMarkdown);
  
  // ২. DOMPurify-এর মাধ্যমে নির্দিষ্ট হোয়াইটলিস্ট অনুযায়ী স্যানিটাইজ করা
  const cleanHtml = purify.sanitize(rawHtml, {
    ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p', 'ul', 'ol', 'li', 'code', 'pre', 'blockquote'],
    ALLOWED_ATTR: ['href', 'title', 'target', 'rel']
  });
  
  return cleanHtml;
}

DOMPurify স্বয়ংক্রিয়ভাবে ক্ষতিকর ট্যাগ (<script>, <iframe>) এবং ইভেন্ট হ্যান্ডলার (onload, onerror) মুছে ফেলে।

কুকি চুরি রোধে ফ্ল্যাগ কনফিগারেশন

যদি কোনোভাবে ক্লায়েন্টে স্ক্রিপ্ট ইনজেক্ট হয়েও যায়, তবে কুকিতে HttpOnly ফ্ল্যাগ থাকলে সেশন হাইজ্যাক করা অসম্ভব হয়ে ওঠে:

// নিরাপদ: express-session-এ কুকি সিকিউরিটি ফ্ল্যাগ
import session from 'express-session';

app.use(session({
  name: '__Secure-sess',
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  cookie: {
    httpOnly: true, // জাভাস্ক্রিপ্টে document.cookie রিড বন্ধ করে
    secure: process.env.NODE_ENV === 'production', // কেবল HTTPS-এ কাজ করবে
    sameSite: 'lax',
    maxAge: 1000 * 60 * 60 * 24 // ২৪ ঘণ্টা
  }
}));

সচরাচর যেসব ভুল পরিলক্ষিত হয়

সাধারণ ভুল ঝুঁকি সমাধান
সরাসরি res.send(userInput) ব্রাউজারে র এইচটিএমএল পার্স হয়ে স্ক্রিপ্ট রান হয় res.json() ব্যবহার করুন অথবা এনকোড করে পাঠান
JSON ডেটা এইচটিএমএলে সরাসরি এমবেড করা <script> ট্যাগের ভেতরে ব্রেক-আউট ইনজেকশন serialize-javascript লাইব্রেরি ব্যবহার করুন
কাস্টম রেজেক্স দিয়ে স্যানিটাইজেশন জটিল পে-লোডে ফিল্টার বাইপাস হয়ে যায় বিশ্বস্ত DOMPurify লাইব্রেরি ব্যবহার করুন
Helmet মিডলওয়্যার মিস করা ব্রাউজার কোনো সিকিউরিটি হেডার পায় না অ্যাপের শুরুতে app.use(helmet()) যুক্ত করুন

Express XSS প্রতিরোধ চেকলিস্ট

প্রোডাকশনে কোড তোলার আগে নিচের বিষয়গুলো মিলিয়ে নিন:

  • helmet মিডলওয়্যার কাস্টম Content Security Policy ও ননস সহ কার্যকর রয়েছে।
  • টেমপ্লেট ইঞ্জিনে সর্বত্র অটো-এস্কেপড সিনট্যাক্স ব্যবহৃত হয়েছে; র ট্যাগ নেই।
  • ব্যবহারকারীর সকল মার্কডাউন ও এইচটিএমএল ইনপুট DOMPurify দিয়ে স্যানিটাইজ করা।
  • অথেনটিকেশন কুকিজে httpOnly: true, secure: true এবং sameSite ফ্ল্যাগ কনফিগার করা হয়েছে।
  • সার্ভার প্রি-লোডেড ডেটার ক্ষেত্রে সেফ সিরিয়ালাইজার ব্যবহার করা হয়েছে।

সারসংক্ষেপ

Node.js এবং Express অ্যাপ্লিকেশনে XSS আক্রমণ শতভাগ প্রতিরোধযোগ্য। Helmet-এর শক্তিশালী CSP হেডার, টেমপ্লেটের নিজস্ব আউটপুট এস্কেপিং, DOMPurify স্যানিটাইজার এবং HttpOnly কুকির সমন্বয়ে মাল্টি-লেয়ার ডিফেন্স তৈরি করলে আপনার ব্যবহারকারীরা সম্পূর্ণ নিরাপদ থাকবে।

তথ্যসূত্র: Express Security Best Practices Documentation, Helmet.js Content Security Policy Guide, DOMPurify Security Specifications, OWASP Top 10 (মূল্যায়ন নভেম্বর ২০২৬)।

আরও পড়ুন

ক্রস-সাইট স্ক্রিপ্টিং (XSS): কীভাবে কাজ করে ও প্রতিরোধের উপায়

ক্রস-সাইট স্ক্রিপ্টিং (XSS) দুর্বলতার আক্রমণ পদ্ধতি, Stored, Reflected ও DOM XSS এবং কনটেক্সট এনকোডিং ও CSP ব্যবহারের পূর্ণাঙ্গ গাইড।

নিরাপত্তা•৪ মিনিটে পড়া

Flask ও FastAPI-তে এসকিউএল ইনজেকশন প্রতিরোধের উপায়

Flask এবং FastAPI মাইক্রোসার্ভিসে SQLAlchemy 2.0, parameterized text() এবং Pydantic ভ্যালিডেশন দিয়ে এসকিউএল ইনজেকশন প্রতিরোধের গাইড।

নিরাপত্তা•৪ মিনিটে পড়া

Django-তে এসকিউএল ইনজেকশন প্রতিরোধের উপায়

Django ফ্রেমওয়ার্কে ORM, RawSQL এবং ডাটাবেস কার্সর ব্যবহারের মাধ্যমে এসকিউএল ইনজেকশন প্রতিরোধ ও কোডবেস সুরক্ষার ব্যবহারিক গাইড।

নিরাপত্তা•৪ মিনিটে পড়া