ডিওমে স্বেচ্ছাসেবী JSON এম্বেড করার জন্য সেরা অনুশীলন?


110

আমি DOM এ স্বেচ্ছাসেবী JSON এম্বেডিং সম্পর্কে চিন্তা করছি:

<script type="application/json" id="stuff">
    {
        "unicorns": "awesome",
        "abc": [1, 2, 3]
    }
</script>

এটি কোনও জাভাস্ক্রিপ্ট টেম্পলেট ইঞ্জিনের সাথে পরে ব্যবহারের জন্য ডিওমে একটি নির্বিচার HTML টেম্পলেট সংরক্ষণ করতে পারে তার অনুরূপ। এই ক্ষেত্রে, আমরা পরে জেএসএন পুনরুদ্ধার করতে এবং এর সাথে পার্স করতে পারি:

var stuff = JSON.parse(document.getElementById('stuff').innerHTML);

এটি কাজ করে , তবে এটি কি সেরা উপায়? এটি কি কোনও সেরা অনুশীলন বা মান লঙ্ঘন করে?

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


1
varজাভাস্ক্রিপ্টে এটি কেন থাকবে না ?
ক্রিজ

@ ক্রিজ, এটি একটি স্ট্যাটিক নথির অংশ হওয়া দরকার যা এটি পরে এনক্যাপসুলেটেড জাভাস্ক্রিপ্টের একটি জটিল চেইন দ্বারা প্রক্রিয়া করা হয়। এটি ডিওমে সংরক্ষণ করে আমি যা করতে চাই।
বেন লি

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

2
আমি মনে করি আপনার আসল পদ্ধতিটি আসলে সর্বোত্তম। এটি এইচটিএমএল 5 এ 100% বৈধ, এটি অভিব্যক্তিপূর্ণ, এটি "জাল" উপাদান তৈরি করে না যা আপনি কেবল সিএসএস দিয়ে মুছে ফেলবেন বা লুকিয়ে রাখবেন; এবং এর জন্য কোনও অক্ষর এনকোডিংয়ের প্রয়োজন নেই। ডাউনসাইড কি?
জেমি ট্রওয়ার্গি

22
যদি </script><script>alert()</script><script>আপনার JSON অবজেক্টের ভিতরে মান সহ একটি স্ট্রিং থাকে তবে আপনি অবাক হয়ে যাবেন। আপনি প্রথমে ডেটা স্যানিটাইজ না করা পর্যন্ত এটি নিরাপদ নয়।
সিলভিট

উত্তর:


77

আমি মনে করি আপনার মূল পদ্ধতিটি সবচেয়ে ভাল। এইচটিএমএল 5 স্পেস এমনকি এই ব্যবহারকে সম্বোধন করে:

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

এখানে পড়ুন: http://dev.w3.org/html5/spec/Overview.html#the-script-element

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


3
ধন্যবাদ. অনুমানের উক্তিটি আমাকে নিশ্চিত করেছে।
বেন লি

17
আপনি যদি প্রথমে JSON অবজেক্টটি পরীক্ষা করে স্যানিটাইজ করেন তবে এটি পুরোপুরি বৈধ: আপনি কেবল ব্যবহারকারী উত্সাহিত ডেটা এম্বেড করতে পারবেন না। প্রশ্নে আমার মন্তব্য দেখুন।
সিলভিট

1
অতিরিক্ত ভাবছেন: এটি রাখার ভাল জায়গাটি কী? মাথা বা শরীর, উপরে বা নীচে?
20:37

1
দুর্ভাগ্যক্রমে, এটি প্রদর্শিত হয় যে সিএসপি নীতি সমস্ত scriptট্যাগগুলি বন্ধ করে দিতে পারে / করবে ।
ল্যারি কে

2
আপনি কীভাবে JSON এম্বেড করার বিরুদ্ধে কার্যকরভাবে রক্ষা করবেন </ translation> এবং এইভাবে, এইচটিএমএল ইনজেকশনের অনুমতি দেয়? কি শক্ত / সহজ কিছু আছে, বা ডেটা অ্যাট্রিবিউট ব্যবহার করা ভাল?
jonasfj

23

একটি সাধারণ দিকনির্দেশ হিসাবে, আমি পরিবর্তে এইচটিএমএল 5 ডেটা অ্যাট্রিবিউট ব্যবহার করার চেষ্টা করব । আপনাকে বৈধ JSON স্থাপন করা বন্ধ করার মতো কিছুই নেই। উদাহরণ:

