Skip to content

মার্কডাউন নিরাপত্তা সেরা অনুশীলন

মার্কডাউন কন্টেন্ট পরিচালনা করার সময় নিরাপত্তা অত্যন্ত গুরুত্বপূর্ণ, বিশেষ করে ব্যবহারকারী-তৈরি কন্টেন্টের ক্ষেত্রে। এই গাইডটি সাধারণ দুর্বলতা এবং সুরক্ষা কৌশল কভার করে।

সাধারণ নিরাপত্তা ঝুঁকি

ক্রস-সাইট স্ক্রিপ্টিং (XSS)

HTML অনুমোদনকারী মার্কডাউন ক্ষতিগ্রস্ত হতে পারে:

markdown
<!-- ক্ষতিকারক ইনপুট -->
<script>alert('XSS')</script>
<img src=x onerror="alert('XSS')">
<iframe src="javascript:alert('XSS')"></iframe>

ইনজেকশন আক্রমণ

markdown
<!-- লিঙ্ক ইনজেকশন -->
[এখানে ক্লিক করুন](javascript:alert('XSS'))
[ক্ষতিকারক](data:text/html,<script>alert('XSS')</script>)

<!-- ইমেজ ইনজেকশন -->
![](javascript:alert('XSS'))

স্যানিটাইজেশন

HTML স্যানিটাইজেশন

javascript
const DOMPurify = require('isomorphic-dompurify');

function renderSafe(markdown) {
  const html = md.render(markdown);
  return DOMPurify.sanitize(html, {
    ALLOWED_TAGS: ['p', 'b', 'i', 'em', 'strong', 'a', 'ul', 'ol', 'li'],
    ALLOWED_ATTR: ['href', 'title']
  });
}

মার্কডাউন পার্সার কনফিগার করুন

javascript
const md = require('markdown-it')({
  html: false,       // সোর্সে HTML ট্যাগ নিষ্ক্রিয় করুন
  linkify: true,     // URL স্বয়ংক্রিয় রূপান্তর
  typographer: true
});

// বিপজ্জনক প্রোটোকল নিষ্ক্রিয় করুন
md.validateLink = function (url) {
  const allowedProtocols = /^(https?|ftp|mailto):/i;
  return allowedProtocols.test(url);
};

কন্টেন্ট সিকিউরিটি পলিসি (CSP)

বেসিক CSP হেডার

html
<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; 
               script-src 'self' 'unsafe-inline'; 
               style-src 'self' 'unsafe-inline'; 
               img-src 'self' data: https:;">

স্ট্রিক্ট CSP

javascript
app.use((req, res, next) => {
  res.setHeader('Content-Security-Policy', [
    "default-src 'self'",
    "script-src 'self'",
    "style-src 'self'",
    "img-src 'self' https:",
    "font-src 'self'",
    "connect-src 'self'",
    "frame-ancestors 'none'"
  ].join('; '));
  next();
});

ইনপুট ভ্যালিডেশন

দৈর্ঘ্য সীমা

javascript
function validateMarkdown(content) {
  const MAX_LENGTH = 50000;
  
  if (content.length > MAX_LENGTH) {
    throw new Error('কন্টেন্ট খুব দীর্ঘ');
  }
  
  return content;
}

কন্টেন্ট ফিল্টারিং

javascript
function filterMarkdown(content) {
  // সম্ভাব্য বিপজ্জনক প্যাটার্ন সরান
  return content
    .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
    .replace(/javascript:/gi, '')
    .replace(/on\w+\s*=/gi, '');
}

ব্যবহারকারী-তৈরি কন্টেন্ট

হোয়াইটলিস্ট অ্যাপ্রোচ

javascript
const allowedTags = {
  p: [],
  strong: [],
  em: [],
  a: ['href', 'title'],
  ul: [],
  ol: [],
  li: [],
  h1: [],
  h2: [],
  h3: [],
  code: [],
  pre: []
};

function sanitizeUserContent(html) {
  return DOMPurify.sanitize(html, {
    ALLOWED_TAGS: Object.keys(allowedTags),
    ALLOWED_ATTR: Object.values(allowedTags).flat()
  });
}

