php - আমি কিভাবে পিএইচপি এসকিউএল ইনজেকশন প্রতিরোধ করতে পারেন?




mysql sql (19)

যদি ব্যবহারকারী ইনপুটটি কোনও SQL ক্যোয়ারিতে সংশোধন ছাড়াই সন্নিবেশ করা হয়, তবে অ্যাপ্লিকেশনটি নিম্নোক্ত উদাহরণের মতো এসকিউএল ইনজেকশনকে দুর্বল করে তোলে:

$unsafe_variable = $_POST['user_input']; 

mysql_query("INSERT INTO `table` (`column`) VALUES ('$unsafe_variable')");

যেহেতু ব্যবহারকারী value'); DROP TABLE table;-- কিছু ইনপুট করতে পারেন value'); DROP TABLE table;-- value'); DROP TABLE table;-- , এবং প্রশ্ন হয়ে যায়:

INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')

এই ঘটনার প্রতিরোধ করতে কি করা যেতে পারে?


গুরুত্বপূর্ণ

এসকিউএল ইনজেকশন প্রতিরোধের সর্বোত্তম উপায় হল পালানোর পরিবর্তে প্রস্তুত বিবৃতিগুলি ব্যবহার করা, যেমন গৃহীত উত্তরটি প্রদর্শন করে।

Aura.Sql এবং EasyDB যেমন লাইব্রেরি EasyDB যা ডেভেলপারদের প্রস্তুত বিবৃতিগুলি সহজে ব্যবহার করার অনুমতি দেয়। এসকিউএল ইনজেকশন রোধে প্রস্তুত বিবৃতিগুলি কেন ভাল তা সম্পর্কে আরো জানতে, ওয়ার্ডপ্রেস এ mysql_real_escape_string() বাইপাস এবং সম্প্রতি নির্দিষ্ট ইউনিকোড এসকিউএল ইনজেকশন দুর্বলতা পড়ুন

ইনজেকশন প্রতিরোধ - mysql_real_escape_string()

পিএইচপি এই আক্রমণ প্রতিরোধ করার জন্য একটি বিশেষভাবে তৈরি ফাংশন আছে। আপনাকে যা করতে হবে তা হল একটি ফাংশন, mysql_real_escape_string