<div id="mydiv" data-unicorns='{"unicorns":"awesome", "abc":[1,2,3]}' class="hidden"></div>

আপনি যদি jQuery ব্যবহার করছেন তবে এটি পুনরুদ্ধার করা তত সহজ easy

var stuff = JSON.parse($('#mydiv').attr('data-unicorns'));

1
বুদ্ধি তৈরি করুন। যদিও খেয়াল করুন যে কী নামের একক উদ্ধৃতি সহ, JSON.parseকাজ করবে না (কমপক্ষে নেটিভ গুগল ক্রোম জেএসওএন.পার্স কাজ করবে না)। জেএসওএন স্পেকের জন্য ডাবল উদ্ধৃতি প্রয়োজন। তবে এটির মতো সত্তা ব্যবহার করে ঠিক করা যথেষ্ট সহজ ...&lt;unicorns&gt;:...
বেন লি

4
যদিও একটি প্রশ্ন: এইচটিএমএল 5 এ গুণাবলীর দৈর্ঘ্যের কোনও সীমা আছে?
বেন লি

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

1
ঠিক আছে, আমার প্রশ্নের উত্তর খুঁজে পেয়েছি: স্ট্যাকওভারফ্লো / প্রশ্ন / 1496096/… - এটি আমার উদ্দেশ্যগুলির জন্য যথেষ্ট।
বেন লি

2
এটি কোনও একক স্ট্রিংয়ের জন্য কাজ করবে না, উদাহরণস্বরূপ "I am valid JSON"এবং ট্যাগের জন্য ডাবল কোট ব্যবহার করে, বা স্ট্রিংয়ে একক উদ্ধৃতি সহ একক উদ্ধৃতি, যেমন data-unicorns='"My JSON's string"'সিএস কোটগুলি JSON হিসাবে এনকোডিং সহ এড়ানো যায় না।
রবি অ্যাভারিল

13

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

http://jsfiddle.net/YmhZv/1/

এখানে ইঞ্জেকশন দেওয়া হচ্ছে

<script type="application/json" id="stuff">
{
    "unicorns": "awesome",
    "abc": [1, 2, 3],
    "badentry": "blah </script><div id='baddiv'>I should not exist.</div><script type="application/json" id='stuff'> ",
}
</script>

পালানোর / এনকোডিংয়ের আশেপাশে কোনও উপায় নেই।


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

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

7

ওডাব্লিউএএসপি এর এক্সএসএস প্রতিরোধের চিট শীটে নিয়ম # 3.1 দেখুন ।

বলুন আপনি এই জেএসএনটিকে এইচটিএমএলে অন্তর্ভুক্ত করতে চান:

{
    "html": "<script>alert(\"XSS!\");</script>"
}

