FlawOpen

flawopen.com/SQL Injection/Numeric ID

Numeric ID के लिए भी string formatting खतरनाक क्यों है?

संदर्भ पृष्ठ
संक्षिप्त उत्तर

जोखिम value के वास्तविक अर्थ से नहीं, बल्कि query को text जोड़कर बनाने से आता है। “यह हमेशा number है” डेटा के बारे में धारणा है, code द्वारा लागू की गई गारंटी नहीं।

धारणा कहाँ टूटती है

HTTP parameters हमेशा string के रूप में आते हैं

URL query parameter या form field नेटवर्क पर text होता है, चाहे database column किसी भी type की अपेक्षा करे। स्पष्ट type validation के बिना framework code तक पहुँचने से पहले id=1 OR 1=1 जैसे input को रोकता नहीं है।

भविष्य का refactor value का स्रोत चुपचाप बदल सकता है

आज सुरक्षित code, क्योंकि ID हमेशा भरोसेमंद internal source से आती है, तब असुरक्षित हो सकता है जब नया caller उसी function को user-supplied value दे। vulnerability पहले से छिपी थी और बदलाव की प्रतीक्षा कर रही थी।

Type coercion असली value छिपा सकता है

खासकर dynamically typed भाषाओं में logs में numeric दिखने वाली value अतिरिक्त characters वाली string हो सकती है। स्पष्ट validation के बिना अपेक्षित और वास्तविक type का मेल निश्चित नहीं है।

Type validation के बाद भी query को parameterize करें

ID को ऐप के अपेक्षित format के अनुसार validate करें, फिर उसे database driver के parameter API से भेजें। Validation input contract की रक्षा करता है; parameterization input को SQL syntax के रूप में interpret होने से रोकती है। Protocol पर driver का व्यवहार अलग हो सकता है, इसलिए यह न मानें कि हर driver values को समान तरीके से भेजता है। PostgreSQL parameters table या column identifiers नहीं दर्शा सकते; dynamic query structure को ऐप की fixed allowlist से चुनें।

संख्यात्मक मान को bind करें और उसका अर्थ जाँचें

यदि ऐप को यही प्रकार चाहिए, तो ID को धनात्मक सुरक्षित पूर्णांक के रूप में validate करें, फिर भी उसे query value के रूप में bind करें। Validation ऐप के input contract की रक्षा करता है; parameterization input को SQL syntax बनने से रोकती है। PostgreSQL parameters table या column identifiers की जगह नहीं ले सकते, इसलिए dynamic query structure को ऐप की fixed allowlist से चुनें।

असुरक्षित — ID को SQL में interpolate करना
const rawId = new URL(request.url).searchParams.get("id");
const result = await pool.query(
  `SELECT id FROM users WHERE id = ${rawId}`
);
सुरक्षित — ID validate करके value के रूप में bind करना
const rawId = new URL(request.url).searchParams.get("id");
if (rawId === null || !/^[0-9]+$/.test(rawId)) {
  return new Response("Invalid id", { status: 400 });
}
const id = Number(rawId);
if (!Number.isSafeInteger(id) || id < 1) {
  return new Response("Invalid id", { status: 400 });
}
const result = await pool.query(
  "SELECT id FROM users WHERE id = $1",
  Array.of(id)
);

संदर्भ

यह भी देखें SQL इंजेक्शन (CWE-89): यह कैसे काम करता है और हर भाषा में इसे कैसे रोकें — flawopen.com पैरामीटराइज़्ड क्वेरी क्या है? क्या Prisma $queryRaw SQL Injection से सुरक्षित है? क्या Rails where() में string interpolation सुरक्षित है? क्या Sequelize query() SQL Injection से सुरक्षित है? क्या SQLAlchemy text() SQL Injection से सुरक्षित है? क्या sqlx की compile-time query जाँच SQL injection रोकती है?