Thuta Learning
How Databases Work
AdvancedData & Databasesbeginner

SQL Injection နှင့် Parameterized Query

ဒီခန်းပြီးရင် ဘာတတ်သွားမလဲ

  • SQL Injection နှင့် Parameterized Query concept ကို နားလည်ရှင်းပြနိုင်ရန်
  • Diagram/table ကို ဖတ်ပြီး data model/schema/architecture ဘယ်လို ပုံသဏ္ဌာန်ရှိသလဲ ခြေရာခံနိုင်ရန်
  • ကိုယ့် project အတွက် database concept/system ကို ဘယ်လို အသုံးချသင့်သလဲ ရှင်းပြနိုင်ရန်

နားလည်ထားရမယ့် အချက်

SQL injection ဖြစ်ရတာက application တစ်ခုက untrusted input ကို query string ထဲ တိုက်ရိုက် ပေါင်းစပ်ပြီး SQL query တည်ဆောက်တဲ့အခါပါ။ User ရိုက်ထည့်တဲ့ data နဲ့ developer ရေးထားတဲ့ SQL syntax ကို database က ခွဲခြားမသိတော့ပါဘူး။

Untrusted input ကို concatenate လုပ်ပြီး SQL မတည်ဆောက်ပါနှင့်

ဒါကို ရိုးရှင်းစွာ ဖော်ပြထားတာက application တွေ compromise ဖြစ်ရတဲ့ အဖြစ်များဆုံး နည်းလမ်းတစ်ခုဖြစ်လို့ပါ။ "...WHERE email = '" + userInput + "'" လို string တစ်ခုကို မြင်တာနဲ့ input ကို နောက်ပိုင်းဘယ်လို validate လုပ်ထားပါစေ bug တစ်ခုအဖြစ် သဘောထားပါ — အဖြေက ပိုသေချာအောင် sanitize လုပ်တာမဟုတ်ဘဲ concatenate လုပ်တာကို ရပ်ဖို့ပါ။

Parameterized query က SQL structure နဲ့ input value ကို channel သီးသန့်နှစ်ခုကနေ ပို့ပါတယ်။ Template ကို ကြိုတင် fix ထားပြီး value ကို နောက်မှ data အနေနဲ့သာ bind လုပ်ပါတယ် — query structure ရဲ့ တစ်စိတ်တစ်ပိုင်းအဖြစ် လုံးဝ မဟုတ်ပါဘူး။

Driver နဲ့ ORM အများစုက parameterized query ကို default, safe input လက်ခံနည်းအဖြစ် support လုပ်ပါတယ်။ ဒီ site ရဲ့ SQL နဲ့ PostgreSQL tutorial တွေမှာ language-specific syntax အတိအကျ ပြထားပါတယ်။

text
UNSAFE VS SAFE QUERY CONSTRUCTION
---------------------------------
UNSAFE: string concatenation
  userInput ------------------+
                               v
  "SELECT * FROM users WHERE email = '" + userInput + "'"
                               |
                               v
                  one blended string of SQL text
                  (input can change the SQL structure)

SAFE: parameterized query
  SQL template:  "SELECT * FROM users WHERE email = $1"
                               |
                               v
                     locked in before input arrives
  userInput ------------------+
                               v
                     bound separately, as pure data
                  (input can never change the structure)

လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်

SQL injection ကို ကာကွယ်ဖို့ဆိုတာ ကျွမ်းကျင်မှုထက် အလေ့အထ ကိစ္စပိုများပါတယ်။ User input က query ကို ရောက်ရှိတဲ့နေရာတိုင်း code ရေးလိုင်းပထမဆုံးကနေတည်း parameterized-query API ကို သုံးသင့်ပါတယ်။

ORM တွေက ဒါကို almost automatic ဖြစ်စေပါတယ်။ Project က raw SQL ဆီ ဆင်းပြီး string concatenation ကို ရင်းနှီးမှုကြောင့် သုံးမိတဲ့အခါ risk ပြန်ပေါ်လာပါတယ် — ဒါက ရပ်တန့်စဉ်းစားထိုက်တဲ့ အချိန်အတိအကျပါ။

အောက်က code က နှစ်ဖက်စလုံးကို ကာကွယ်ရေးရှုထောင့်ကနေ ပြထားပါတယ်: အန္တရာယ်ရှိတဲ့ input ကို flag လုပ်တဲ့ pattern-detector နဲ့ content ဘာပါပါ ဘေးကင်းစွာ ကိုင်တွယ်တဲ့ simulated parameterized query။ Database အစစ်ပေါ်မှာ exploit မရှိပါ။

Untrusted input ကို concatenate လုပ်ပြီး SQL query မတည်ဆောက်ပါနှင့်

ဒါက သင့်ကိုယ်ပိုင် application ကို ကာကွယ်ပေးတာပါ။ User input က query structure ကို ပြန်ပုံဖော်နိုင်တာနဲ့ attacker တစ်ယောက်က app ရဲ့ logic ကိုယ်တိုင် ဖော်ပြရည်ရွယ်ထားတာထက် ပိုပြီး data ကို ဖတ်/ပြင်/ဖျက် နိုင်ပါတယ်။

အတူတူ စမ်းရေးကြည့်မယ်