<div>এইচটিএমএল একটি লুকানো তৈরি করুন । এরপরে, অনিরাপদ সত্তাগুলি (যেমন, &, <,>, ", ', এবং, /) এনকোড করে আপনার JSON এড়িয়ে চলুন এবং এটিকে উপাদানটির ভিতরে রেখে দিন।

<div id="init_data" style="display:none">
        {&#34;html&#34;:&#34;&lt;script&gt;alert(\&#34;XSS!\&#34;);&lt;/script&gt;&#34;}
</div>

এখন আপনি textContentজাভাস্ক্রিপ্ট ব্যবহার করে উপাদানটির পড়া এবং এটি বিশ্লেষণ করে এটি অ্যাক্সেস করতে পারেন :

var text = document.querySelector('#init_data').textContent;
var json = JSON.parse(text);
console.log(json); // {html: "<script>alert("XSS!");</script>"}

আমি বিশ্বাস করি যে এটি সেরা এবং নিরাপদ উত্তর। লক্ষ্য করুন যে প্রচুর প্রচলিত JSON অক্ষরগুলি পালিয়ে যায় এবং নির্দিষ্ট অক্ষরগুলি দ্বিগুণ পালিয়ে যায়, যেমন বস্তুর অভ্যন্তরের উদ্ধৃতিগুলি {name: 'Dwayne "The Rock" Johnson'}। আপনার ফ্রেমওয়ার্ক / টেম্প্লেটিং লাইব্রেরিতে ইতিমধ্যে এইচটিএমএল এনকোডিং করার নিরাপদ উপায় অন্তর্ভুক্ত হওয়ায় সম্ভবত এই পদ্ধতিটি ব্যবহার করা এখনও সেরা। বেস 64 ব্যবহার করা একটি বিকল্প হবে যা এইচটিএমএল নিরাপদ এবং জেএস স্ট্রিংয়ের ভিতরে রাখতে নিরাপদ। বিটিও () / এটোব () ব্যবহার করে জেএসে এনকোড / ডিকোড করা সহজ এবং সার্ভার সাইড করা আপনার পক্ষে সম্ভবত সহজ।
sstur

একটি এমনকি নিরাপদ পদ্ধতি হ'ল শব্দার্থগতভাবে সঠিক <data>উপাদানটি ব্যবহার করা এবং valueবৈশিষ্ট্যের মধ্যে জেএসওএন ডেটা অন্তর্ভুক্ত করা। তারপরে আপনাকে কেবলমাত্র &quotডেটা বদ্ধ করার জন্য ডাবল উদ্ধৃতি ব্যবহার করা হয়, বা &#39;আপনি যদি একক উদ্ধৃতি ব্যবহার করেন (যা সম্ভবত আরও ভাল) তবে উদ্ধৃতি চিহ্নগুলি দিয়ে পালাতে হবে ।
রোনার বার্গ

5

আমি JSON কে একটি ফাংশন কলব্যাক ( JSONP ধরণের ) সহ একটি ইনলাইন স্ক্রিপ্টে রাখার পরামর্শ দেব :

<script>
someCallback({
    "unicorns": "awesome",
    "abc": [1, 2, 3]
});
</script>

যদি ডকুমেন্টের পরে এক্সিকিউটিভ স্ক্রিপ্টটি লোড হয় তবে আপনি সম্ভবত এটি কোনও অতিরিক্ত শনাক্তকারী যুক্তির সাথে সংরক্ষণ করতে পারেন: someCallback("stuff", { ... });


ক্যালব্যাক ফাংশনটি সংজ্ঞায়িত করার একমাত্র অসুবিধা সহ @ বেনলি এটি খুব ভালভাবে কাজ করা উচিত। অন্যান্য প্রস্তাবিত সমাধান বিশেষ জেএমএল অক্ষরগুলিতে বিরতি দেয় (উদাহরণস্বরূপ &) এবং আপনার উদ্ধৃতিগুলি যদি আপনার জেএসএনে থাকে।
অনুলিপি

এটি আরও ভাল অনুভূত হয়েছে কারণ ডেটা খুঁজে পেতে আপনার কোনও ডোম ক্যোয়ারির প্রয়োজন নেই
জাসিম

@ কপি এই সমাধানটির এখনও অবকাশ প্রয়োজন (ম্যাডকোডার এর উত্তর দেখুন)। এখানে এটি সম্পূর্ণতার জন্য রেখে দেওয়া হচ্ছে।
pvgoran

2

আমার সুপারিশটি হ'ল জেএসওএন ডেটা বাইরের .jsonফাইলগুলিতে রাখা এবং তারপরে অ্যাজাক্সের মাধ্যমে সেই ফাইলগুলি পুনরুদ্ধার করা। আপনি ওয়েব-পৃষ্ঠাতে (ইনলাইন) সিএসএস এবং জাভাস্ক্রিপ্ট কোড রাখেন না, তবে আপনি কেন এটি JSON দিয়ে করবেন?


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

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

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

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

2

এইচটিএমএল 5 এ মেশিনের পঠনযোগ্য ডেটা রাখার জন্য একটি <data>উপাদান রয়েছে । আপনার পক্ষে একটি "সম্ভবত নিরাপদ" বিকল্প হিসাবে সেই উপাদানটির বৈশিষ্ট্যের <script type="application/json">মধ্যে আপনার জেএসওএন ডেটা অন্তর্ভুক্ত করতে পারে value

const jsonData = document.querySelector('.json-data');
const data = JSON.parse(jsonData.value);

console.log(data)
<data class="json-data" value='
  {
    "unicorns": "awesome",
    "abc": [1, 2, 3],
    "careful": "to escape &#39; quotes"
  }
'></data>

এই ক্ষেত্রে আপনি এমন সমস্ত একক উদ্ধৃতি প্রতিস্থাপন করা প্রয়োজন &#39;অথবা সঙ্গে &quot;আপনি উদ্ধৃতি চিহ্ন সঙ্গে মান ঘিরা মনোনীত। অন্যথায় অন্যান্য ঝুঁকির মতো আপনার ঝুঁকি এক্সএসএসের আক্রমণগুলি পরামর্শ দিয়েছে।

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