mysql_real_escape_string একটি স্ট্রিং লাগে যা একটি মাইএসকিউএল ক্যোয়ারিতে ব্যবহৃত হবে এবং সমস্ত এসকিউএল ইনজেকশন প্রচেষ্টাগুলি নিরাপদে পালিয়ে গেলে একই স্ট্রিংটি ফেরত দেবে। মূলত, এটি সেই বিরক্তিকর উদ্ধৃতিগুলি (') প্রতিস্থাপন করবে যা একটি ব্যবহারকারী একটি মাইএসকিউএল-নিরাপদ বিকল্প, একটি পালানো উদ্ধৃতি দিয়ে প্রবেশ করতে পারে।'

দ্রষ্টব্য: আপনি এই ফাংশন ব্যবহার করতে ডাটাবেস সংযুক্ত করা আবশ্যক!

// MySQL সংযোগ করুন

$name_bad = "' OR 1'"; 

$name_bad = mysql_real_escape_string($name_bad);

$query_bad = "SELECT * FROM customers WHERE username = '$name_bad'";
echo "Escaped Bad Injection: <br />" . $query_bad . "<br />";


$name_evil = "'; DELETE FROM customers WHERE 1 or username = '"; 

$name_evil = mysql_real_escape_string($name_evil);

$query_evil = "SELECT * FROM customers WHERE username = '$name_evil'";
echo "Escaped Evil Injection: <br />" . $query_evil;

আপনি MySQL - SQL ইনজেকশন প্রতিরোধের আরও বিশদ জানতে পারেন।


নিরাপত্তা সতর্কতা : এই উত্তরটি নিরাপত্তা সর্বোত্তম অনুশীলনগুলির সাথে সঙ্গতিপূর্ণ নয়। এসকিউএলিং এসকিউএল ইনজেকশন প্রতিরোধ করতে অপর্যাপ্ত , পরিবর্তে প্রস্তুত বিবৃতি ব্যবহার করুন। আপনার নিজের ঝুঁকিতে নীচের রূপরেখা কৌশল ব্যবহার করুন। (এছাড়াও, mysql_real_escape_string() পিএইচপি 7 এ সরানো হয়েছিল।)

আপনি এই মত মৌলিক কিছু করতে পারে:

$safe_variable = mysql_real_escape_string($_POST["user-input"]);
mysql_query("INSERT INTO table (column) VALUES ('" . $safe_variable . "')");

এটি প্রত্যেক সমস্যার সমাধান করবে না, তবে এটি একটি খুব ভাল পদক্ষেপের পাথর। আমি পরিবর্তনশীল এর অস্তিত্ব, বিন্যাস (সংখ্যা, অক্ষর, ইত্যাদি) চেক হিসাবে সুস্পষ্ট আইটেম বাকি।


আপনি দেখতে পারেন, মানুষ আপনাকে সবচেয়ে প্রস্তুত বিবৃতি ব্যবহার সুপারিশ। এটি ভুল নয়, কিন্তু যখন আপনার ক্যোয়ারী প্রক্রিয়া প্রতি একবার কার্যকর হয়, তখন সামান্য পারফরম্যান্সের শাস্তি হবে।

আমি এই সমস্যার মুখোমুখি ছিলাম, কিন্তু আমার মনে হয় আমি খুব জটিল পদ্ধতিতে এটি সমাধান করেছি - হ্যাকাররা কোট ব্যবহার করে এড়াতে ব্যবহার করে। আমি এমুলেটেড প্রস্তুত বিবৃতি সঙ্গে এই ব্যবহৃত। আমি সম্ভাব্য এসকিউএল ইনজেকশন আক্রমণের সব ধরনের প্রতিরোধ করার জন্য এটি ব্যবহার।

আমার পদ্ধতি:

  • আপনি ইনপুট হতে ইনপুট আশা যদি এটি সত্যিই পূর্ণসংখ্যা নিশ্চিত করুন। পিএইচপি মত একটি পরিবর্তনশীল টাইপ ভাষা এটি খুবই গুরুত্বপূর্ণ। আপনি উদাহরণস্বরূপ এই খুব সহজ কিন্তু শক্তিশালী সমাধানটি ব্যবহার করতে পারেন: sprintf("SELECT 1,2,3 FROM table WHERE 4 = %u", $input);

  • আপনি পূর্ণসংখ্যা হেক্স থেকে অন্য কিছু আশা করি । যদি আপনি এটি hex, আপনি পুরোপুরি সব ইনপুট অব্যাহতি হবে। সি / সি ++ তে একটি ফাংশন রয়েছে যা mysql_hex_string() নামে পরিচিত, পিএইচপি তে আপনি bin2hex() ব্যবহার করতে পারেন।

    আপনার mysql_real_escape_string স্ট্রিংটি 2x আকারের মূল দৈর্ঘ্যের জন্য চিন্তা করবেন না কারণ এমনকি যদি আপনি mysql_real_escape_string ব্যবহার করেন তবে mysql_real_escape_string একই ক্ষমতা ((2*input_length)+1) , যা একই।

  • বাইনারি ডেটা স্থানান্তরিত করার সময় এই হেক্স পদ্ধতিটি প্রায়ই ব্যবহার করা হয়, তবে আমি এসকিউএল ইনজেকশন আক্রমণগুলি প্রতিরোধ করতে সমস্ত ডেটাতে এটি ব্যবহার না করার কোন কারণ দেখি না। উল্লেখ্য, আপনাকে 0x দিয়ে ডেটা UNHEX হবে অথবা পরিবর্তে MySQL ফাংশন UNHEX ব্যবহার করতে হবে।

সুতরাং, উদাহরণস্বরূপ, প্রশ্ন:

SELECT password FROM users WHERE name = 'root'

হয়ে যাবে:

SELECT password FROM users WHERE name = 0x726f6f74

অথবা

SELECT password FROM users WHERE name = UNHEX('726f6f74')

হেক্স নিখুঁত অব্যাহতি। ইনজেকশন কোন উপায়।

UNHEX ফাংশন এবং 0x উপসর্গ মধ্যে পার্থক্য

মন্তব্যের মধ্যে কিছু আলোচনা ছিল, তাই আমি পরিশেষে এটা পরিষ্কার করতে চান। এই দুটি পদ্ধতির খুব অনুরূপ, কিন্তু তারা কিছু উপায়ে একটু ভিন্ন:

** 0x ** উপসর্গটি শুধুমাত্র গৃহস্থালি, ওয়ারার, পাঠ্য, ব্লক, বাইনারি ইত্যাদি ডেটা কলামগুলির জন্য ব্যবহার করা যেতে পারে।
এছাড়াও, আপনি যদি খালি স্ট্রিং সন্নিবেশ করতে চলেছেন তবে এটির ব্যবহারটি একটু জটিল। আপনাকে পুরোপুরি এটি '' দিয়ে '' প্রতিস্থাপন করতে হবে, অথবা আপনি একটি ত্রুটি পাবেন।

UNHEX () কোন কলামে কাজ করে; আপনি খালি স্ট্রিং সম্পর্কে চিন্তা করতে হবে না।

হেক্স পদ্ধতি প্রায়ই আক্রমণ হিসাবে ব্যবহার করা হয়

মনে রাখবেন যে এই হেক্স পদ্ধতিটি প্রায়শই এসকিউএল ইনজেকশন আক্রমণ হিসাবে ব্যবহৃত হয় যেখানে ইন্টিজারগুলি কেবল স্ট্রিংগুলির মতো এবং কেবল mysql_real_escape_string সাথে পালিয়ে যায়। তারপর আপনি কোট ব্যবহার এড়াতে পারেন।

উদাহরণস্বরূপ, যদি আপনি এমন কিছু করেন তবে:

"SELECT title FROM article WHERE id = " . mysql_real_escape_string($_GET["id"])

একটি আক্রমণ খুব সহজেই আপনি ইনজেকশন করতে পারেন । আপনার স্ক্রিপ্ট থেকে নিম্নলিখিত ইনজেকশন কোড ফিরে বিবেচনা করুন:

নির্বাচন করুন ... যেখানে id = -1 টি ইউনিয়ন তথ্য_সিকিমা.tables থেকে সারণি_নাম নির্বাচন করুন

এবং এখন শুধু টেবিলের গঠন নিষ্কাশন:

নির্বাচন করুন ... যেখানে id = -1 টি ইউনিয়ন সবথেকে কলাম_নাম info_schema.column থেকে নির্বাচন করুন যেখানে table_name = 0x61727469636c65

এবং তারপর শুধু যে কোন তথ্য চান নির্বাচন করুন। এটা কি শান্ত না?

কিন্তু যদি কোন ইনজেকশেবল সাইটটির কোডার হেক্স করে তবে কোন ইনজেকশন সম্ভব হবে না কারণ প্রশ্নটি এইরকম দেখতে পাবে: SELECT ... WHERE id = UNHEX('2d312075...3635')


আমার মতে, সাধারণত আপনার পিএইচপি অ্যাপ্লিকেশন (অথবা যে কোনও ওয়েব অ্যাপ্লিকেশনের জন্য) এ এসকিউএল ইনজেকশন প্রতিরোধের সবচেয়ে ভাল উপায় হল আপনার অ্যাপ্লিকেশনটির আর্কিটেকচার সম্পর্কে চিন্তা করা। যদি এসকিউএল ইনজেকশন থেকে রক্ষা করার একমাত্র উপায় হল কোনও বিশেষ পদ্ধতি বা ফাংশন ব্যবহার করতে মনে রাখা যা সঠিকভাবে ডাটাবেসের সাথে কথাবার্তা করে প্রত্যেকটি সময়, আপনি এটি ভুল করছেন। এই ভাবে, এটি কেবলমাত্র সময়ের ব্যাপার, যতক্ষণ না আপনি আপনার কোডে কোনও সময়ে আপনার প্রশ্নের সঠিকভাবে বিন্যাস করতে ভুলবেন না।

এমভিসি প্যাটার্নটি গ্রহণ করা এবং CakePHP বা কোড CodeIgniter মত একটি ফ্রেমওয়ার্ক সম্ভবত সঠিক উপায়: নিরাপদ ডাটাবেস প্রশ্নগুলি তৈরি করার মতো সাধারণ কাজগুলি সমাধান করা হয়েছে এবং এই কাঠামোর মধ্যে কেন্দ্রীয়ভাবে প্রয়োগ করা হয়েছে। তারা আপনাকে আপনার ওয়েব অ্যাপ্লিকেশনটিকে বুদ্ধিমান ভাবে সংগঠিত করতে এবং নিরাপদভাবে একক এসকিউএল ক্যোয়ারীগুলি নির্মাণের চেয়ে বস্তুগুলি লোড এবং সঞ্চয় করার বিষয়ে আরও বেশি চিন্তা করতে আপনাকে সহায়তা করে।


এখানে প্রতিটি উত্তর সমস্যা শুধুমাত্র অংশ জুড়ে। আসলে, চারটি ভিন্ন প্রশ্ন অংশ রয়েছে যা আমরা গতিশীলভাবে যুক্ত করতে পারি:

  • একটি স্ট্রিং
  • একটি সংখ্যা
  • একটি সনাক্তকারী
  • একটি সিনট্যাক্স শব্দ।

এবং প্রস্তুত বিবৃতি শুধুমাত্র তাদের দুটি কভার।

কিন্তু কখনও কখনও আমাদের আরও বেশি গতিশীল আমাদের ক্যোয়ারী তৈরি করতে হবে, পাশাপাশি অপারেটর বা সনাক্তকারীগুলিকে যুক্ত করে। সুতরাং, আমরা বিভিন্ন সুরক্ষা কৌশল প্রয়োজন হবে।

সাধারণভাবে, যেমন একটি সুরক্ষা পদ্ধতি whitelisting উপর ভিত্তি করে।

এই ক্ষেত্রে, প্রতিটি গতিশীল পরামিতি আপনার স্ক্রিপ্টে হার্ডকোড হওয়া উচিত এবং সেই সেট থেকে নির্বাচিত করা উচিত। উদাহরণস্বরূপ, ডাইনামিক অর্ডার করার জন্য:

$orders  = array("name", "price", "qty"); // Field names
$key     = array_search($_GET['sort'], $orders)); // See if we have such a name
$orderby = $orders[$key]; // If not, first one will be set automatically. smart enuf :)
$query   = "SELECT * FROM `table` ORDER BY $orderby"; // Value is safe

তবে, সনাক্তকারী নিরাপদ করার আরেকটি উপায় রয়েছে - পালানো। যতক্ষণ আপনি একটি সনাক্তকারী উদ্ধৃত আছে, যতক্ষণ আপনি তাদের দ্বিগুণ করে ব্যাকটিক্স থেকে পালাতে পারেন।

আরও একটি ধাপ হিসাবে, আমরা প্রস্তুত বিবৃতি থেকে কিছু স্থানধারক (প্রশ্নের মধ্যে প্রকৃত মূল্য প্রতিনিধিত্ব করার জন্য একটি প্রক্সি) ব্যবহার করার একটি সত্যিকারের উজ্জ্বল ধারনা ধার করতে পারি এবং অন্য কোনও স্থানধারক - একটি সনাক্তকারী স্থানধারক আবিষ্কার করতে পারি।

সুতরাং, দীর্ঘ গল্প সংক্ষিপ্ত করতে: এটি একটি স্থানধারক , প্রস্তুত বিবৃতি একটি রূপালী বুলেট হিসাবে বিবেচনা করা যেতে পারে।

