অনিরাপদ কোডটি দুর্ঘটনাক্রমে ব্যবহার করা হয়নি তা নিশ্চিত করুন


10

একটি ফাংশন ডেটা f()ব্যবহার করে eval()(বা বিপজ্জনক হিসাবে কিছু) যা আমি তৈরি করি এবং local_fileআমার প্রোগ্রামটি চালিত মেশিনে জমা করেছি:

import local_file

def f(str_to_eval):
    # code....
    # .... 
    eval(str_to_eval)    
    # ....
    # ....    
    return None


a = f(local_file.some_str)

f() আমি যে স্ট্রিং সরবরাহ করি তা আমার নিজস্ব হওয়ায় চালানো নিরাপদ।

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

আমি কীভাবে নিশ্চিত করব যে এই ফাংশনটি ব্যবহারের জন্য অনিরাপদ (নির্দিষ্ট মানদণ্ডটি মেনে না নিলে) আমি কখনই "ভুলতে" পারি না?

দ্রষ্টব্য: eval()বিপজ্জনক এবং সাধারণত নিরাপদ কিছু দ্বারা প্রতিস্থাপন করা যেতে পারে।


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

1
" আমাকে সেই মেশিনে বিশ্বাস করা দরকার যা সেই ফাইলটি সরবরাহ করে " - আপনাকে সর্বদা আপনার কোডটি সম্পাদন করে এমন মেশিনে বিশ্বাস রাখতে হবে trust
বার্গি

"এই স্ট্রিংটি বিভক্ত হয়ে যায়; দয়া করে এখানে দূষিত কোডটি রাখবেন না" এই মন্তব্য করে ফাইলটিতে একটি মন্তব্য করুন?
ব্যবহারকারী 253751

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

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

উত্তর:


26

"নিরাপদ" ইনপুট সাজানোর জন্য একটি প্রকারের সংজ্ঞা দিন। আপনার ফাংশনে f(), যুক্তিটি এই ধরণের আছে বা একটি ত্রুটি নিক্ষেপ করে তা জোর দিয়ে নিন। স্মার্ট যথেষ্ট একটি শর্টকাট সংজ্ঞায়িত না করা def g(x): return f(SafeInput(x))

উদাহরণ:

class SafeInput(object):
  def __init__(self, value):
    self._value = value

  def value(self):
    return self._value

def f(safe_string_to_eval):
  assert type(safe_string_to_eval) is SafeInput, "safe_string_to_eval must have type SafeInput, but was {}".format(type(safe_string_to_eval))
  ...
  eval(safe_string_to_eval.value())
  ...

a = f(SafeInput(local_file.some_str))

যদিও এটি সহজে পরিলক্ষিত হতে পারে, দুর্ঘটনাক্রমে এটি করা আরও কঠিন করে তোলে। লোকেরা এই জাতীয় কট্টর ধরণের চেকের সমালোচনা করতে পারে তবে তারা বিষয়টিটি মিস করবে। যেহেতু SafeInputপ্রকারটি কেবলমাত্র একটি ডেটাটাইপ এবং কোনও অবজেক্ট-ওরিয়েন্টেড শ্রেণি নয় যা উপক্লাস হতে পারে, তাই ধরণের পরিচয়ের type(x) is SafeInputজন্য পরীক্ষা করা ধরণের সাথে সামঞ্জস্যতার জন্য যাচাই করার চেয়ে নিরাপদ isinstance(x, SafeInput)। যেহেতু আমরা একটি নির্দিষ্ট ধরণের প্রয়োগ করতে চাই না, স্পষ্টতাল ধরণের উপেক্ষা করে এবং কেবলমাত্র গা imp় হাঁসের টাইপিং করাও সন্তোষজনক নয়। পাইথনের একটি টাইপ সিস্টেম রয়েছে, সুতরাং আসুন সম্ভাব্য ভুলগুলি ধরার জন্য এটি ব্যবহার করুন!


