Skip to content

Markdown सुरक्षा सर्वोत्तम प्रथाएं

Markdown सामग्री को संभालते समय सुरक्षा महत्वपूर्ण है, विशेष रूप से उपयोगकर्ता-जनित सामग्री के साथ। यह गाइड सामान्य कमजोरियों और सुरक्षा रणनीतियों को कवर करती है।

सामान्य सुरक्षा जोखिम

क्रॉस-साइट स्क्रिप्टिंग (XSS)

HTML की अनुमति देने वाले Markdown का शोषण किया जा सकता है:

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']
  });
}

Markdown पार्सर कॉन्फ़िगर करें

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, // प्रत्येक IP को windowMs प्रति 100 अनुरोधों की सीमा
  message: 'बहुत अधिक सबमिशन, कृपया बाद में पुनः प्रयास करें।'
});

app.post('/api/markdown', markdownLimiter, (req, res) => {
  // markdown सबमिशन संभालें
});

फ़ाइल अपलोड सुरक्षा

सत्यापन

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: 'निषिद्ध' });
  }
  // markdown प्रोसेस करें
});

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();
}

सुरक्षित Markdown पार्सिंग

सुरक्षित पार्सर कॉन्फ़िगरेशन

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
## Markdown सुरक्षा चेकलिस्ट

- [ ] 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 द्वारा निर्मित