সুতরাং, যতক্ষণ আপনি স্থানধারীদের (এবং এই স্থানধারীদের অবশ্যই যথাযথভাবে প্রক্রিয়াভুক্ত) ব্যবহার করে প্রশ্নের সাথে গতিশীল অংশগুলি যোগ করছেন ততক্ষণ একটি সাধারণ সুপারিশটি সংশোধন করা যেতে পারে , আপনি নিশ্চিত হতে পারেন যে আপনার প্রশ্নটি নিরাপদ

এখনও, এসকিউএল সিনট্যাক্স কীওয়ার্ডগুলির সাথে একটি সমস্যা রয়েছে (যেমন AND , DESC এবং DESC ), তবে সাদা DESC এই ক্ষেত্রে একমাত্র পদ্ধতি বলে মনে হয়।

হালনাগাদ

যদিও এসকিউএল ইনজেকশন সুরক্ষা সম্পর্কিত সর্বোত্তম অনুশীলনের একটি সাধারণ চুক্তি রয়েছে তবে এখনও অনেকগুলি খারাপ অভ্যাস রয়েছে। এবং তাদের মধ্যে কিছু খুব গভীরভাবে পিএইচপি ব্যবহারকারীদের মন rooted। উদাহরণস্বরূপ, এই পৃষ্ঠায় রয়েছে (যদিও বেশিরভাগ দর্শকদের কাছে অদৃশ্য) 80 টিরও বেশি মুছে ফেলা উত্তর - সমস্ত খারাপ মানের কারণে বা খারাপ এবং পুরানো অনুশীলনের প্রচার করে সম্প্রদায়টি সরিয়েছে। খারাপ, কিছু খারাপ উত্তর মুছে ফেলা হয় না, বরং সমৃদ্ধ।

উদাহরণস্বরূপ, there(1) still(3) many(4) answers(5) , share সহ আপনি ম্যানুয়াল স্ট্রিং share - একটি পুরনো পদ্ধতি যা অনিরাপদ প্রমাণিত হয়।

অথবা একটি সামান্য ভাল উত্তর যা কেবল স্ট্রিং ফর্ম্যাটিংয়ের আরেকটি পদ্ধতি প্রস্তাব করে এবং এটি এমনকি চূড়ান্ত প্যানেসিয়াকেও সমৃদ্ধ করে। অবশ্যই, এটা না। এই পদ্ধতিটি নিয়মিত স্ট্রিং ফর্ম্যাটিংয়ের চেয়ে ভাল নয়, তবুও এটি তার সমস্ত ত্রুটিগুলি রাখে: এটি শুধুমাত্র স্ট্রিংগুলিতে প্রযোজ্য এবং অন্য যেকোন ম্যানুয়াল ফর্ম্যাটিং হিসাবে, এটি অপরিহার্যভাবে ঐচ্ছিক, অ-বাধ্যতামূলক পরিমাপ যা কোনো ধরণের মানব ত্রুটির প্রবণতা।

আমি মনে করি এটি একটি পুরানো কুসংস্কারের কারণে এটি, যেমন OWASP বা পিএইচপি ম্যানুয়াল মত কর্তৃপক্ষ দ্বারা সমর্থিত, যা যা "পালিয়ে যাওয়া" এবং এসকিউএল ইনজেকশন থেকে সুরক্ষার মধ্যে সমতা ঘোষণা করে।

যাই হোক না কেন পিএইচপি ম্যানুয়াল বয়সের জন্য বলেন, *_escape_string কোন উপায়ে তথ্য নিরাপদ করে তোলে এবং কখনও উদ্দেশ্যে করা হয়েছে। স্ট্রিং ব্যতীত অন্য কোনও SQL অংশে নিরর্থক হওয়ার পাশাপাশি, ম্যানুয়াল এড়িয়ে যাওয়া ভুল, কারণ এটি স্বয়ংক্রিয়ভাবে বিপরীত হিসাবে ম্যানুয়াল।

ও ওএসএসএসপি এটিকে আরও খারাপ করে তোলে, ব্যবহারকারীর ইনপুট এড়িয়ে চলার উপর জোর দেয় যা একটি বোকা বোকা: ইনজেকশন সুরক্ষা প্রসঙ্গে এমন কোনও শব্দ থাকা উচিত নয়। প্রতিটি পরিবর্তনশীল সম্ভাব্য বিপজ্জনক - কোন ব্যাপার উৎস! অথবা, অন্য কথায় - প্রত্যেক পরিবর্তনশীলকে সঠিকভাবে কোনও প্রশ্নে ফরম্যাট করা উচিত - কোনও উৎস আবারও। এটি গুরুত্বপূর্ণ যে গন্তব্য। যে মুহূর্তে একজন বিকাশকারী মেষগুলিকে ছাগল থেকে আলাদা করতে শুরু করে (চিন্তা করে যে কোন নির্দিষ্ট পরিবর্তনশীল "নিরাপদ" কিনা বা না) তিনি বিপর্যয়ের প্রতি তার প্রথম পদক্ষেপ গ্রহণ করেন। উল্লেখ নেই যে এমনকি শব্দটি এন্ট্রি পয়েন্টে পালিয়ে যাওয়ার জন্য প্রচুর পরিমাণে পরামর্শ দেয়, যা খুব জাদু উদ্ধৃতির বৈশিষ্ট্যের অনুরূপ - ইতোমধ্যে তুচ্ছ, অব্যবহৃত এবং সরানো।

সুতরাং, যাই হোক না কেন "পালিয়ে যাওয়া" এর বিপরীতে, প্রস্তুত বিবৃতিগুলি এমন পরিমাপ যা প্রকৃতপক্ষে এসকিউএল ইনজেকশন (যখন প্রযোজ্য) থেকে রক্ষা করে।

যদি আপনি এখনও দৃঢ়প্রত্যয়ী না হন তবে আমি এখানে লিখেছি একটি ধাপে ধাপে ব্যাখ্যা, হিটহিকার্স গাইড টু এসকিউএল ইনজেকশন প্রতিরোধ , যেখানে আমি এই সমস্ত বিষয়গুলি বিস্তারিতভাবে ব্যাখ্যা করেছি এবং এমনকি সম্পূর্ণরূপে খারাপ অনুশীলন এবং তাদের প্রকাশনার জন্য সম্পূর্ণরূপে নিবেদিত একটি বিভাগকে সংকলিত করেছি।


পরামিতি অনুসন্ধান এবং ইনপুট বৈধতা যেতে উপায়। এসকিউএল ইনজেকশনটি ঘটতে পারে এমন অনেক পরিস্থিতিতে রয়েছে, যদিও mysql_real_escape_string() ব্যবহার করা হয়েছে।

যারা উদাহরণ এসকিউএল ইনজেকশন ঝুঁকিপূর্ণ হয়:

$offset = isset($_GET['o']) ? $_GET['o'] : 0;
$offset = mysql_real_escape_string($offset);
RunQuery("SELECT userid, username FROM sql_injection_test LIMIT $offset, 10");

অথবা

$order = isset($_GET['o']) ? $_GET['o'] : 'userid';
$order = mysql_real_escape_string($order);
RunQuery("SELECT userid, username FROM sql_injection_test ORDER BY `$order`");

উভয় ক্ষেত্রে, আপনি encapsulation রক্ষা করতে ব্যবহার করতে পারবেন না।

Source : অপ্রত্যাশিত এসকিউএল ইনজেকশন (যখন পালানো যথেষ্ট নয়)


PDO এবং প্রস্তুত প্রশ্ন ব্যবহার করুন।

( $conn একটি PDO অবজেক্ট)

$stmt = $conn->prepare("INSERT INTO tbl VALUES(:id, :name)");
$stmt->bindValue(':id', $id);
$stmt->bindValue(':name', $name);
$stmt->execute();

