এবং ন্যূনতম সাহায্য আপনার বিকাশ ফাংশন থেকে হবে. পিএইচপি: \"উদ্ধৃতি\"। মাইএসকিউএল কোয়েরি লেখা, স্ল্যাশ করা, উদ্ধৃতি ত্যাগ করা কোডে অনুসন্ধান করা

উদ্ধৃতি স্ট্রিং (11)

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

$query = "সারণীতে ঢোকান (id, col1, col2) VALUES (NULL, val1, val2)";

এছাড়াও, উপরের উদাহরণে, বিবেচনা করুন যে "টেবিল," "col[n]," এবং "val[n]" ভেরিয়েবল হতে পারে।

এই জন্য মান কি? তুমি কি করছো?

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

উত্তর

এখন ধরুন আপনি MySQL ক্যোয়ারীতে সরাসরি পোস্ট ভেরিয়েবল ব্যবহার করছেন তাহলে এটি এভাবে ব্যবহার করুন:

$query = "`টেবিল` (`id`, `name`, `email`) VALUES (" ".$_POST["id"]।" "," ".$_POST["name"] তে সন্নিবেশ করুন।" ", " ".$_POST["ইমেইল"].." ")";

মাইএসকিউএলে পিএইচপি ভেরিয়েবল ব্যবহার করার জন্য এটি সর্বোত্তম অনুশীলন।

প্রধানত Mysql-এ, এই ধরনের শনাক্তকারী ব্যবহার করা হয় ` , " , " এবং () প্রশ্নে।

    " বা " মান হিসেবে একটি স্ট্রিং অন্তর্ভুক্ত করতে ব্যবহার করুন "01/26/2014 00:00:00" বা "01/26/2014 00:00:00"। এই শনাক্তকারীটি শুধুমাত্র "01/26/2014 00:00:00" স্ট্রিং ফাংশনের জন্য ব্যবহৃত হয়, যেমন now() বা sum ,max।

    ` একটি টেবিল বা টেবিল টেবিল অন্তর্ভুক্ত করতে ব্যবহার করুন, যেমন table_name থেকে column_name নির্বাচন করুন যেখানে id = "2"

    () শুধুমাত্র একটি প্রশ্নের অংশগুলিকে সহজভাবে আবদ্ধ করতে ব্যবহৃত হয়, উদাহরণস্বরূপ table_name থেকে column_name নির্বাচন করুন যেখানে (id = "2" এবং লিঙ্গ = "পুরুষ") বা নাম = "রাকেশ।

সমস্ত (ভালভাবে ব্যাখ্যা করা) উত্তরগুলি ছাড়াও, নীচে উল্লেখ করা কিছুই ছিল না এবং আমি প্রায়ই এই প্রশ্নোত্তরগুলিতে আসি।

সংক্ষেপে; মাইএসকিউএল মনে করে আপনি গণিত করতে চানআপনার নিজের টেবিল/কলামে এবং হাইফেন যেমন "ইমেল" ইমেইল হিসাবে ব্যাখ্যা করুন।

দায়িত্ব অস্বীকার।তাই আমি ভেবেছিলাম যে আমি এটিকে "FYI" উত্তর হিসাবে যুক্ত করব যারা ডাটাবেসের সাথে কাজ করার জন্য সম্পূর্ণ নতুন, এবং যারা ইতিমধ্যে বর্ণিত প্রযুক্তিগত শর্তাদি বুঝতে পারেন না।

(আপনার প্রশ্নের SQL প্রকৃতি সম্পর্কে উপরে ভাল উত্তর আছে, কিন্তু আপনি PHP এ নতুন হলে এটি প্রাসঙ্গিক হতে পারে।)

এটা মনে রাখা গুরুত্বপূর্ণ হতে পারে যে পিএইচপি একক এবং দ্বিগুণ উদ্ধৃতিগুলিকে ভিন্নভাবে ব্যবহার করে...

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

$foo = "বার"; প্রতিধ্বনি "একটি $foo আছে"; // একটি $foo প্রতিধ্বনি আছে "একটি $foo আছে"; // একটি বার প্রতিধ্বনি আছে `ls -l`; // ... একটি ডিরেক্টরি তালিকা

যদি কল টেবিল এবং মানগুলি ভেরিয়েবল হয়, তবে দুটি উপায় রয়েছে:

ডবল উদ্ধৃতি "" সহ সম্পূর্ণ প্রশ্ন হল:

$query = "$table_name (id, $col1, $col2) মানগুলিতে সন্নিবেশ করুন (NULL, "$val1", "$val2")";

$query = "ঢোকান ".$table_name।" (id, ".$col1.", ".$col2.") VALUES (NULL, "".$val1.", "".$val2."" ) ";

একক উদ্ধৃতি সহ "" :

$query = "ঢোকান ".$table_name।" (id, ".$col1.", ".$col2.") VALUES (NULL, ".$val1.", ".$val2.")";

যখন কলাম/মূল্যের নাম একটি MySQL সংরক্ষিত কীওয়ার্ডের মতো হয় তখন ব্যাকটিক্স ব্যবহার করুন।

বিঃদ্রঃ.আপনি যদি টেবিলের নামের সাথে একটি কলামের নাম উল্লেখ করেন, তাহলে ব্যাকটিক্স ব্যবহার করুন:

`টেবিল_নাম` `কলাম_নাম`<- Примечание: исключить. из задних клещей.

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

স্ট্রিং মানগুলির জন্য একক উদ্ধৃতি ব্যবহার করা উচিত, যেমন VALUES() তালিকায়৷ স্ট্রিং মানগুলির জন্যও ডাবল কোট MySQL দ্বারা সমর্থিত, কিন্তু একক উদ্ধৃতিগুলি অন্যান্য RDBMS-এর দ্বারা ব্যাপকভাবে গৃহীত হয়, তাই ডাবল উদ্ধৃতিগুলির পরিবর্তে একক উদ্ধৃতি ব্যবহার করা একটি ভাল ধারণা।

MySQL এছাড়াও DATE এবং DATETIME আক্ষরিক মানগুলিকে স্ট্রিং হিসাবে একক-উদ্ধৃত করা আশা করে, যেমন "2001-01-01 00:00:00"। আরও তথ্যের জন্য, তারিখ এবং সময় সাহিত্য ডকুমেন্টেশন দেখুন, বিশেষ করে হাইফেন ব্যবহারের বিকল্প - তারিখের স্ট্রিং-এ একটি সেগমেন্ট বিভাজক হিসাবে।

তাই আপনার উদাহরণ ব্যবহার করে, আমি পিএইচপি স্ট্রিংটি ডাবল কাস্ট করব এবং "val1", "val2" মানগুলির জন্য একক উদ্ধৃতি ব্যবহার করব। NULL একটি MySQL কীওয়ার্ড এবং একটি অ-মান এবং তাই ব্যবহার করা হয় না।

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