রেট লিমিটিং

javascript
const rateLimit = require('express-rate-limit');

const markdownLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 মিনিট
  max: 100, // প্রতি windowMs এ প্রতি IP তে 100 রিকোয়েস্ট
  message: 'অত্যধিক সাবমিশন, অনুগ্রহ করে পরে আবার চেষ্টা করুন।'
});

app.post('/api/markdown', markdownLimiter, (req, res) => {
  // মার্কডাউন সাবমিশন হ্যান্ডেল করুন
});

ফাইল আপলোড নিরাপত্তা

ভ্যালিডেশন

javascript
const allowedExtensions = ['.md', '.markdown', '.txt'];
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB

function validateFile(file) {
  const ext = path.extname(file.name).toLowerCase();
  
  if (!allowedExtensions.includes(ext)) {
    throw new Error('অবৈধ ফাইল টাইপ');
  }
  
  if (file.size > MAX_FILE_SIZE) {
    throw new Error('ফাইল খুব বড়');
  }
  
  return true;
}

ভাইরাস স্ক্যানিং

javascript
const ClamScan = require('clamscan');

async function scanFile(filePath) {
  const clamscan = await new ClamScan().init();
  const { isInfected, viruses } = await clamscan.isInfected(filePath);
  
  if (isInfected) {
    throw new Error(`ভাইরাস সনাক্ত হয়েছে: ${viruses.join(', ')}`);
  }
  
  return true;
}

প্রমাণীকরণ এবং অনুমোদন

অ্যাক্সেস কন্ট্রোল

javascript
function checkPermissions(user, action) {
  const permissions = {
    admin: ['read', 'write', 'delete'],
    editor: ['read', 'write'],
    viewer: ['read']
  };
  
  return permissions[user.role]?.includes(action);
}

app.post('/api/markdown', (req, res) => {
  if (!checkPermissions(req.user, 'write')) {
    return res.status(403).json({ error: 'নিষিদ্ধ' });
  }
  // মার্কডাউন প্রসেস করুন
});

CSRF সুরক্ষা

javascript
const csrf = require('csurf');
const csrfProtection = csrf({ cookie: true });

app.post('/api/markdown', csrfProtection, (req, res) => {
  // সুরক্ষিত এন্ডপয়েন্ট
});

সুরক্ষিত স্টোরেজ

এনক্রিপশন

javascript
const crypto = require('crypto');