javascript
// Defensive pattern-detector: flags characters/keywords that are dangerous
// ONLY if someone concatenates them directly into a raw SQL string.
function looksDangerousIfConcatenated(input) {
  const suspiciousPattern = /('|--|;|\bor\b|\bunion\b|\bdrop\b)/i;
  return suspiciousPattern.test(input);
}

// Simulated parameterized query: a real driver sends the SQL text and the
// parameter values as SEPARATE channels, so the value is always treated as
// plain data and can never change the query's structure.
function runParameterizedQuery(sqlTemplate, params) {
  return { sql: sqlTemplate, boundParams: params, executedAsData: true };
}

const suspiciousInput = "' OR '1'='1";
const normalInput = "alice@example.com";

console.log("suspicious input flagged:", looksDangerousIfConcatenated(suspiciousInput));
console.log("normal input flagged:", looksDangerousIfConcatenated(normalInput));

console.log(runParameterizedQuery("SELECT * FROM users WHERE email = $1", [suspiciousInput]));
console.log(runParameterizedQuery("SELECT * FROM users WHERE email = $1", [normalInput]));
You should see
Detector က suspicious input "' OR '1'='1" ကို true၊ normal input "alice@example.com" ကို false လို့ flag လုပ်ပါတယ်။ နှစ်ခုစလုံး simulated parameterized query ကို ဖြတ်တဲ့အခါ { sql: "SELECT * FROM users WHERE email = $1", boundParams: [input], executedAsData: true } ကို နှစ်ခုလုံးအတွက် အတူတူ ပြန်ပေးပါတယ် — safe path က flag လုပ်ခံရတဲ့ input ထဲမှာ ဘာပါပါ တစ်ပုံစံတည်း ကိုင်တွယ်ပါတယ်။

၅ မိနစ် စမ်းကြည့်

Test input တတိယခု "O'Brien" (apostrophe ပါတဲ့ တကယ့် surname) ကို ထည့်ပြီး code ကို run ကြည့်ပါ။ Detector က flag လုပ်ပါသလား။ Detector ရဲ့ pattern-matching မပြည့်စုံပေမယ့် parameterized query က ဒါကို ဘာကြောင့် မှန်ကန်စွာ ကိုင်တွယ်နိုင်ဆဲလဲ ရှင်းပြပါ။

သတိလေးတစ်ချက်

Parameterized query ကို ပြောင်းသုံးမည့်အစား input sanitization (သို့) escaping ကို အဓိက ကာကွယ်ရေးအဖြစ် မှီခိုနေခြင်း — parameterized query ကမူ bug category တစ်ခုလုံးကို construction အားဖြင့် ဖယ်ရှားပေးပါတယ်။

ORM က query တိုင်းကို အလိုအလျောက် ကာကွယ်ပေးမယ်လို့ ယူဆပြီး ရှုပ်ထွေးတဲ့ query တစ်ခုအတွက် 'တစ်ခါတည်း' ဆိုပြီး raw, concatenated SQL ဆီ ဆင်းသွားခြင်းပါ။

OWASP: SQL Injection Prevention Cheat SheetHow Databases Work

ဒီနေရာမှာ လူအများမှားတတ်တယ်

  • Parameterized query ကို ပြောင်းသုံးမည့်အစား input sanitization (သို့) escaping ကို အဓိက ကာကွယ်ရေးအဖြစ် မှီခိုနေခြင်း — parameterized query ကမူ bug category တစ်ခုလုံးကို construction အားဖြင့် ဖယ်ရှားပေးပါတယ်။
  • ORM က query တိုင်းကို အလိုအလျောက် ကာကွယ်ပေးမယ်လို့ ယူဆပြီး ရှုပ်ထွေးတဲ့ query တစ်ခုအတွက် 'တစ်ခါတည်း' ဆိုပြီး raw, concatenated SQL ဆီ ဆင်းသွားခြင်းပါ။
  • ဒီ course က database concept/landscape ကို framework-neutral level မှာသာ သင်ပေးပါတယ် — SQL syntax, PostgreSQL, MongoDB, Redis ကို နက်နက်ရှိုင်းရှိုင်း လေ့လာချင်ရင် SQL, PostgreSQL, MongoDB, Redis tutorial တွေဆီ ဆက်သွားပါ။

လေ့ကျင့်ခန်း

Test input တတိယခု "O'Brien" (apostrophe ပါတဲ့ တကယ့် surname) ကို ထည့်ပြီး code ကို run ကြည့်ပါ။ Detector က flag လုပ်ပါသလား။ Detector ရဲ့ pattern-matching မပြည့်စုံပေမယ့် parameterized query က ဒါကို ဘာကြောင့် မှန်ကန်စွာ ကိုင်တွယ်နိုင်ဆဲလဲ ရှင်းပြပါ။

You'll know it worked when: Detector က suspicious input "' OR '1'='1" ကို true၊ normal input "alice@example.com" ကို false လို့ flag လုပ်ပါတယ်။ နှစ်ခုစလုံး simulated parameterized query ကို ဖြတ်တဲ့အခါ { sql: "SELECT * FROM users WHERE email = $1", boundParams: [input], executedAsData: true } ကို နှစ်ခုလုံးအတွက် အတူတူ ပြန်ပေးပါတယ် — safe path က flag လုပ်ခံရတဲ့ input ထဲမှာ ဘာပါပါ တစ်ပုံစံတည်း ကိုင်တွယ်ပါတယ်။

SQL Injection နှင့် Parameterized Query | Thuta Learning