RDBMS-সম্পর্কিত ফাংশনগুলি (যেমন MySQL-এ NOW() উদ্ধৃত করা উচিত নয়, যদিও তাদের আর্গুমেন্টগুলি একই নিয়ম বা উদ্ধৃতি নিয়মের অধীন ইতিমধ্যে উল্লিখিত৷

ব্যাকটিক(`) টেবিল ও কলাম ┬──── ┬──┬───────┐ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ que = `টেবিল` (`id`, `col1`, `col2`, `date`, `updated`) VALUES (NULL, "val1", "val2", "2001-01-01", NOW()) এর মধ্যে ঢোকান"; উদ্ধৃতিহীন কীওয়ার্ড ─────┴┴┴┘ │ │ │ │ │ │ ││││ │ │││││ একক-উদ্ধৃত (") ──── ──── স্ট্রিং ─ ───┴── ┴────┘ │ │ │││││ একক-উদ্ধৃত (") তারিখ ──────────────────────── ─ ───┴── উদ্ধৃতিহীন ফাংশন ────────────────────────────────────────────── ──┴┴┴┴┘

পরিবর্তনশীল ইন্টারপোলেশন

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

// কিছু ভেরিয়েবল প্রতিস্থাপনের সাথে একই জিনিস // এখানে, একটি পরিবর্তনশীল টেবিলের নাম $table ব্যাকটিক-উদ্ধৃত, এবং ভ্যারিয়েবল // VALUES তালিকায় একক-উদ্ধৃত $query = "INSERT INTO `$টেবিল`(`id`, `col1`, `col2`, `date`) মান (NULL, "$val1", "$val2", "$ তারিখ")";

প্রস্তুত বিবৃতি

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

// নামযুক্ত প্যারামিটার সহ PDO উদাহরণ, unquoted $query = " INSERT INTO `table` (`id`, `col1`, `col2`, `date`) VALUES (:id, :col1, :col2, :date)" ; // MySQLi এর সাথে উদাহরণ? parameters, unquoted $query = "ঢোকান `টেবিল` (`id`, `col1`, `col2`, `date`) VALUES (?, ?, ?, ?)";

যে চিহ্নগুলি শনাক্তকারীতে একটি পিছনের রেফারেন্স প্রদান করে:

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

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

বিপরীত অনুমান সম্পর্কে আরও জানতে এই উত্তরটি দেখুন।

এখন ডাবল কোটস এবং একক উদ্ধৃতি সম্পর্কে (মাইকেল ইতিমধ্যে এটি উল্লেখ করেছেন)।

কিন্তু মান নির্ধারণ করতে, আপনাকে একক বা ডবল উদ্ধৃতি ব্যবহার করতে হবে। আরেকটি উদাহরণ দেখা যাক।

`টেবিলনাম` (`আইডি, `শিরোনাম`) মান (শূন্য, শিরোনাম1) ঢোকান;

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

INSERT INTO `tablename` (`id, `title`) VALUES (NULL, "title1");

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

$query = "সারণীতে সন্নিবেশ করুন (`id`, `col1`, `col2`) মান (NULL, "$val1", "$val2"");

এখন, পিএইচপি-তে ডবল কোট ব্যবহার করে, আপনি ভেরিয়েবল $val1 এবং $val2-কে তাদের মান ব্যবহার করতে দেবেন, এইভাবে একটি বৈধ কোয়েরি তৈরি করা হবে। পছন্দ

$val1 = "আমার মান 1"; $val2 = "আমার মান 2"; $query = "সারণীতে সন্নিবেশ করুন (`id`, `col1`, `col2`) মান (NULL, "$val1", "$val2"");

`টেবিল` (`id`, `col1`, `col2`) VALUES (NULL, "আমার মান 1", "আমার মান 2") ঢোকান

এখানে অনেক সহায়ক উত্তর ছিল, সাধারণত দুটি পয়েন্টে শেষ হয়।

  1. ব্যাকটিক্স (`) শনাক্তকারীর নামের চারপাশে ব্যবহার করা হয়।
  2. একক উদ্ধৃতি (") মানগুলির চারপাশে ব্যবহৃত হয়।

এবং যেমন @ মাইকেল বারকোস্কি বলেছেন

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

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

123E10 একটি বৈধ শনাক্তকারীর নাম, তবে এটি একটি বৈধ পূর্ণসংখ্যা আক্ষরিক।

[বিস্তারিত না গিয়ে আপনি কীভাবে এমন একটি আইডি নাম পাবেন] ধরা যাক আমি 123456e6 নামে একটি অস্থায়ী টেবিল তৈরি করতে চাই।

ব্যাকটিক্সে কোন ত্রুটি নেই।

DB > অস্থায়ী টেবিল তৈরি করুন `123456e6` (`id` char (8)); কোয়েরি ঠিক আছে, 0টি সারি প্রভাবিত হয়েছে (0.03 সেকেন্ড)

আপনি কলব্যাক ব্যবহার না করলে ত্রুটি৷

DB > অস্থায়ী টেবিল তৈরি করুন 123451e6 (`id` char (8)); ERROR 1064 (42000): আপনার SQL সিনট্যাক্সে একটি ত্রুটি আছে; লাইন 1 এ "123451e6 (`id` char (8))" এর কাছাকাছি ব্যবহার করার জন্য সঠিক সিনট্যাক্সের জন্য আপনার MariaDB সার্ভার সংস্করণের সাথে সামঞ্জস্যপূর্ণ ম্যানুয়ালটি দেখুন

যাইহোক, 123451a6 একটি সূক্ষ্ম আইডি নাম (ব্যাকটিক্স ছাড়া)।

DB > অস্থায়ী টেবিল তৈরি করুন 123451a6 (`id` char (8)); কোয়েরি ঠিক আছে, 0টি সারি প্রভাবিত হয়েছে (0.03 সেকেন্ড)

এটি সম্পূর্ণ কারণ 1234156e6ও একটি সূচকীয় সংখ্যা।

স্ট্রিং মানগুলির জন্য একক উদ্ধৃতি ব্যবহার করা উচিত, যেমন VALUES() তালিকায়৷

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

পিএইচপি এবং মাইএসকিউএল-এর সাথে মিলিত হলে, ডবল কোট এবং একক উদ্ধৃতিগুলি ক্যোয়ারী লেখার সময়কে ব্যাপকভাবে সরল করে।

মাইএসকিউএল-এ দুই ধরনের উদ্ধৃতি রয়েছে:

  1. " স্ট্রিং লিটারেল অন্তর্ভুক্ত করতে
  2. ` টেবিল এবং কলামের নামের মতো শনাক্তকারী অন্তর্ভুক্ত করতে

এবং তারপর আছে "এটি একটি বিশেষ ক্ষেত্রে। এটির জন্য ব্যবহার করা যেতে পারে একসার্ভারের sql_mode এর উপর নির্ভর করে একটি সময়ে উপরের লক্ষ্যগুলির মধ্যে:

  1. ডিফল্টস্ট্রিং লিটারেল নেস্ট করতে "অক্ষর" ব্যবহার করা যেতে পারে "
  2. ANSI_QUOTES মোডে " চিহ্নটি সনাক্তকারী অন্তর্ভুক্ত করতে ব্যবহার করা যেতে পারে, ANSI_QUOTES

নিম্নলিখিত ক্যোয়ারী SQL মোডের উপর নির্ভর করে বিভিন্ন ফলাফল (বা ত্রুটি) তৈরি করবে:

টেবিল থেকে "কলাম" নির্বাচন করুন যেখানে foo = "বার"

ANSI_QUOTES নিষ্ক্রিয়

প্রশ্নটি স্ট্রিং আক্ষরিক "কলাম" নির্বাচন করবে যেখানে কলাম foo স্ট্রিং "বার" এর সমান

ANSI_QUOTES সক্ষম হয়েছে৷

কোয়েরি কলাম কলাম নির্বাচন করবে যেখানে কলাম foo কলামের সমান

কখন ব্যবহার করতে হবে

  • আমি আপনাকে " ব্যবহার করা এড়াতে পরামর্শ দিচ্ছি যাতে আপনার কোড SQL মোডের উপর নির্ভর না করে
  • সর্বদা শনাক্তকারী অন্তর্ভুক্ত করুন কারণ এটি একটি ভাল অভ্যাস (SO তে বেশ কয়েকটি প্রশ্ন এটি নিয়ে আলোচনা করুন)

" " এবং " " ব্যবহারের মধ্যে একটি স্পষ্ট পার্থক্য রয়েছে।

যখন " " সর্বত্র ব্যবহৃত হয়, তখন কোন "রূপান্তর বা অনুবাদ" থাকে না। এটা যেমন আছে ছাপা হয়.

"" দিয়ে, এটিকে ঘিরে থাকা যাই হোক না কেন তার মান "অনুবাদিত বা রূপান্তরিত" হয়।

অনুবাদ/রূপান্তর বলতে আমি যা বোঝাতে চাচ্ছি তা হল: একক উদ্ধৃতির মধ্যে থাকা কিছু তাদের মানগুলিতে "অনুবাদিত" হবে না। তারা গৃহীত হবে কারণ তারা কোট ভিতরে আছে. উদাহরণ: a=23 , তারপর echo "$a" স্ট্যান্ডার্ড আউটপুটে $a তৈরি করবে। যখন ইকো "$a" স্ট্যান্ডার্ড আউটপুটে 23 তৈরি করবে।

(PHP 4 >= 4.3.0, PHP 5)

mysql_real_escape_string — এসকিউএল স্টেটমেন্টে ব্যবহারের জন্য একটি স্ট্রিং-এ বিশেষ অক্ষরগুলিকে এস্কেপ করে

বর্ণনা

mysql_real_escape_string (স্ট্রিং $unescaped_string [, সম্পদ $link_identifier = NULL]): স্ট্রিং

সংযোগের বর্তমান অক্ষর সেটটিকে বিবেচনা করে unescaped_string-এ বিশেষ অক্ষরগুলিকে এস্কেপ করে যাতে এটি একটি এ স্থাপন করা নিরাপদ হয় mysql_query(). যদি বাইনারি ডেটা সন্নিবেশ করতে হয় তবে এই ফাংশনটি ব্যবহার করতে হবে।

mysql_real_escape_string() মাইএসকিউএল-এর লাইব্রেরি ফাংশন mysql_real_escape_string কল করে, যা নিম্নলিখিত অক্ষরগুলিতে ব্যাকস্ল্যাশগুলিকে প্রিপেন্ড করে: \x00, \n, \r, \ , " , " এবং \x1a.

MySQL-এ একটি ক্যোয়ারী পাঠানোর আগে ডেটা নিরাপদ করতে এই ফাংশনটি সর্বদা (কিছু ব্যতিক্রম ছাড়া) ব্যবহার করা উচিত।

সতর্ক করা

নিরাপত্তা: ডিফল্ট অক্ষর সেট

অক্ষর সেটটি অবশ্যই সার্ভার স্তরে বা API ফাংশন সহ সেট করতে হবে mysql_set_charset()এটি প্রভাবিত করার জন্য mysql_real_escape_string() . আরও তথ্যের জন্য অক্ষর সেটের ধারণা বিভাগটি দেখুন।

পরামিতি

unescaped_string

যে স্ট্রিং এস্কেপ করা হবে.

লিঙ্ক_আইডেন্টিফায়ার

MySQL সংযোগ। যদি লিঙ্ক শনাক্তকারী নির্দিষ্ট না করা হয়, শেষ লিঙ্ক দ্বারা খোলা mysql_connect()অনুমান করা হচ্ছে. যদি এই ধরনের কোনো লিঙ্ক পাওয়া না যায়, তাহলে এটি একটি তৈরি করার চেষ্টা করবে mysql_connect()কোনো যুক্তি ছাড়াই ডাকা হয়েছিল। যদি কোন সংযোগ পাওয়া যায় বা প্রতিষ্ঠিত না হয়, একটি E_WARNINGস্তর ত্রুটি উত্পন্ন হয়.

রিটার্ন মান

পালিয়ে যাওয়া স্ট্রিং ফেরত দেয়, বা মিথ্যাত্রুটির উপর

ত্রুটি/ব্যতিক্রম

একটি MySQL সংযোগ ছাড়াই এই ফাংশনটি কার্যকর করাও নির্গত হবে E_WARNINGস্তরের পিএইচপি ত্রুটি। শুধুমাত্র একটি বৈধ MySQL সংযোগের সাথে এই ফাংশনটি চালান।

উদাহরণ

উদাহরণ #1 সহজ mysql_real_escape_string() উদাহরণ

// সংযোগ করুন
$link = mysql_connect("mysql_host" , "mysql_user" , "mysql_password")
অথবা ডাই(mysql_error());

//প্রশ্ন
$query = sprintf ( "নির্বাচন করুন * ব্যবহারকারীদের থেকে WHERE user="%s" এবং password="%s"",
mysql_real_escape_string($user),
mysql_real_escape_string($password));
?>

উদাহরণ #2 mysql_real_escape_string() একটি সংযোগ উদাহরণ প্রয়োজন

এই উদাহরণটি দেখায় যে এই ফাংশনটি কল করার সময় যদি একটি MySQL সংযোগ উপস্থিত না থাকে তাহলে কি হবে।

উপরের উদাহরণটি অনুরূপ কিছু আউটপুট করবে:

সতর্কীকরণ: mysql_real_escape_string(): লাইন 5-এ /this/test/script.php-এ এমন কোনও ফাইল বা ডিরেক্টরি নেই সতর্কীকরণ: mysql_real_escape_string(): লাইন 5-এ /this/test/script.php-এ সার্ভারের একটি লিঙ্ক স্থাপন করা যায়নি bool(false) স্ট্রিং(41) "SELECT * FROM actors WHERE last_name = """

উদাহরণ #3 একটি উদাহরণ এসকিউএল ইনজেকশন আক্রমণ

// আমরা $_POST["পাসওয়ার্ড"] চেক করিনি, এটি ব্যবহারকারীর যা ইচ্ছা তা হতে পারে! উদাহরণস্বরূপ:
$_POST [ "username" ] = "aidan" ;
$_POST [ "পাসওয়ার্ড" ] = "" বা ""="" ;

// কোন মিল ব্যবহারকারী আছে কিনা তা পরীক্ষা করার জন্য ডাটাবেস অনুসন্ধান করুন
$query = ( $_POST [ "ব্যবহারকারীর নাম" ]) " এবং password=" ( $_POST [ "পাসওয়ার্ড" ]) "" ;
mysql_query($query);

// এর মানে MySQL এ পাঠানো প্রশ্নটি হবে:
echo $query;
?>

প্রশ্নটি MySQL এ পাঠানো হয়েছে:

এটি যে কেউ বৈধ পাসওয়ার্ড ছাড়াই লগ ইন করার অনুমতি দেবে।

মন্তব্য

ব্যবহারের আগে একটি MySQL সংযোগ প্রয়োজন৷ mysql_real_escape_string() অন্যথায় স্তরের একটি ত্রুটি E_WARNINGউৎপন্ন হয়, এবং মিথ্যাফেরত দেওয়া হয়। যদি link_identifier সংজ্ঞায়িত না হয়, শেষ MySQL সংযোগ ব্যবহার করা হয়।

বিঃদ্রঃ: mysql_real_escape_string() পালিয়ে যায় না % এবং _ . এইগুলি মাইএসকিউএল-এর সাথে একত্রিত হলে ওয়াইল্ডকার্ড লাইক, প্রদান, বা প্রত্যাহার করুন.

8 বছর আগে

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

ফাংশন mysql_escape_mimic ($inp) (
যদি(is_array($inp))
রিটার্ন অ্যারে_ম্যাপ (__METHOD__ , $inp);

যদি(!খালি($inp) && is_string ($inp )) (
str_replace (অ্যারে("\\" , "\0" , "\n" , "\r" , """ , """ , "\x1a" ), অ্যারে("\\\\" , "\) ফেরত দিন \0" , "\\n" , "\\r" , "\\"" , "\\"" , "\\Z" ), $inp );
}

$inp ফেরত দিন;
}
?>

13 বছর আগে

মনে রাখবেন যে mysql_real_escape_string ডকুমেন্টেশনে উল্লিখিত হিসাবে \x00, \n, \r, এবং \x1a তে ব্যাকস্ল্যাশগুলিকে প্রিপেন্ড করে না, কিন্তু আসলে অক্ষরটিকে প্রশ্নের জন্য একটি MySQL গ্রহণযোগ্য উপস্থাপনা দিয়ে প্রতিস্থাপন করে (উদাহরণস্বরূপ \n "\ এর সাথে প্রতিস্থাপিত হয়) n" লিটারাল)। (\, ", এবং " ডকুমেন্টেড হিসাবে পালানো হয়েছে) এটি আপনার এই ফাংশনটি কীভাবে ব্যবহার করা উচিত তা পরিবর্তন করে না, তবে আমি মনে করি এটি জেনে রাখা ভাল।

6 বছর আগে

পালানোর কোন আলোচনাই সকলকে না বলে সম্পূর্ণ হয় না যে ব্যাখ্যা করা কোড তৈরি করতে আপনার কখনই বাহ্যিক ইনপুট ব্যবহার করা উচিত নয়। এটি এসকিউএল স্টেটমেন্টের জন্য যায়, অথবা আপনি যেকোন ধরনের "eval" ফাংশনকে কল করবেন।

সুতরাং, এই ভয়ঙ্করভাবে ভাঙা ফাংশন ব্যবহার করার পরিবর্তে, পরিবর্তে প্যারামেট্রিক প্রস্তুত বিবৃতি ব্যবহার করুন।

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

ওটার মানে কি?

এর মানে এই মত একটি SQL বিবৃতি নির্মাণের পরিবর্তে:

"X (A) মানের মধ্যে ঢোকান(."$_POST["a"]।)"

এইরকম দেখতে একটি বিবৃতি কার্যকর করতে আপনার mysqli's ready() ফাংশন () ব্যবহার করা উচিত:

"X (A) মানের মধ্যে সন্নিবেশ করান(?)"

দ্রষ্টব্য: এর মানে এই নয় যে আপনি কখনই গতিশীল SQL স্টেটমেন্ট তৈরি করবেন না। এর মানে হল যে সেই স্টেটমেন্টগুলি তৈরি করতে আপনার কখনই ব্যবহারকারী-প্রদত্ত ডেটা ব্যবহার করা উচিত নয়। ব্যবহারকারী-প্রদত্ত যে কোনও ডেটা পরামিতি হিসাবে বিবৃতিতে পাস করা উচিত। প্রস্তুত করা হয়েছে।

সুতরাং, উদাহরণস্বরূপ, আপনি যদি একটি ছোট কাঠামো তৈরি করেন এবং অনুরোধ URI-এর উপর ভিত্তি করে একটি টেবিলে একটি সন্নিবেশ করতে চান, তাহলে $_SERVER["REQUEST_URI"] মান (অথবা যেকোনো) গ্রহণ না করাই আপনার সর্বোত্তম স্বার্থে এটির অংশ) এবং সরাসরি এটিকে আপনার প্রশ্নের সাথে সংযুক্ত করুন। পরিবর্তে, আপনি যে $_SERVER["REQUEST_URI"] মান চান তার অংশটি পার্স আউট করুন এবং এটিকে কোনো ধরনের ফাংশন বা সহযোগী অ্যারের মাধ্যমে নন-ইউজারের সাথে ম্যাপ করুন। প্রদত্ত মান৷ যদি ম্যাপিং কোনও মান তৈরি না করে, আপনি জানেন যে ব্যবহারকারীর প্রদত্ত ডেটাতে কিছু ভুল হয়েছে৷

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

এছাড়াও, প্যারামেট্রিক প্রস্তুত বিবৃতি ব্যবহার করার সময়ও, ব্যবহারকারীদের দ্বারা প্রদত্ত ডেটার কিছু ধরণের বৈধতা আপনার করা উচিত। এর কারণ হল যে ব্যবহারকারী-প্রদত্ত ডেটা প্রায়শই কিছু তৈরি করা HTML-এর অংশ হয়ে যায় এবং আপনি নিশ্চিত করতে চান যে ব্যবহারকারীর প্রদত্ত ডেটা ব্রাউজারে নিরাপত্তা সমস্যা সৃষ্টি করবে না।

9 বছর আগে

এসকিউএল ইনজেকশনের উদাহরণ #2-এ একটি মজার কৌতুহল রয়েছে: AND OR এর উপর অগ্রাধিকার নেয়, তাই ইনজেকশন করা প্রশ্নটি আসলে WHERE (user="aidan" AND password="") OR ""="" হিসাবে কার্যকর হয়, তাই পরিবর্তে একটি নির্বিচারে ব্যবহারকারীর নামের সাথে সম্পর্কিত একটি ডাটাবেস রেকর্ড ফেরত দেওয়ার ক্ষেত্রে (এই ক্ষেত্রে "এইডান"), এটি প্রকৃতপক্ষে সমস্ত ডেটাবেস রেকর্ড ফেরত দেবে৷ কোনও নির্দিষ্ট ক্রমে নয়৷ তাই একজন আক্রমণকারী যে কোনও অ্যাকাউন্ট হিসাবে লগ ইন করতে সক্ষম হতে পারে, তবে অগত্যা যে কোনও অ্যাকাউন্টে লগ ইন করতে পারে না৷ এটি কোন অ্যাকাউন্টের উপর নিয়ন্ত্রণ করুন।

অবশ্যই একজন আক্রমণের সম্ভাবনাকারী শুধুমাত্র তাদের পরামিতি পরিবর্তন করতে পারে নির্দিষ্ট আগ্রহের ব্যবহারকারীদের লক্ষ্য করার জন্য:

//যেমন আক্রমণকারীর মান
$_POST [ "username" ] = "" ;
$_POST["পাসওয়ার্ড"] = "" বা ব্যবহারকারী = "প্রশাসক" এবং "" = "";

// বিকৃত প্রশ্ন
$query = "নির্বাচন করুন * ব্যবহারকারীদের থেকে WHERE user="$_POST [ ব্যবহারকারীর নাম ] " এবং পাসওয়ার্ড=" $_POST [ পাসওয়ার্ড ] "" ;

echo $query;

// MySQL এ পাঠানো প্রশ্নটি পড়বে:
// নির্বাচন করুন * ব্যবহারকারীদের থেকে WHERE user="" AND password="" বা user="administrator" AND ""="";
// যা কাউকে "প্রশাসক" নামে অ্যাকাউন্টে অ্যাক্সেস পেতে দেয়

?>

1 বছর আগে

@ফিডার
আমি তার নোটটি নিম্নরূপ ব্যাখ্যা করেছি:
$string = "asda\0sd\x1aas\\\\\\\dasd\"asdasd\na\"\"sdasdad";
$array1 = অ্যারে("\\\\\\\\", "\0", "\n", "\r", """, """, "\x1a");
$array2 = অ্যারে("\\\\\\\\\\\\\\\\\", "\\\0", "\\\n", "\\\r", "\\\ " ", "\\\"", "\\\Z");
echo($string);
ইকো(PHP_EOL);
জন্য($i=0; $i যদি ($i==0)
$p = "/(?অন্য
$p = "/(?প্রতিধ্বনি($i);
প্রতিধ্বনি($p);
echo($array2[$i]);
$string = preg_replace($p, $array2[$i], $string);
প্রতিধ্বনি("\t");
echo($string);
ইকো(PHP_EOL);
}
ইকো(PHP_EOL);
echo($string);

২ বছর আগে

নম্ব সাফারিতে স্যামকে উদ্ধৃত করতে

["পলায়ন সংক্রান্ত কোনো আলোচনাই সকলকে না বলে সম্পূর্ণ হয় না যে ব্যাখ্যা করা কোড তৈরি করতে আপনার কখনই বাহ্যিক ইনপুট ব্যবহার করা উচিত নয়। এটি এসকিউএল স্টেটমেন্টের জন্য প্রযোজ্য, অথবা আপনি যেকোন ধরনের "ইভাল" ফাংশন বলতে চান।

সুতরাং, এই ভয়ঙ্করভাবে ভাঙা ফাংশন ব্যবহার করার পরিবর্তে, পরিবর্তে প্যারামেট্রিক প্রস্তুত বিবৃতি ব্যবহার করুন।

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

স্যাম ঠিক বলেছেন.........

যাইহোক, আমি মনে করি না যে সমস্ত স্যানিটাইজিং বন্ধ করা এবং প্যারামেট্রিক প্রস্তুত বিবৃতিতে কাজটি পাস করা বুদ্ধিমান।

একটি নির্দিষ্ট পরিস্থিতিতে কাজ করা একটি নির্দিষ্ট বিকাশকারী সর্বদা বৈধ ইনপুট সম্পর্কে আরও জানবে (সেই প্রসঙ্গে নির্দিষ্ট)।

আপনি যদি একজন ব্যবহারকারীকে এমন একটি মান পাস করতে বলেন যা আপনি ইতিমধ্যেই দিয়েছেন এবং আপনি জানেন যে এই জাতীয় সমস্ত মান AB****** থেকে শুরু হয় এবং স্ট্রিংটি 7 বা 11 দৈর্ঘ্যের হওয়া উচিত তবে অন্য কোনও দৈর্ঘ্যের নয় তবে আপনার কাছে থাকবে একটি ভাল প্রাক-স্যানিটাইজারের ভিত্তি - একটি স্ট্রিংয়ের বিভিন্ন অনুমোদিত দৈর্ঘ্য উত্তরাধিকার ডেটা নির্দেশ করতে পারে।

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

এইভাবে আমার ডিবি নিরাপদ করা অনিরাপদ বিবৃতি দিয়ে আটকে যায় না - এটি কেবল আটকে যায় না যা ভাল।

স্তরগুলিতে নিরাপত্তা - প্রস্তুত বিবৃতি ব্যবহার করার আগে স্যানিটাইজেশন এবং বৈধতা এখনও প্রতিটি পরিস্থিতিতে বিবেচনা করা উচিত।

উপরন্তু যতদূর আমি অফিসিয়াল ডক পড়তে পারি
==============================================

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

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

এটি আমাকে পরামর্শ দেয় যে অভ্যন্তরীণ ক্ষেত্রে বিপদ এড়ানো যায় বিকল্প পরিচালনার মাধ্যমে বাতিলকরণের মাধ্যমে নয়।

এর মানে হল যে একটি বড় প্রকল্প প্রস্তুত করা বিবৃতিতে অসম্পূর্ণ রূপান্তর, একটি সংস্থার বিভিন্ন অংশে লিগ্যাসি কোড বা একে অপরের সাথে কথা বলা সার্ভারগুলি সবই একটি অনাক্রম্য অবস্থান বা পরিস্থিতি থেকে খারাপ খবরটি এমন একটিকে প্রেরণ করতে পারে যা প্রতিরোধী নয়।

যতক্ষণ না অতিরিক্ত ঝুঁকি না নিয়ে স্যানিটাইজেশন দক্ষতার সাথে সম্পাদিত হয় ততক্ষণ আমি ব্যক্তিগতভাবে স্যানিটাইজেশনের নির্দিষ্ট স্তরের সাথে লেগে থাকব এবং তারপর প্রস্তুত বিবৃতিগুলিকে কল করব।


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

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

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

উপরের সবগুলি স্ট্রিং ডেটা এবং তারিখগুলিতে প্রযোজ্য৷ উদ্ধৃতি চিহ্ন দিয়ে সংখ্যাগুলিকে পিছনে না রেখে বা চারপাশে সন্নিবেশ করা যেতে পারে। আপনি যদি এই কাজ করেন তাহলে অগত্যা!ক্যোয়ারীতে ঢোকানোর আগে ডেটাটিকে পছন্দসই প্রকারে জোর করুন, উদাহরণস্বরূপ:
$id = intval ($id);
যাইহোক, সরলতার জন্য (এবং নির্ভরযোগ্যতা), আপনি স্ট্রিংগুলির মতো সংখ্যার সাথে কাজ করতে পারেন (যেহেতু mysql এখনও তাদের পছন্দসই টাইপে রূপান্তর করে)। তদনুসারে, আমরা অনুরোধে ঢোকানো কোনও ডেটা ট্রেস করব এবং এটিকে উদ্ধৃতি চিহ্নে আবদ্ধ করব।

এছাড়াও, আরও একটি নিয়ম রয়েছে - ঐচ্ছিক, তবে ত্রুটিগুলি এড়াতে এটি অনুসরণ করা উচিত:
ক্ষেত্র এবং টেবিলের নাম পিছনের একক উদ্ধৃতিতে আবদ্ধ করা উচিত - "`" (এই চিহ্ন সহ কীটি "1" কী-এর বাম দিকে একটি স্ট্যান্ডার্ড কীবোর্ডে অবস্থিত)। সর্বোপরি, ক্ষেত্রের নামটি mysql-এর সাথে মিলে যেতে পারে। কীওয়ার্ড, কিন্তু যদি আমরা একটি ব্যাক কোট ব্যবহার করি, তাহলে MySQL বুঝবে সবকিছু সঠিক:
`টেবিল` থেকে * নির্বাচন করুন যেখানে `তারিখ` = "2006-04-04"
আপনার এই উদ্ধৃতি চিহ্নগুলির মধ্যে পার্থক্য করা উচিত এবং একটিকে অন্যটির সাথে বিভ্রান্ত করা উচিত নয়। আপনার এটাও মনে রাখা উচিত যে ব্যাকটিকগুলি স্ল্যাশের মাধ্যমে এড়ানো যায় না।

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

এসকিউএল ইনজেকশন হ্যাকার আক্রমণের একটি পদ্ধতি যখন একটি স্ক্রিপ্টে স্থানান্তরিত ডেটা এমনভাবে পরিবর্তিত হয় যাতে এই স্ক্রিপ্টে উত্পন্ন ক্যোয়ারীটি যা উদ্দেশ্যে করা হয়েছিল তার থেকে সম্পূর্ণ আলাদা কিছু করতে শুরু করে।
এই ধরনের আক্রমণ থেকে রক্ষা করার নিয়ম দুটি পয়েন্টে বিভক্ত করা যেতে পারে:
1. ডেটা নিয়ে কাজ করা।
2. ক্যোয়ারী নিয়ন্ত্রণের সাথে কাজ করা।

আমরা উপরে বিস্তারিত প্রথম পয়েন্ট আলোচনা. এটা বলা যেতে পারে যে এটি আসলে একটি প্রতিরক্ষা নয়। একটি ক্যোয়ারীতে ডেটা যোগ করার নিয়মগুলির সাথে সম্মতি নির্ধারণ করা হয়, প্রথমত, SQL SYNTAX এর প্রয়োজনীয়তা দ্বারা। এবং পার্শ্ব প্রতিক্রিয়া হিসাবে, আমাদের হ্যাকিংয়ের বিরুদ্ধে সুরক্ষাও রয়েছে।

দ্বিতীয় পয়েন্টটি অনেক বেশি কঠিন, যেহেতু ডেটার জন্য কোনো একক সার্বজনীন নিয়ম নেই - একটি ব্যাকটিক্স ফিল্ডের নামটিকে হ্যাকার দ্বারা পরিবর্তন করা থেকে রক্ষা করবে না। টেবিলের নাম, SQL স্টেটমেন্ট, LIMIT কমান্ড প্যারামিটার এবং অন্যান্য বিবৃতি রক্ষা করার জন্য উদ্ধৃতি ব্যবহার করা সম্ভব নয়।
অতএব, একটি ক্যোয়ারীতে নিয়ন্ত্রণ উপাদান প্রতিস্থাপন করার সময় মৌলিক নিয়ম হল:
আপনি যদি একটি ক্যোয়ারীতে গতিশীলভাবে SQL স্টেটমেন্ট বা ক্ষেত্র, ডাটাবেস, টেবিলের নাম সন্নিবেশ করতে চান, তাহলে কোন অবস্থাতেই আপনি সরাসরি ক্যোয়ারীতে প্রবেশ করাবেন না।
এই ধরনের সংযোজনের জন্য সমস্ত বিকল্প আপনার স্ক্রিপ্টে অগ্রিম লিখতে হবে এবং ব্যবহারকারী যা লিখেছেন তার উপর ভিত্তি করে নির্বাচন করতে হবে।
উদাহরণস্বরূপ, যদি আপনাকে অপারেটর দ্বারা অর্ডারে একটি ক্ষেত্রের নাম পাস করতে হয়, তাহলে কোনো অবস্থাতেই আপনি সরাসরি এটি প্রতিস্থাপন করবেন না। আমরা প্রথমে এটি পরীক্ষা করতে হবে. উদাহরণস্বরূপ, বৈধ মানগুলির একটি অ্যারে তৈরি করুন এবং এটিকে অনুরোধে প্রতিস্থাপন করুন শুধুমাত্র যদি পাস করা প্যারামিটারটি এই অ্যারেতে উপস্থিত থাকে:
$orders = array("নাম" , "মূল্য" , "qty");
$key = array_search($_GET["sort"], $orders));
$orderby = $orders [ $key ];
$query = ক্রম অনুসারে `টেবিল` থেকে * নির্বাচন করুন$orderby " ;

আমরা ব্যবহারকারীর দ্বারা প্রবেশ করা শব্দের জন্য পূর্ব-বর্ণিত বিকল্পগুলির অ্যারে অনুসন্ধান করি এবং যদি আমরা এটি খুঁজে পাই, আমরা অ্যারের সংশ্লিষ্ট উপাদান নির্বাচন করি। যদি কোনো মিল পাওয়া না যায়, অ্যারের প্রথম উপাদান নির্বাচন করা হবে।
সুতরাং, অনুরোধে যা প্রতিস্থাপিত হয়েছে তা ব্যবহারকারী যা প্রবেশ করেছে তা নয়, তবে আমাদের স্ক্রিপ্টে যা লেখা হয়েছে।
অন্য সব ক্ষেত্রে একই কাজ করা আবশ্যক.
উদাহরণস্বরূপ, যদি WHERE ক্লজটি গতিশীলভাবে তৈরি হয়:
যদি (!empty($_GET [ "price" ])) $where .= "price="" . mysql_real_escape_string ($_GET [ "price" ]). """ ;
$query = "টেবিল থেকে * নির্বাচন করুন যেখানে $কোথায় " ;

আমার পক্ষে এমন একটি ক্ষেত্রে কল্পনা করা কঠিন যেখানে একটি টেবিলের নাম গতিশীলভাবে একটি ক্যোয়ারীতে ঢোকানো যেতে পারে, কিন্তু যদি এটি ঘটে, তবে নামটিও স্ক্রিপ্টে পূর্ব-সংজ্ঞায়িত একটি সেট থেকে সন্নিবেশ করা দরকার।
LIMIT অপারেটরের পরামিতিগুলিকে গাণিতিক ক্রিয়াকলাপ বা intval() ফাংশন ব্যবহার করে একটি পূর্ণসংখ্যার ধরণে বাধ্য করা উচিত।
মনে করবেন না যে এখানে তালিকাভুক্ত উদাহরণগুলি গতিশীল ক্যোয়ারী নির্মাণের জন্য সমস্ত বিকল্পকে নিঃশেষ করে দেয়৷ আপনাকে কেবল নীতিটি বুঝতে হবে এবং এই জাতীয় সমস্ত ক্ষেত্রে এটি প্রয়োগ করতে হবে।

আমার কাজের প্রকৃতির কারণে, আমাকে ওয়েব অ্যাপ্লিকেশনের সোর্স কোডের নিরাপত্তা অডিট করতে হবে।
প্রচুর ওয়েব অ্যাপ্লিকেশন এবং প্রচুর কোড...

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

তো, শুরু করা যাক।

অকেজো চরিত্র পলায়নপর
এসকিউএল ইনজেকশনের জন্য ঝুঁকিপূর্ণ PHP ওয়েব অ্যাপ্লিকেশনের 83% মধ্যে পাওয়া যায়
অক্ষরের জন্য এস্কেপ ফাংশন ব্যবহার করা যেমন
mysql_escape_string
mysql_real_escape_string
যোগ স্ল্যাশ
উদ্ধৃতি চিহ্ন ছাড়া। প্রায়শই এটি নিজেকে সাংখ্যিক প্যারামিটারে প্রকাশ করে (সকল ধরণের *_id)।
উদাহরণ
$sql = "ব্যবহারকারী তালিকা থেকে ব্যবহারকারী নির্বাচন করুন যেখানে userid=".mysql_real_escape_string($_GET["uid"]);

এটি নিরাপদ কোড বলে মনে হচ্ছে, তবে শুধুমাত্র পৃষ্ঠে। আমার অনুশীলনে পিএইচপিতে এসকিউএল ইনজেকশনের সবচেয়ে সাধারণ প্যাটার্নটি এখানে রয়েছে। এই দুর্বলতাকে আক্রমণ করার জন্য, একজন আক্রমণকারীকে আক্রমণ ভেক্টরে " " \x00 \r \n \x1a অক্ষর ব্যবহার করা এড়াতে হবে।
উদাহরণ স্বরূপ:
/index.php?uid=-777 UNION ব্যবহারকারী তালিকা থেকে পাসওয়ার্ড নির্বাচন করুন

কোড অনুসন্ধান করুন
ভাষার শব্দার্থবিদ্যা দ্বারা জটিল। একটি সাধারণ অনুসন্ধানের জন্য আপনি egrep ব্যবহার করতে পারেন:
egrep -Rin "(নির্বাচন|আপডেট | grep -v "[\""]["\"]"

অনুসন্ধান অভিব্যক্তির যুক্তি নিম্নরূপ: ফিল্টারিং ফাংশনের বাম দিকে উদ্ধৃতি অক্ষরগুলির ("", "", "", "") কোন ক্রম নেই এমন সমস্ত লাইন খুঁজুন। পদ্ধতিটি, অবশ্যই, 100% থেকে অনেক দূরে, তবে শব্দার্থগত বিশ্লেষণ করার জন্য একটি নিয়মিত অভিব্যক্তির প্রয়োজন হওয়া অসম্ভব।
তথ্য প্রদর্শন করা সহজ করতে, আপনি কনসোলে রঙে ফাংশনটি হাইলাইট করতে পারেন:
egrep -Rin "(নির্বাচন|আপডেট | grep -v "[\""]["\"]" | egrep --color "(mysql_escape_string|mysql_real_escape_string|addslashes)"

এই ওয়াইল্ডকার্ড দুর্বলতা থেকে রক্ষা করার জন্য, টাইপ কাস্টিং ব্যবহার করা ভাল।
এটি সর্বদা দ্রুত কাজ করে এবং সব ধরনের ফিল্টারিং এবং স্ক্রীনিং এর চেয়ে বেশি নির্ভরযোগ্য।
উপরের উদাহরণের জন্য, প্যাচটি এইরকম হতে পারে:
$sql = "ব্যবহারকারী তালিকা থেকে ব্যবহারকারী নির্বাচন করুন যেখানে userid=".intval($_GET["uid"]);

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

তাই মূলত আমি MySQL এবং PHP এর এলাকায় গভীরভাবে খনন করেছি... বিশেষত ডাটাবেস এবং ফর্ম ইনপুট নিয়ে কাজ করার সময় আমার যে নিরাপত্তা ব্যবস্থা নেওয়া উচিত। এখনও অবধি আমি নিম্নলিখিতগুলিকে অত্যন্ত প্রস্তাবিত বলে পেয়েছি:

  1. প্রস্তুত বিবৃতি
  2. _real_escape_string() ব্যবহার করা হচ্ছে
  3. ম্যাজিক উদ্ধৃতি ব্যবহার না করা কারণ এটি ডাটাবেসগুলিকে বিভ্রান্ত করে এবং আপনাকে "আপনি এটিকে কল করেননি..." এর মতো জিনিসগুলি প্রদান করে।

এই সব মহান এবং আমি এটি উপর নজর রাখছি. যাইহোক, আমি ভাবছিলাম ডলার চিহ্ন [$], শতাংশ চিহ্ন [%], এবং সম্ভবত অন্যদের মতো অক্ষরগুলি এড়ানো উচিত কিনা। প্রশ্ন সম্ভবত একটি PHP পরিবর্তনশীল হিসাবে ডলার চিহ্ন ব্যাখ্যা করতে পারে? আমি শুনেছি LIKE সিনট্যাক্স সম্পর্কে কি % প্রতীক বা এমনকি একটি ওয়াইল্ডকার্ড ব্যবহার করে? প্রস্তুত বিবৃতিগুলি প্রযুক্তিগতভাবে এই সমস্তটির যত্ন নেওয়া উচিত, তবে আমি কেবল নিরাপদে থাকতে চেয়েছিলাম এবং নিশ্চিত করতে চেয়েছিলাম যে আমি সবকিছু সঠিকভাবে কভার করেছি। যেসব ক্ষেত্রে আমি প্রস্তুত বিবৃতি ব্যবহার করতে ভুলে যাই বা কেবল তাদের অবহেলা করি, আমি আশা করেছিলাম যে প্রতিরক্ষার এই দ্বিতীয় লাইনটি আমাকে বলতে পারে যে আমি মাথা ঘোরা থেকে মুক্তি পেতে পারি।

পালানোর জন্য আমি বর্তমানে যা ব্যবহার করছি তা এখানে:

ফাংশন এস্কেপ($connection, $data)( $new_data = trim($data); $new_data = i_real_escape_string($connection, $new_data); $new_data = addcslashes($new_data, "%_$"); $new_data = htmlspecial ($new_data, ENT_NOQUOTES); $new_data ফেরত দিন; )

তাহলে এটা কি সঠিক? আমি কি ভয়ানক ভুল কিছু করছি? দয়া করে মনে রাখবেন যে ডাটাবেস ডেটা ফেরত দেওয়ার সময় আমাকে $,% এবং _ অক্ষরের আগে ব্যাকস্ল্যাশগুলি সরিয়ে ফেলতে হবে।

আমি কি ভয়ানক ভুল কিছু করছি?

প্রথমে আপনার গবেষণা সম্পর্কে।

প্রস্তুত বিবৃতি - একমাত্রবিস্ময়কর জিনিস আপনি খুঁজে পেয়েছেন।

যদিও mysqli_real_escape_string ব্যবহার করে (অনুমান করা হচ্ছে আপনি প্রস্তুত বিবৃতি ব্যবহার করছেন) অকেজো এবং ক্ষতিকর(একটি ফলাফল তৈরি করা যা আপনি নিজেই উল্লেখ করেছেন: "আপনি ডাকছেন না...")।

এবং ম্যাজিক কোটগুলি অনেক আগেই ভাষা থেকে মুছে ফেলা হয়েছে - এইভাবে সত্যিই কিছু মূল্যবান নয়।

সুতরাং এমনকি আপনার প্রাথমিক প্রাঙ্গনে অধিকাংশ স্পষ্টভাবে ভুল.

এখন আপনার প্রশ্নে।

প্রশ্ন সম্ভবত একটি PHP পরিবর্তনশীল হিসাবে ডলার চিহ্ন ব্যাখ্যা করতে পারে?

আমি শুনেছি LIKE সিনট্যাক্স সম্পর্কে কি % প্রতীক বা এমনকি একটি ওয়াইল্ডকার্ড ব্যবহার করে?

হ্যা। তুমি সঠিক শুনেছ। LIKE অপারেটরের সঠিক উদ্দেশ্য হল একটি প্যাটার্ন অনুসন্ধান করা। এই অক্ষরগুলিকে LIKE-এ নিষ্ক্রিয় করা সামান্যতম অর্থপূর্ণ হবে না।

প্রতিবার আপনি LIKE অপারেটর ব্যবহার করতে যাচ্ছেন, আপনাকে অবশ্যই সিদ্ধান্ত নিতে হবে কোন নির্দিষ্ট অক্ষরটি ব্যবহার করতে হবে এবং কোনটি অননুমোদিত হবে। আপনি একটি এককালীন সমাধান ব্যবহার করতে পারবেন না। উল্লেখ করার মতো নয় যে অন্যান্য সমস্ত mysql মিথস্ক্রিয়াতে % চিহ্নের কোন বিশেষ অর্থ নেই।

প্রস্তুত বিবৃতি প্রযুক্তিগতভাবে এই সব যত্ন নেওয়া উচিত

প্রস্তুত বিবৃতি $ বা % চিহ্নের সাথে কোন সম্পর্ক নেই। প্রস্তুত বিবৃতিগুলি এসকিউএল ইনজেকশনকে নির্দেশ করে, কিন্তু কোন অক্ষর এটি ঘটাতে পারে না (আপনি "ইনজেকশন" কে সঠিকভাবে ব্যবহৃত LIKE অপারেটর বলতে পারেন না, আপনি কি পারেন?)।

অবশেষে, সবচেয়ে খারাপ অংশে।

যদি আপনি প্রস্তুত বিবৃতি ব্যবহার করতে ভুলে যান বা সেগুলি অনুসরণ করতে অবহেলা করেন,

কিছুই আপনাকে রক্ষা করবে না।

এবং ন্যূনতম সাহায্য আপনার বিকাশ ফাংশন থেকে হবে.

সারসংক্ষেপ।

  1. এই বৈশিষ্ট্য পরিত্রাণ পান.
  2. ব্যবহার করুন ফিলার*ক্যোয়ারীতে প্রতিটি পৃথক ভেরিয়েবলের প্রতিনিধিত্ব করতে।
  3. এস্কেপ % এবং _ অক্ষর ইনপুটে শুধুমাত্র যদি সেগুলি LIKE অপারেটরে ব্যবহার করা হবে এবং আপনি তাদের ব্যাখ্যা করতে চান না।
  4. আউটপুটের জন্য htmlspecialchars() ব্যবহার করুন, mysql ইনপুট নয়।

* প্রস্তুত বিবৃতি পড়ুন যদি এই শব্দটি আপনার কাছে অপরিচিত হয়।

আপনি ডলার চিহ্ন এড়াতে হবে না. MySQL এই অক্ষরটিকে বিশেষভাবে দেখে না, এবং PHP এটিকে শুধুমাত্র সোর্স কোডে চিনতে পারে, স্ট্রিং মানগুলিতে নয় (যদি না আপনি স্ট্রিংটিতে ইভালকে কল করেন তবে এটি একটি সম্পূর্ণ অন্য কীট)।

আপনাকে শুধুমাত্র % এবং _ এড়িয়ে যেতে হবে যদি আপনি LIKE আর্গুমেন্ট হিসাবে ব্যবহারকারীর ইনপুট ব্যবহার করেন এবং আপনি চান না যে ব্যবহারকারী ওয়াইল্ডকার্ড ব্যবহার করতে সক্ষম হন। আপনি একটি অনুসন্ধান ফর্ম প্রক্রিয়াকরণ করা হলে এটি ঘটতে পারে. একটি ডাটাবেসে সংরক্ষণ করার সময় আপনাকে এটি ব্যবহার করতে হবে না।

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

কি ডেটা এবং কিসের জন্য এটি ব্যবহার করা হয় তার উপর নির্ভর করে।

আপনি যদি খুঁজে পান যে PHP-এর ডিফল্ট আউট-অফ-দ্য-বক্স বিবৃতিগুলি খুব বড় এবং জটিল, আমি আপনাকে সরলীকৃত প্রশ্নগুলির একটি ধারণা দিতে গিথুবে উপলব্ধ কিছু ক্লাসের দিকে নজর দেওয়ার পরামর্শ দিই।

এই ক্লাসের সাথে প্রশ্ন সন্নিবেশ করার একটি উদাহরণ

$ডেটা = অ্যারে ("লগইন" => "অ্যাডমিন", "সক্রিয়" => সত্য, "প্রথম নাম" => "জন", "শেষ নাম" => "ডো", "পাসওয়ার্ড" => $db->func( "SHA1(?)", অ্যারে ("secretpassword+salt")), // password = SHA1("secretpassword+salt") "createdAt" => $db->now(), // createdAt = NOW() " মেয়াদ শেষ হয়" => $db->এখন("+1Y") // মেয়াদ শেষ হয় = NOW() + ব্যবধান 1 বছর // সমর্থিত বিরতি [সেকেন্ড], [মি]মিনিট, [ঘণ্টা]ঘণ্টা, [ডি]দিন, [মাস বছর); $id = $db-> সন্নিবেশ ("ব্যবহারকারী", $ডেটা); যদি ($id) echo "ব্যবহারকারী তৈরি করা হয়। id="। $id; অন্যথায় ইকো "সন্নিবেশ ব্যর্থ হয়েছে: "। $db->getLastError();