প্রস্তুত বিবৃতি এবং পরামিতি প্রশ্নের ব্যবহার করুন। এই যে কোনও পরামিতি থেকে আলাদাভাবে ডাটাবেস সার্ভারে প্রেরিত এবং পাঠানো হয় এমন SQL স্টেটমেন্ট। আক্রমণকারীর জন্য দূষিত এসকিউএল ইনজেকশনের পক্ষে এটি অসম্ভব।

আপনি মূলত এই অর্জন দুটি বিকল্প আছে:

  1. PDO ব্যবহার করে (কোন সমর্থিত ডাটাবেস ড্রাইভারের জন্য):

    $stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
    
    $stmt->execute(array('name' => $name));
    
    foreach ($stmt as $row) {
        // do something with $row
    }
    
  2. MySQLi ব্যবহার করে (MySQL এর জন্য):

    $stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
    $stmt->bind_param('s', $name); // 's' specifies the variable type => 'string'
    
    $stmt->execute();
    
    $result = $stmt->get_result();
    while ($row = $result->fetch_assoc()) {
        // do something with $row
    }
    

আপনি যদি মাইএসকিউএল ছাড়া অন্য কোনও ডেটাবেসে সংযোগ করছেন, তবে ড্রাইভার-নির্দিষ্ট দ্বিতীয় বিকল্পটি রয়েছে যা আপনি পোস্টগ্রেএসকিউএল (যেমন pg_prepare() এবং pg_execute() জন্য উল্লেখ করতে পারেন। পিডিও সর্বজনীন বিকল্প।

সঠিকভাবে সংযোগ সেট আপ

মনে রাখবেন PDO ব্যবহার করে একটি মাইএসকিউএল ডাটাবেস অ্যাক্সেস করার জন্য প্রকৃত প্রস্তুত বিবৃতি ডিফল্টভাবে ব্যবহার করা হয় না । এটি ঠিক করার জন্য আপনাকে প্রস্তুত বিবৃতিগুলির এমুলেশন নিষ্ক্রিয় করতে হবে। পিডিও ব্যবহার করে সংযোগ তৈরির একটি উদাহরণ হল:

$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');

$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

উপরের উদাহরণে ত্রুটি মোড কঠোরভাবে প্রয়োজনীয় নয়, তবে এটি যুক্ত করার পরামর্শ দেওয়া হয় । এইভাবে স্ক্রিপ্টটি যখন কোনও ভুল ঘটে তখন Fatal Error সাথে থামবে না। এবং এটি বিকাশকারীকে কোনও ত্রুটি (গুলি) catch সুযোগ দেয় যা N PDOException গুলি হিসাবে throw

অবশ্য বাধ্যতামূলক , প্রথম setAttribute() লাইন, যা setAttribute() প্রস্তুত বিবৃতিগুলি নিষ্ক্রিয় করে এবং প্রকৃত প্রস্তুত বিবৃতিগুলি ব্যবহার করে বলে। এটি নিশ্চিত করে যে বিবৃতি এবং মানগুলি পিএইচপি দ্বারা মাইএসকিউএল সার্ভারে পাঠানোর আগে পার্স করা হয় না (সম্ভাব্য আক্রমণকারীকে দূষিত এসকিউএলকে ইনজেকশন করার কোন সুযোগ নেই)।

যদিও আপনি কন্সট্রকটরের বিকল্পগুলিতে charset সেট করতে পারেন তবে এটি মনে রাখা গুরুত্বপূর্ণ যে পিএইচপি এর 'পুরোনো' সংস্করণগুলি (<5.3.6) নীরবভাবে DSN এর চার্সেটের পরামিতিটি উপেক্ষা করে

ব্যাখ্যা

কি হয় SQL সার্ভার আপনি prepare পাস পাস ডাটাবেস সার্ভার দ্বারা বিশ্লেষণ এবং সংকলিত হয়। প্যারামিটার উল্লেখ করে (হয় একটি ? বা একটি নামযুক্ত পরামিতি যেমন :name উপরে উদাহরণে :name ) আপনি ডাটাবেস ইঞ্জিনটি বলবেন যেখানে আপনি ফিল্টার করতে চান। তারপরে আপনি যখন execute কল করেন, তখন প্রস্তুত বিবৃতিটি আপনার নির্দিষ্ট করা পরামিতি মানগুলির সাথে মিলিত হয়।

এখানে গুরুত্বপূর্ণ বিষয় হল যে প্যারামিটার মান সংকলিত বিবৃতির সাথে মিলিত হয়, একটি SQL স্ট্রিং নয়। এসকিউএল ইনজেকশন ডাটাবেস পাঠাতে এসকিউএল তৈরি করে যখন দূষিত স্ট্রিং সহ স্ক্রিপ্ট tricking দ্বারা কাজ করে। সুতরাং প্যারামিটার থেকে আলাদাভাবে আসল এসকিউএল পাঠানোর মাধ্যমে, আপনি এমন কোনও কিছু শেষ করার ঝুঁকি সীমাবদ্ধ করেন যা আপনি চান না। প্রস্তুতকৃত বিবৃতি ব্যবহার করার সময় পাঠানো যেকোনো প্যারামিটার কেবল স্ট্রিং হিসাবে বিবেচিত হবে (যদিও ডাটাবেস ইঞ্জিনটি কিছু অপটিমাইজেশন করতে পারে তবে অবশ্যই প্যারামিটারগুলি সংখ্যা হিসাবেও শেষ হতে পারে)। উপরের উদাহরণে, যদি $name পরিবর্তনশীল 'Sarah'; DELETE FROM employees 'Sarah'; DELETE FROM employees ফলাফলটি কেবল স্ট্রিংয়ের জন্য অনুসন্ধান হবে "'Sarah'; DELETE FROM employees" এবং আপনি খালি টেবিলের সাথে শেষ না হবেন।

প্রস্তুত বিবৃতি ব্যবহার করার আরেকটি সুবিধা হল যে আপনি যদি একই অধিবেশনটিতে একই বিবৃতিটি অনেক বার সম্পাদন করেন তবে এটি আপনাকে কিছু গতিবিধিকে দেওয়ার পরে কেবল একবার বিশ্লেষণ এবং সংকলিত হবে।

ওহ, এবং যেহেতু আপনি একটি সন্নিবেশের জন্য এটি কীভাবে করবেন তা জিজ্ঞাসা করার পরে, এখানে একটি উদাহরণ (পিডিও ব্যবহার করে):

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array('column' => $unsafeValue));

প্রস্তুত বিবৃতি গতিশীল প্রশ্নের জন্য ব্যবহার করা যাবে?

আপনি এখনও কোয়েরি প্যারামিটারগুলির জন্য প্রস্তুত বিবৃতিগুলি ব্যবহার করতে পারেন, তবে গতিশীল প্রশ্নগুলির গঠন নিজেই প্যারামিটারিজেড হতে পারে না এবং কিছু ক্যোয়ারী বৈশিষ্ট্যগুলি প্যারামেট্রিজড করা যাবে না।

এই নির্দিষ্ট পরিস্থিতিতে, সবচেয়ে ভাল জিনিস এমন একটি পরিচ্ছন্ন তালিকা ফিল্টার ব্যবহার করে যা সম্ভাব্য মানগুলিকে সীমিত করে।

// Value whitelist
// $dir can only be 'DESC' otherwise it will be 'ASC'
if (empty($dir) || $dir !== 'DESC') {
   $dir = 'ASC';
}

আমি কয়েক বছর আগে এই সামান্য ফাংশন লিখেছেন:

function sqlvprintf($query, $args)
{
    global $DB_LINK;
    $ctr = 0;
    ensureConnection(); // Connect to database if not connected already.
    $values = array();
    foreach ($args as $value)
    {
        if (is_string($value))
        {
            $value = "'" . mysqli_real_escape_string($DB_LINK, $value) . "'";
        }
        else if (is_null($value))
        {
            $value = 'NULL';
        }
        else if (!is_int($value) && !is_float($value))
        {
            die('Only numeric, string, array and NULL arguments allowed in a query. Argument '.($ctr+1).' is not a basic type, it\'s type is '. gettype($value). '.');
        }
        $values[] = $value;
        $ctr++;
    }
    $query = preg_replace_callback(
        '/{(\\d+)}/', 
        function($match) use ($values)
        {
            if (isset($values[$match[1]]))
            {
                return $values[$match[1]];
            }
            else
            {
                return $match[0];
            }
        },
        $query
    );
    return $query;
}

function runEscapedQuery($preparedQuery /*, ...*/)
{
    $params = array_slice(func_get_args(), 1);
    $results = runQuery(sqlvprintf($preparedQuery, $params)); // Run query and fetch results.   
    return $results;
}

এটি একটি এক-রেখার C # -শ স্ট্রিং-এ চলমান বিবৃতিগুলিকে অনুমোদন করে।

runEscapedQuery("INSERT INTO Whatever (id, foo, bar) VALUES ({0}, {1}, {2})", $numericVar, $stringVar1, $stringVar2);

এটা পরিবর্তনশীল ধরনের বিবেচনা escapes। আপনি টেবিল, কলামের নামগুলি পরামিতি করার চেষ্টা করলে, এটি অসম সিনট্যাক্স যা উদ্ধৃতিগুলিতে প্রতিটি স্ট্রিং রাখে এটি ব্যর্থ হবে।