5
একটি ছোট পরিবর্তন প্রয়োজন হতে পারে যদিও। assertযেহেতু আমি অপ্টিমাইজড পাইথন কোডটি ব্যবহার করব তা স্বয়ংক্রিয়ভাবে সরানো হবে। এর মতো কিছু if ... : raise NotSafeInputErrorদরকার হবে।
ফার্মি প্যারাডক্স

4
যদি আপনি যাইহোক এই রাস্তাটি নিচে চলে যাচ্ছেন তবে আমি দৃ strongly ়ভাবে eval()একটি পদ্ধতিতে চালিত হওয়ার পরামর্শ দিচ্ছি SafeInput, যাতে আপনার স্পষ্টত ধরণের চেকের প্রয়োজন না হয়। পদ্ধতিটিকে এমন কোনও নাম দিন যা আপনার অন্য শ্রেণীর কোনওটিতে ব্যবহৃত হয় না। এইভাবে, আপনি এখনও পরীক্ষার উদ্দেশ্যে পুরো জিনিসটিকে উপহাস করতে পারেন।
কেভিন

@ কেভিন: evalস্থানীয় ভেরিয়েবলের অ্যাক্সেস হিসাবে এটি দেখে , কোডটি কীভাবে এটি ভেরিয়েবলকে পরিবর্তিত করে তার উপর নির্ভর করে। ইওালটিকে অন্য পদ্ধতিতে স্থানান্তরিত করে, এটিতে আর স্থানীয় ভেরিয়েবলগুলি পরিবর্তন করার ক্ষমতা থাকবে না।
সুজোরড জব পোস্টমাস

পরবর্তী পদক্ষেপটি হতে পারে যে SafeInputকনস্ট্রাক্টর স্থানীয় ফাইলের নাম / হ্যান্ডেল নেবে এবং নিজেই পড়বে, তা নিশ্চিত করে যে ডেটাটি কোনও স্থানীয় ফাইল থেকে আসে না।
ওভেন

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

11

যেমন জোয়েল একবার উল্লেখ করেছে, ভুল কোডটিকে ভুল দেখায় ("রিয়েল সলিউশন" বিভাগে স্ক্রোল করুন, বা আরও ভাল এটি পুরোপুরি পড়ুন; এটি মূল্যবান, এমনকি যদি এটি ফাংশন নামের পরিবর্তে পরিবর্তনশীলকে সম্বোধন করে)। সুতরাং আমি বিনীতভাবে আপনার ফাংশনটির মতো নতুন নামকরণের পরামর্শ দিচ্ছি f_unsafe_for_external_use()- আপনি সম্ভবত কিছু সংক্ষিপ্তসার স্কিম নিয়ে এসেছেন।

সম্পাদনা: আমি মনে করি অ্যামনের পরামর্শটি একই থিমের ওও ভিত্তিক প্রকরণটি খুব ভাল :-)


0

@Amon দ্বারা পরামর্শটি পরিপূরক করে, আপনি এখানে কৌশল বিন্যাসের পাশাপাশি পদ্ধতি অবজেক্টের প্যাটার্নটি একত্রিত করার বিষয়েও ভাবতে পারেন।

class AbstractFoobarizer(object):
    def handle_cond(self, foo, bar):
        """
        Handle the event or something.
        """
        raise NotImplementedError

    def run(self):
        # do some magic
        pass

এবং তারপরে একটি 'সাধারণ' বাস্তবায়ন

class PrintingFoobarizer(AbstractFoobarizer):
    def handle_cond(self, foo, bar):
        print("Something went very well regarding {} and {}".format(foo, bar))

এবং অ্যাডমিন-ইনপুট-ইভাল বাস্তবায়ন

class AdminControllableFoobarizer(AbstractFoobarizer):
    def handle_cond(self, foo, bar):
        # Look up code in database/config file/...
        code = get_code_from_settings()
        eval(code)

(দ্রষ্টব্য: একটি বাস্তব-বিশ্ব-ইশ উদাহরণ সহ, আমি আরও ভাল উদাহরণ দিতে সক্ষম হতে পারি)।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.