আমি লাইক কোয়েরি লেখার চেষ্টা করছি।
আমি পড়েছি যে খাঁটি স্ট্রিং কোয়েস নিরাপদ নয়, তবে আমি নিরাপদে 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
ভেরিয়েবলের সাথে মিল রাখতে চান , query
LIKE 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
আপনার মডেল নামটি প্রতিস্থাপন করতে ভুলবেন না