flawopen.com/SQL Injection/Numeric ID
Numeric ID के लिए भी string formatting खतरनाक क्यों है?
जोखिम value के वास्तविक अर्थ से नहीं, बल्कि query को text जोड़कर बनाने से आता है। “यह हमेशा number है” डेटा के बारे में धारणा है, code द्वारा लागू की गई गारंटी नहीं।
धारणा कहाँ टूटती है
URL query parameter या form field नेटवर्क पर text होता है, चाहे database column किसी भी type की अपेक्षा करे। स्पष्ट type validation के बिना framework code तक पहुँचने से पहले id=1 OR 1=1 जैसे input को रोकता नहीं है।
आज सुरक्षित code, क्योंकि ID हमेशा भरोसेमंद internal source से आती है, तब असुरक्षित हो सकता है जब नया caller उसी function को user-supplied value दे। vulnerability पहले से छिपी थी और बदलाव की प्रतीक्षा कर रही थी।
खासकर 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 से चुनें।
const rawId = new URL(request.url).searchParams.get("id");
const result = await pool.query(
`SELECT id FROM users WHERE id = ${rawId}`
);
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)
);
संदर्भ
- flawopen.com — SQL Injection (सभी भाषाएँ)
- पैरामीटराइज़्ड क्वेरी क्या है?
- node-postgres — Parameterized query API