function encryptContent(content, key) {
  const iv = crypto.randomBytes(16);
  const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
  let encrypted = cipher.update(content, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  return { encrypted, iv: iv.toString('hex') };
}

function decryptContent(encrypted, iv, key) {
  const decipher = crypto.createDecipheriv('aes-256-cbc', key, Buffer.from(iv, 'hex'));
  let decrypted = decipher.update(encrypted, 'hex', 'utf8');
  decrypted += decipher.final('utf8');
  return decrypted;
}

SQL ইনজেকশন প্রতিরোধ

javascript
// প্যারামিটারাইজড কোয়েরি ব্যবহার করুন
const query = 'INSERT INTO posts (title, content) VALUES (?, ?)';
db.execute(query, [title, content]);

// কখনই ব্যবহারকারীর ইনপুট কনক্যাটেনেট করবেন না
// ❌ const query = `INSERT INTO posts VALUES ('${userInput}')`;

API নিরাপত্তা

API রেট লিমিটিং

javascript
const slowDown = require('express-slow-down');

const speedLimiter = slowDown({
  windowMs: 15 * 60 * 1000,
  delayAfter: 100,
  delayMs: 500
});

app.use('/api/', speedLimiter);

API কী ভ্যালিডেশন

javascript
function validateApiKey(req, res, next) {
  const apiKey = req.headers['x-api-key'];
  
  if (!apiKey || !isValidApiKey(apiKey)) {
    return res.status(401).json({ error: 'অবৈধ API কী' });
  }
  
  next();
}

সুরক্ষিত মার্কডাউন পার্সিং

সেফ পার্সার কনফিগারেশন

javascript
const md = require('markdown-it')({
  html: false,          // HTML নিষ্ক্রিয় করুন
  xhtmlOut: true,       // XHTML আউটপুট ব্যবহার করুন
  breaks: false,        // \n কে <br> তে রূপান্তর করবেন না
  linkify: true,        // URL স্বয়ংক্রিয় রূপান্তর
  typographer: false    // সামঞ্জস্যের জন্য স্মার্ট কোট নিষ্ক্রিয় করুন
});

// কাস্টম লিঙ্ক ভ্যালিডেশন
md.validateLink = (url) => {
  const safe = /^(https?|mailto):/i.test(url);
  return safe;
};

// রেন্ডার ফাংশন
md.renderer.rules.link_open = (tokens, idx, options, env, self) => {
  const token = tokens[idx];
  const hrefIndex = token.attrIndex('href');
  
  if (hrefIndex >= 0) {
    const url = token.attrs[hrefIndex][1];
    
    // নিরাপত্তা অ্যাট্রিবিউট যোগ করুন
    token.attrPush(['rel', 'noopener noreferrer']);
    
    // বাহ্যিক লিঙ্কের জন্য target="_blank" যোগ করুন
    if (/^https?:/.test(url)) {
      token.attrPush(['target', '_blank']);
    }
  }
  
  return self.renderToken(tokens, idx, options);
};

নিরাপত্তা হেডার

ব্যাপক নিরাপত্তা হেডার

javascript
const helmet = require('helmet');

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      styleSrc: ["'self'", "'unsafe-inline'"],
      scriptSrc: ["'self'"],
      imgSrc: ["'self'", "data:", "https:"],
    }
  },
  hsts: {
    maxAge: 31536000,
    includeSubDomains: true,
    preload: true
  },
  frameguard: {
    action: 'deny'
  },
  noSniff: true,
  xssFilter: true
}));

নিরাপত্তা চেকলিস্ট

markdown
## মার্কডাউন নিরাপত্তা চেকলিস্ট

- [ ] মার্কডাউন পার্সারে HTML নিষ্ক্রিয় করুন
- [ ] সমস্ত HTML আউটপুট স্যানিটাইজ করুন
- [ ] URL ভ্যালিডেট এবং হোয়াইটলিস্ট করুন
- [ ] কন্টেন্ট সিকিউরিটি পলিসি বাস্তবায়ন করুন
- [ ] প্যারামিটারাইজড কোয়েরি ব্যবহার করুন
- [ ] ফাইল আপলোড ভ্যালিডেট করুন
- [ ] ফাইল সাইজ লিমিট সেট করুন
- [ ] রেট লিমিটিং বাস্তবায়ন করুন
- [ ] CSRF সুরক্ষা ব্যবহার করুন
- [ ] সংবেদনশীল কন্টেন্ট এনক্রিপ্ট করুন
- [ ] API কী ভ্যালিডেট করুন
- [ ] সুরক্ষিত হেডার সেট করুন
- [ ] নিরাপত্তা ইভেন্ট লগ করুন
- [ ] নিয়মিত নিরাপত্তা অডিট
- [ ] ডিপেন্ডেন্সি আপডেট রাখুন

মনিটরিং এবং লগিং

নিরাপত্তা ইভেন্ট লগিং

javascript
const winston = require('winston');

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.File({ filename: 'security.log' })
  ]
});

function logSecurityEvent(event, details) {
  logger.warn({
    timestamp: new Date().toISOString(),
    event,
    details,
    ip: details.ip,
    user: details.user
  });
}

উপসংহার

নিরাপত্তা একটি চলমান প্রক্রিয়া। নিয়মিত আপনার নিরাপত্তা ব্যবস্থা পর্যালোচনা এবং আপডেট করুন, ডিপেন্ডেন্সি আপডেট রাখুন এবং নতুন দুর্বলতা সম্পর্কে অবগত থাকুন।

অতিরিক্ত রিসোর্স

www.markdownlang.com দ্বারা নির্মিত