নিরাপত্তা আপডেট: পূর্ববর্তী str_replaceসংস্করণটি ব্যবহারকারীর ডেটাতে {#} টোকেন যোগ করে ইনজেকশনগুলিকে অনুমতি দেয়। preg_replace_callbackপ্রতিস্থাপন এই টোকেন রয়েছে যদি এই সংস্করণ সমস্যা সৃষ্টি করে না।


আমি মনে করি কেউ পিএইচপি এবং মাইএসকিউএল বা অন্য কোন ডেটাবেস সার্ভার ব্যবহার করতে চায়:

  1. PDO শেখার বিষয়ে চিন্তা করুন (পিএইচপি ডেটা অবজেক্টস) - এটি একটি ডাটাবেস অ্যাক্সেস স্তর যা একাধিক ডেটাবেসে অ্যাক্সেসের অভিন্ন পদ্ধতি সরবরাহ করে।
  2. MySQLi শেখার MySQLi
  3. যেমন নেটিভ পিএইচপি ফাংশন ব্যবহার করুন: strip_tags , mysql_real_escape_string() অথবা যদি পরিবর্তনশীল সাংখ্যিক, ঠিক (int)$foohere পিএইচপি ভেরিয়েবল টাইপ সম্পর্কে আরও পড়ুন । আপনি যদি পিডিও বা মাইএসকিউএলির মতো লাইব্রেরি ব্যবহার করেন তবে সর্বদা PDO::quote() এবং mysqli_real_escape_string()

লাইব্রেরি উদাহরণস্বরূপ:

---- পিডিও

----- কোন স্থানধারক - এসকিউএল ইনজেকশন জন্য পাকা! এটা খারাপ

$request = $pdoConnection->("INSERT INTO parents (name, addr, city) values ($name, $addr, $city)");

----- অনাহুত স্থানধারক

$request = $pdoConnection->("INSERT INTO parents (name, addr, city) values (?, ?, ?);

----- নামযুক্ত স্থানধারক

$request = $pdoConnection->("INSERT INTO parents (name, addr, city) value (:name, :addr, :city)");

--- MySQLi

$request = $mysqliConnection->prepare('
       SELECT * FROM trainers
       WHERE name = ?
       AND email = ?
       AND last_login > ?');

    $query->bind_param('first_param', 'second_param', $mail, time() - 3600);
    $query->execute();

PS :

পিডিও সহজেই এই যুদ্ধ জয়। বারোটি ভিন্ন ডাটাবেস ড্রাইভার এবং নামযুক্ত প্যারামিটারের সহায়তায় আমরা ছোট পারফরম্যান্স ক্ষতি উপেক্ষা করতে পারি এবং তার API এ ব্যবহার করতে পারি। নিরাপত্তা দৃষ্টিকোণ থেকে, যতক্ষণ ডেভেলপার তাদের ব্যবহার করা অনুমিত হয় ততক্ষণ পর্যন্ত তাদের উভয় নিরাপদ

তবে পিডিও এবং মাইএসকিউলি উভয়ই খুব দ্রুত, মাইএসকিউএলটি বেঞ্চমার্কগুলির মধ্যে উল্লেখযোগ্যভাবে দ্রুত সঞ্চালিত হয় - ~ 2.5% অনির্বাচিত বিবৃতির জন্য এবং ~ 6.5% প্রস্তুতদের জন্য।

এবং আপনার ডাটাবেস প্রতি ক্যোয়ারী পরীক্ষা করুন - এটা ইনজেকশন প্রতিরোধ করার জন্য একটি ভাল উপায়।


** সতর্কতা: এই উত্তরের বর্ণিত পদ্ধতিটি শুধুমাত্র খুব নির্দিষ্ট পরিস্থিতিতে প্রয়োগ করে এবং এটি সুরক্ষিত নয় কারণ এসকিউএল ইনজেকশন আক্রমণগুলি কেবলমাত্র ইনজেক্ট করতে সক্ষম হওয়ার উপর নির্ভর করে না X=Y। **

যদি আক্রমণকারীরা পিএইচপি এর $_GETভেরিয়েবলের মাধ্যমে বা ইউআরএল এর ক্যোয়ারী স্ট্রিংয়ের মাধ্যমে ফর্মে হ্যাক করার চেষ্টা করছে , তবে তারা নিরাপদ না থাকলে আপনি তাদের ধরতে সক্ষম হবেন।

RewriteCond %{QUERY_STRING} ([0-9]+)=([0-9]+)
RewriteRule ^(.*) ^/track.php

কারণ 1=1, 2=2, 1=2, 2=1, 1+1=2, ইত্যাদি ... একটি আক্রমণকারী একজন SQL ডাটাবেস সাধারণ প্রশ্ন আছে। হয়তো এটি অনেক হ্যাকিং অ্যাপ্লিকেশন দ্বারা ব্যবহার করা হয়।

কিন্তু আপনাকে অবশ্যই সাবধান থাকতে হবে, আপনার সাইটের থেকে নিরাপদ অনুসন্ধানটি পুনঃলিখন করতে হবে না। উপরের কোডটি আপনাকে একটি টিপ দিচ্ছে, পুনর্লিখন বা পুনঃনির্দেশ (এটি আপনার উপর নির্ভর করে) যে হ্যাকিং-নির্দিষ্ট গতিশীল ক্যোয়ারী স্ট্রিং কোনও পৃষ্ঠায় আক্রমনকারীর IP ঠিকানা সংরক্ষণ করবে , বা এমনকি তাদের কুকি, ইতিহাস, ব্রাউজার, বা অন্য কোনও সংবেদনশীল তথ্য, যাতে আপনি তাদের অ্যাকাউন্ট নিষিদ্ধ বা কর্তৃপক্ষের সাথে যোগাযোগ করে পরে তাদের সাথে মোকাবিলা করতে পারেন।


Idiorm মত একটি 'অবজেক্ট-রিলেশনাল Idiorm' ব্যবহার করা একটি ভাল ধারণা :

$user = ORM::for_table('user')
->where_equal('username', 'j4mie')
->find_one();

$user->first_name = 'Jamie';
$user->save();

$tweets = ORM::for_table('tweet')
    ->select('tweet.*')
    ->join('user', array(
        'user.id', '=', 'tweet.user_id'
    ))
    ->where_equal('user.username', 'j4mie')
    ->find_many();

foreach ($tweets as $tweet) {
    echo $tweet->text;
}

এটি কেবলমাত্র এসকিউএল ইনজেকশন থেকে সংরক্ষণ করে না তবে সিনট্যাক্স ত্রুটি থেকেও! এছাড়াও ফিল্টার ফিল্টার বা একাধিক ফলাফলগুলিতে একাধিক ফলাফলগুলিতে প্রয়োগ করার জন্য পদ্ধতি শৃঙ্খলা সহ মডেল সংগ্রহ সমর্থন করে।


PDO ( mysql_ফাংশন থেকে আসছে ) ব্যবহার করার বিষয়ে অনিশ্চিতদের জন্য , আমি একটি খুব সাধারণ, পিডিও রপার তৈরি করেছি যা একটি একক ফাইল। এটি সমস্ত সাধারণ বিষয়গুলি প্রয়োগ করা কত সহজ হবে তা দেখানোর জন্য বিদ্যমান। PostgreSQL, MySQL, এবং SQLite এর সাথে কাজ করে।

মূলত, এটা পড়তে PDO কিভাবে PDO ফাংশন লাগাতে বাস্তব জীবনে ব্যবহার করার জন্য এটি সহজ সংরক্ষণ এবং বিন্যাস মান পুনরুদ্ধার করতে করতে দেখতে আপনি চান।

আমি একটি একক কলাম চাই

$count = DB::column('SELECT COUNT(*) FROM `user`);

আমি একটি অ্যারে (কী => মান) ফলাফল চান (অর্থাত একটি নির্বাচনবাক্য তৈরি করার জন্য)

$pairs = DB::pairs('SELECT `id`, `username` FROM `user`);

আমি একটি একক সারি ফলাফল চান

$user = DB::row('SELECT * FROM `user` WHERE `id` = ?', array($user_id));

আমি ফলাফল একটি অ্যারে চাই

$banned_users = DB::fetch('SELECT * FROM `user` WHERE `banned` = ?', array(TRUE));

অনেক দরকারী উত্তর সম্পর্কে, আমি এই থ্রেডে কিছু মান যোগ করার আশা করি। এসকিউএল ইনজেকশন একটি আক্রমণ যা ব্যবহারকারী ইনপুট (ব্যবহারকারীরা ভরা ইনপুট এবং তারপরে ভিতরে প্রশ্নগুলির মধ্যে ব্যবহার করে) মাধ্যমে সম্পন্ন করা যেতে পারে, এসকিউএল ইনজেকশন নিদর্শনগুলি সঠিক কোয়েরি সিনট্যাক্স হয় যখন আমরা এটি কল করতে পারি: খারাপ কারণে খারাপ প্রশ্নগুলি, আমরা অনুমান করি যে নিরাপত্তার তিনটি নীতি (গোপনীয়তা, সততা, প্রাপ্যতা) প্রভাবিত করে এমন গোপন তথ্য (অ্যাক্সেস নিয়ন্ত্রণ ব্যবধান) পেতে চেষ্টা করে এমন খারাপ ব্যক্তি হোন।

এখন, আমাদের পয়েন্টটি যেমন এসকিউএল ইনজেকশন আক্রমণ, পিএইচপি ব্যবহার করে এসকিউএল ইনজেকশন আক্রমণকে প্রতিরোধ করা প্রশ্ন জিজ্ঞাসা করা প্রশ্ন, আরও বেশি বাস্তবসম্মত, ডাটা ফিল্টারিং বা ইনপুট ডেটা ক্লিয়ারিং, যেমন ব্যবহারকারীর ইনপুট ডেটা ব্যবহার করে প্রশ্ন, পিএইচপি বা অন্য কোন প্রোগ্রামিং ভাষা ব্যবহার করে মামলা হয় না বা এসকিউএল ইনজেকশন প্রতিরোধের সমর্থনে যে কোনও সরঞ্জামের মতো আধুনিক প্রযুক্তির ব্যবহার করার জন্য আরো মানুষকে সুপারিশ করা হয়েছে, এই সরঞ্জামগুলি আর উপলব্ধ নেই? আপনি কিভাবে আপনার আবেদন নিরাপদ?

এসকিউএল ইনজেকশন এর বিরুদ্ধে আমার পদ্ধতি হল: ব্যবহারকারীর ইনপুট ডেটা সাবস্ক্রাইব করে পাঠানোর আগে (কোনও প্রশ্নের মধ্যে এটি ব্যবহার করার আগে) সাফ করুন।

ডেটার ফিল্টারিং (নিরাপদ ডেটাতে অনিরাপদ ডেটা রূপান্তর করা) এটি বিবেচনা করুন যে PDO এবং MySQLi উপলব্ধ নয়, আপনি কীভাবে আপনার আবেদনটি সুরক্ষিত করতে পারেন? আপনি কি আমাকে ব্যবহার করতে বাধ্য করেন? পিএইচপি ছাড়া অন্যান্য ভাষা সম্পর্কে কি? আমি সাধারণ ধারনা প্রদান করতে পছন্দ করি কারণ এটি শুধুমাত্র বিস্তৃত সীমানার জন্য ব্যবহার করা যেতে পারে নির্দিষ্ট ভাষা নয়।

  1. এসকিউএল ব্যবহারকারী (ব্যবহারকারীর বিশেষাধিকার সীমাবদ্ধ): সর্বাধিক সাধারণ এসকিউএল ক্রিয়াকলাপগুলি (নির্বাচন করুন, আপডেট করুন, INSERT), তারপরে, কেন এমন ব্যবহারকারীকে আপডেট করার সুবিধা দেওয়া উচিত নয়? উদাহরণস্বরূপ লগইন, এবং অনুসন্ধান পৃষ্ঠাগুলি শুধুমাত্র SELECT ব্যবহার করে, তাহলে, কেন এই পৃষ্ঠাগুলিতে ডিবি ব্যবহারকারীদের উচ্চতর সুবিধাগুলি ব্যবহার করে? RULE: সমস্ত সুবিধাগুলির জন্য একটি ডেটাবেস ব্যবহারকারী তৈরি করবেন না, সমস্ত এসকিউএল ক্রিয়াকলাপের জন্য, আপনি সহজে ব্যবহারের জন্য ব্যবহারকারী নাম হিসাবে আপনার প্রকল্পটি (বিভ্রান্তকারী, নির্বাচনকারী, আপডেটউসার) তৈরি করতে পারেন।

অন্তত বিশেষাধিকার নীতি দেখুন

  1. ডেটা ফিল্টারিং: কোনও প্রশ্ন তৈরি করার আগে ব্যবহারকারী ইনপুট যাচাই এবং ফিল্টার করা উচিত, প্রোগ্রামারদের জন্য, প্রতিটি ব্যবহারকারী-ইনপুট ভেরিয়েবলগুলির জন্য কিছু বৈশিষ্ট্য নির্ধারণ করা গুরুত্বপূর্ণ: ডেটা টাইপ, ডেটা প্যাটার্ন এবং ডেটা দৈর্ঘ্য । একটি ক্ষেত্র যা (x এবং y) এর মধ্যে একটি নম্বর (x এবং y) এর মধ্যে একটি স্ট্রিং (পাঠ্য) যা ক্ষেত্রের জন্য সঠিক নিয়ম ব্যবহার করে অবশ্যই যাচাই করা উচিত: প্যাটার্ন ক্ষেত্রে, উদাহরণস্বরূপ, ব্যবহারকারীর অবশ্যই কেবলমাত্র কিছু অক্ষর থাকা উচিত বলে [a- zA-Z0-9_-।] দৈর্ঘ্য (x এবং n) এর মধ্যে পরিবর্তিত হয় যেখানে x এবং n (পূর্ণসংখ্যা, x <= n)। নিয়ম: সঠিক ফিল্টার এবং বৈধতা নিয়ম তৈরি আমার জন্য সর্বোত্তম অনুশীলন।

  2. অন্যান্য সরঞ্জামগুলি ব্যবহার করুন: এখানে, আমি আপনার সাথে সম্মত হব যে প্রস্তুত বিবৃতি (প্যারামিটারিজেড প্রশ্ন) এবং সংরক্ষিত পদ্ধতিগুলি, এখানে অসুবিধাগুলি এই পদ্ধতিগুলির জন্য উন্নত দক্ষতা প্রয়োজন যা বেশিরভাগ ব্যবহারকারীদের জন্য বিদ্যমান নয়, এখানে মূল ধারণাটি এসকিউএল প্রশ্নের মধ্যে পার্থক্য করা এবং ভিতরে ব্যবহৃত তথ্য, উভয় পন্থাগুলি এমনকি অনিরাপদ ডেটা সহও ব্যবহার করা যেতে পারে, কারণ এখানে ব্যবহারকারী-ইনপুট ডেটা মূল প্রশ্নে কোনও যোগ করেনি যেমন (যেকোন বা x = x)। আরো তথ্যের জন্য, OWASP এসকিউএল ইনজেকশন প্রতিরোধের ঠকাই পত্রক পড়ুন

এখন, আপনি যদি একজন উন্নত ব্যবহারকারী হন তবে আপনি এই প্রতিরক্ষাটি ব্যবহার করার মতো শুরু করতে শুরু করুন, তবে, নতুনদের জন্য, যদি তারা দ্রুত প্রক্রিয়াটি বাস্তবায়ন না করে এবং বিবৃতিটি প্রস্তুত না করে তবে ইনপুট ডেটা ফিল্টার করা যতটা সম্ভব ফিল্টার করা ভাল।

অবশেষে, ব্যবহারকারীর নাম লিখার পরিবর্তে ব্যবহারকারী এই পাঠ্যটি নীচে পাঠায় তা বিবেচনা করুন:

[1] UNION SELECT IF(SUBSTRING(Password,1,1)='2',BENCHMARK(100000,SHA1(1)),0) User,Password FROM mysql.user WHERE User = 'root'

এই ইনপুটটি কোনও প্রস্তুত বিবৃতি এবং সংরক্ষিত পদ্ধতি ছাড়াই তাড়াতাড়ি চেক করা যেতে পারে, তবে ব্যবহারকারীর ডেটা ফিল্টারিং এবং বৈধকরণের পরে তাদের ব্যবহার করে নিরাপদ দিকে থাকা।

শেষ বিন্দু অপ্রত্যাশিত আচরণ সনাক্ত করা যা আরও প্রচেষ্টার এবং জটিলতা প্রয়োজন; এটা স্বাভাবিক ওয়েব অ্যাপ্লিকেশন জন্য সুপারিশ করা হয় না। উপরের ব্যবহারকারীর ইনপুটতে অপ্রত্যাশিত আচরণটি নির্বাচন করুন একবার, শব্দের, আইএফ, সাবস্ট্রিং, বেঞ্চমার্ক, SHA, এই শব্দগুলি সনাক্ত হওয়ার পরে রুট সনাক্ত করা হয়, আপনি ইনপুট এড়াতে পারেন।

UPDATE1:

একজন ব্যবহারকারী মন্তব্য করেছেন যে এই পোস্টটি নিরর্থক, ঠিক আছে! এখানে OWASP.ORG দেওয়া হয়েছে:

প্রাথমিক প্রতিরক্ষা:

বিকল্প # 1: প্রস্তুত বিবৃতিগুলির ব্যবহার (প্যারামিটারাইজড ক্যোয়ারী)
বিকল্প # 2: সংরক্ষিত পদ্ধতিগুলির ব্যবহার
বিকল্প # 3: সমস্ত ব্যবহারকারী সরবরাহকৃত ইনপুট থেকে বেরিয়ে আসার

অতিরিক্ত সুরক্ষা:

এছাড়াও প্রয়োগ করুন: সর্বনিম্ন বিশেষাধিকারটিও
সম্পাদন করুন: হোয়াইট তালিকা ইনপুট যাচাইকরণ

আপনি যেমন জানতে পারেন, একটি নিবন্ধে দাবি করা বৈধ যুক্তি দ্বারা সমর্থিত হওয়া উচিত, অন্তত একটি রেফারেন্স! অন্যথায়, এটি একটি আক্রমণ এবং খারাপ দাবি হিসাবে বিবেচিত হয়!

Update2:

পিএইচপি ম্যানুয়াল থেকে, পিএইচপি: প্রস্তুত বিবৃতি - ম্যানুয়াল :

Escaping এবং এসকিউএল ইনজেকশন

বাঁধ ভেরিয়েবল সার্ভার দ্বারা স্বয়ংক্রিয়ভাবে পালিয়ে যাবে। সার্ভারটি তাদের পালিয়ে যাওয়া মানগুলিকে যথাযথ স্থানে কার্যকর করার আগে বিবৃতি টেমপ্লেটে প্রবেশ করে। একটি উপযুক্ত রূপান্তর তৈরি করতে, আবদ্ধ পরিবর্তনশীল প্রকারের জন্য সার্ভারে একটি ইঙ্গিত প্রদান করা আবশ্যক। আরও তথ্যের জন্য mysqli_stmt_bind_param () ফাংশনটি দেখুন।

এসকিউএল ইনজেকশন রোধ করার জন্য সার্ভারের মধ্যে মানগুলির স্বয়ংক্রিয়ভাবে পালাবার সময় কখনও কখনও সুরক্ষা বৈশিষ্ট্য হিসাবে বিবেচিত হয়। ইনপুট মানগুলি সঠিকভাবে পাল্টে গেলে অ-প্রস্তুত বিবৃতিগুলির সাথে একই ডিগ্রী সুরক্ষা অর্জন করা যেতে পারে।

Update3:

প্রস্তুত বিবৃতি ব্যবহার করার সময় পিডিও এবং মাইএসকিউএলআই কীভাবে মাইএসকিউএল সার্ভারে প্রশ্নটি পাঠাচ্ছে তা জানতে আমি পরীক্ষার ক্ষেত্রে তৈরি করেছি:

PDO:

$user = "''1''"; //Malicious keyword
$sql = 'SELECT * FROM awa_user WHERE userame =:username';
$sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute(array(':username' => $user));

প্রশ্ন লগ

    189 Query SELECT * FROM awa_user WHERE userame ='\'\'1\'\''
    189 Quit

MySQLi:

$stmt = $mysqli->prepare("SELECT * FROM awa_user WHERE username =?")) {
$stmt->bind_param("s", $user);
$user = "''1''";
$stmt->execute();

প্রশ্ন লগ

    188 Prepare   SELECT * FROM awa_user WHERE username =?
    188 Execute   SELECT * FROM awa_user WHERE username ='\'\'1\'\''
    188 Quit

এটা স্পষ্ট যে একটি প্রস্তুত বিবৃতি এছাড়াও তথ্য থেকে escaping হয়, অন্য কিছুই।

উপরের বিবৃতিতে যেমন উল্লেখ করা হয়েছে The automatic escaping of values within the server is sometimes considered a security feature to prevent SQL injection. The same degree of security can be achieved with non-prepared statements, if input values are escaped correctly, এটি প্রমাণ করে যে ডেটা যাচাইকরণ যেমন intval()কোনও প্রশ্ন পাঠানোর আগে পূর্ণসংখ্যা মানগুলির জন্য একটি ভাল ধারণা, তদ্ব্যতীত, প্রশ্ন পাঠানোর আগে দূষিত ব্যবহারকারীর ডেটা প্রতিরোধ করা সঠিক এবং বৈধ পদ্ধতি

আরও বিস্তারিত জানার জন্য এই প্রশ্নটি দেখুন: পিডিও মাইএসকিউএলকে কাঁচা ক্যোয়ারী পাঠায়, যখন মাইস্কুলি প্রস্তুত প্রশ্ন পাঠায়, উভয় একই ফলাফল দেয়

তথ্যসূত্র:

  1. এসকিউএল ইনজেকশন ঠকাই পত্রক
  2. এসকিউএল ইনজেকশন
  3. তথ্য নিরাপত্তা
  4. নিরাপত্তা নীতি
  5. তথ্য বৈধতা

এই পিএইচপি ফাংশন ব্যবহার করে mysql_escape_string()আপনি দ্রুত উপায়ে একটি ভাল প্রতিরোধ পেতে পারেন।

উদাহরণ স্বরূপ:

SELECT * FROM users WHERE name = '".mysql_escape_string($name_from_html_form)."'

mysql_escape_string - একটি mysql_query ব্যবহারের জন্য একটি স্ট্রিং escapes

আরো প্রতিরোধের জন্য, আপনি শেষে যোগ করতে পারেন ...

wHERE 1=1   or  LIMIT 1

অবশেষে আপনি পাবেন:

SELECT * FROM users WHERE name = '".mysql_escape_string($name_from_html_form)."' LIMIT 1

এই সমস্যার সহজ বিকল্প ডাটাবেস নিজেই উপযুক্ত অনুমতি প্রদান করে সমাধান করা যেতে পারে। উদাহরণস্বরূপ: যদি আপনি একটি MySQL ডাটাবেস ব্যবহার করেন তবে টার্মিনাল বা UI সরবরাহ করে ডাটাবেসটিতে প্রবেশ করুন এবং এই কমান্ডটি অনুসরণ করুন:

 GRANT SELECT, INSERT, DELETE ON database TO [email protected]'localhost' IDENTIFIED BY 'password';

এটি ব্যবহারকারীকে নির্দিষ্ট ক্যোয়ারীর কেবলমাত্র সীমিত করতে সীমিত করবে। মুছে ফেলার অনুমতি সরান এবং তাই পিএইচপি পৃষ্ঠা থেকে বহিষ্কৃত প্রশ্নের থেকে তথ্য মুছে ফেলা হবে না। দ্বিতীয় জিনিসটি বিশেষাধিকারগুলি ফ্লাশ করা যাতে মাইএসকিউএল অনুমতি এবং আপডেটগুলি রিফ্রেশ করে।

FLUSH PRIVILEGES; 

flush সম্পর্কে আরও তথ্য ।

ব্যবহারকারীর জন্য বর্তমান সুবিধাগুলি দেখতে নিম্নলিখিত প্রশ্নের জবাবে।

select * from mysql.user where User='username';

GRANT সম্পর্কে আরও জানুন ।


এসকিউএল ইনজেকশন এবং অন্যান্য এসকিউএল হ্যাক প্রতিরোধ করার অনেক উপায় আছে। আপনি সহজে এটি ইন্টারনেট (গুগল অনুসন্ধান) খুঁজে পেতে পারেন। অবশ্যই পিডিও ভাল সমাধানের এক। কিন্তু আমি আপনাকে এসকিউএল ইনজেকশন থেকে কিছু ভাল লিঙ্ক প্রতিরোধ সুপারিশ করতে চাই।

এসকিউএল ইনজেকশন এবং কিভাবে প্রতিরোধ করা হয়

SQL ইনজেকশন জন্য পিএইচপি ম্যানুয়াল

পিএইচপি এসকিউএল ইনজেকশন এবং প্রতিরোধের মাইক্রোসফ্ট ব্যাখ্যা

এবং মাইএসকিউএল এবং পিএইচপি সহ এসকিউএল ইনজেকশন প্রতিরোধের মতো কিছু

এখন, কেন আপনি এসকিউএল ইনজেকশন থেকে আপনার প্রশ্নের প্রতিরোধ করতে হবে?

আমি আপনাকে জানাতে চাই: কেন আমরা নীচের সংক্ষিপ্ত উদাহরণ দিয়ে এসকিউএল ইনজেকশন প্রতিরোধ করার চেষ্টা করি:

লগইন প্রমাণীকরণ মিলের জন্য প্রশ্ন:

$query="select * from users where email='".$_POST['email']."' and password='".$_POST['password']."' ";

এখন, যদি কেউ (একটি হ্যাকার) রাখে

$_POST['email']= [email protected]' OR '1=1

এবং পাসওয়ার্ড কিছু ....

প্রশ্নটি শুধুমাত্র সিস্টেমে বিশ্লেষণ করা হবে:

$query="select * from users where email='[email protected]' OR '1=1';

অন্যান্য অংশ বাতিল করা হবে। তাহলে কি হবে? একটি অ-অনুমোদিত ব্যবহারকারী (হ্যাকার) তার পাসওয়ার্ড ছাড়া প্রশাসক হিসাবে লগ ইন করতে সক্ষম হবে। এখন, সে এমন কিছু করতে পারে যা অ্যাডমিন / ইমেল ব্যক্তি করতে পারে। এসকিউএল ইনজেকশন রোধ করা না হলে এটি খুবই বিপজ্জনক।


নিরাপত্তার দৃষ্টিকোণ থেকে আমি সংরক্ষিত পদ্ধতিগুলির ( মাইএসকিউএল 5.0 থেকে প্রক্রিয়া সমর্থন সমর্থন করেছে ) পছন্দ করি - সুবিধাগুলি হল -

  1. বেশিরভাগ ডাটাবেস ( MySQL সহ ) ব্যবহারকারীর অ্যাক্সেস সঞ্চিত পদ্ধতিগুলি কার্যকর করার জন্য সীমাবদ্ধ করতে সক্ষম করে। সুবিধাপ্রাপ্ত সুরক্ষা অ্যাক্সেস নিয়ন্ত্রণ বিশেষাধিকারগুলির আক্রমন বাড়ানোর জন্য কার্যকর। এটি সংকটাপন্ন অ্যাপ্লিকেশনগুলিকে সরাসরি ডাটাবেসের বিরুদ্ধে এসকিউএল চালাতে সক্ষম হতে বাধা দেয়।
  2. তারা অ্যাপ্লিকেশন থেকে কাঁচা এসকিউএল কোয়েরি বিমূর্ত তাই ডেটাবেস কাঠামোর এত কম তথ্য আবেদন পাওয়া যায়। এটি ডেটাবেসের অন্তর্নিহিত কাঠামো বুঝতে এবং উপযুক্ত আক্রমণগুলি ডিজাইন করা কঠিন করে তোলে।
  3. তারা শুধুমাত্র পরামিতি গ্রহণ, তাই পরামিতি প্রশ্নের সুবিধার আছে। অবশ্যই - IMO আপনাকে এখনও আপনার ইনপুটটি স্যানিটাইজ করতে হবে - বিশেষত যদি আপনি সঞ্চিত পদ্ধতির ভিতরে গতিশীল SQL ব্যবহার করছেন।

অসুবিধা হয় -

  1. তারা (সংরক্ষিত পদ্ধতি) বজায় রাখা খুব কঠিন এবং খুব দ্রুত বৃদ্ধি করতে ঝোঁক। এই তাদের একটি সমস্যা পরিচালনা করে তোলে।
  2. তারা গতিশীল প্রশ্নের জন্য খুব উপযুক্ত নয় - যদি তারা প্যারামিটার হিসাবে গতিশীল কোড গ্রহণ করতে নির্মিত হয় তবে অনেকগুলি সুবিধা নেতিবাচক হয়।

যদি সম্ভব হয়, আপনার পরামিতি ধরনের নিক্ষেপ। কিন্তু এটি int, bool, এবং float মত সহজ ধরনের শুধুমাত্র কাজ করছে।

$unsafe_variable = $_POST['user_id'];

$safe_variable = (int)$unsafe_variable ;

mysqli_query($conn, "INSERT INTO table (column) VALUES ('" . $safe_variable . "')");




sql-injection