আমি লাইক কোয়েরি লেখার চেষ্টা করছি।
আমি পড়েছি যে খাঁটি স্ট্রিং কোয়েস নিরাপদ নয়, তবে আমি নিরাপদে LIKE হাশ কোয়েরি কীভাবে লিখতে হয় তা ব্যাখ্যা করার মতো কোনও ডকুমেন্টেশন পাইনি।
এটা কি সম্ভব? এসকিউএল ইঞ্জেকশনের বিরুদ্ধে আমাকে নিজেই রক্ষা করা উচিত?
আমি লাইক কোয়েরি লেখার চেষ্টা করছি।
আমি পড়েছি যে খাঁটি স্ট্রিং কোয়েস নিরাপদ নয়, তবে আমি নিরাপদে LIKE হাশ কোয়েরি কীভাবে লিখতে হয় তা ব্যাখ্যা করার মতো কোনও ডকুমেন্টেশন পাইনি।
এটা কি সম্ভব? এসকিউএল ইঞ্জেকশনের বিরুদ্ধে আমাকে নিজেই রক্ষা করা উচিত?
উত্তর:
আপনার ক্যোয়ারী স্ট্রিংটি সঠিকভাবে স্যানিটাইজড হয়েছে তা নিশ্চিত করতে আপনার অবস্থার বর্ণনা দিতে অ্যারে বা হ্যাশ ক্যোয়ারী বাক্য গঠন ব্যবহার করুন:
Foo.where("bar LIKE ?", "%#{query}%")
বা:
Foo.where("bar LIKE :query", query: "%#{query}%")
যদি সম্ভব যে queryঅন্তর্ভুক্ত হতে পারে %চরিত্র তারপর আপনি নির্বিষ করার প্রয়োজন queryসঙ্গে sanitize_sql_likeপ্রথম:
Foo.where("bar LIKE ?", "%#{sanitize_sql_like(query)}%")
Foo.where("bar LIKE :query", query: "%#{sanitize_sql_like(query)}%")
%স্ট্রিংয়ে পালাতে ব্যর্থ । এটি নির্বিচারে "এসকিউএল ইঞ্জেকশন" নয় তবে এখনও অপ্রত্যাশিতভাবে কাজ করতে পারে।
%কারণ %এটি LIKEসিনট্যাক্সের অংশ । আপনি যদি পরে পালাতে পারেন %তবে ফলাফলটি মূলত একটি সাধারণ =ক্যোয়ারী হবে।
queryভেরিয়েবলের সাথে প্যারাম্যাট্রাইজ করা হয়েছে এবং অনেক ক্ষেত্রে আপনি আক্ষরিক স্ট্রিংটির সাথে queryভেরিয়েবলের সাথে মিল রাখতে চান , queryLIKE metacharacters ব্যবহার করার অনুমতি দেবেন না । আসুন আরও বাস্তবসম্মত উদাহরণটি ধরুন যে% ...%: স্ট্রিংগুলির একটি পথের মতো কাঠামো রয়েছে এবং আপনি মিলের চেষ্টা করেন /users/#{user.name}/tags/%। এখন যদি আমি আমার ব্যবহারকারীর নামটি সাজানোর ব্যবস্থা করি তবে আমি fr%d%পর্যবেক্ষণ করতে fredএবং fridaতার ট্যাগগুলি দেখতে সক্ষম হবো ...
sanitize_sql_like()।
আরেল ব্যবহার করে আপনি এই নিরাপদ এবং বহনযোগ্য কোয়েরি করতে পারেন:
title = Model.arel_table[:title]
Model.where(title.matches("%#{query}%"))
Model.where(title.matches("%#{query}%").not)কাজ করে, উত্পন্ন এসকিউএল কিছুটা বিশ্রী হলেও:WHERE (NOT (`models`.`title` LIKE '%foo%'))
Model.where(title.does_not_match("%#{query}%"))। উত্পন্ন: WHERE (`models`.`title` NOT LIKE '%foo%')
%অবিশ্বস্ত ইনপুট থেকে স্যানিটাইজ করতে ব্যর্থ : >> ActiveRecord::VERSION::STRING => "5.2.3" >> field = Foo.arel_table[:bar] >> Foo.where(field.matches('%')).to_sql => "SELECT `foos`.* FROM `foos` WHERE `foos`.`bar` LIKE '%'"
Model.where.not(title.matches("%#{query}%"))। does_not_matchআইএমও যদিও আরও ভাল পড়া।
যদি কেউ নেস্টেড সংস্থায় অনুসন্ধান অনুসন্ধান করে থাকে তবে এটি চেষ্টা করুন:
Model.joins(:association).where(
Association.arel_table[:attr1].matches("%#{query}%")
)
একাধিক বৈশিষ্ট্যের জন্য এটি ব্যবহার করে দেখুন:
Model.joins(:association).where(
AssociatedModelName.arel_table[:attr1].matches("%#{query}%")
.or(AssociatedModelName.arel_table[:attr2].matches("%#{query}%"))
.or(AssociatedModelName.arel_table[:attr3].matches("%#{query}%"))
)
AssociatedModelNameআপনার মডেল নামটি প্রতিস্থাপন করতে ভুলবেন না