এটি একটি বাস্তব-বিশ্ব অ্যাপ্লিকেশন সহ একটি কোড গল্ফ ধাঁধা। কিছু বর্তমান ব্রাউজার, যদি আপনি এমন URL টি প্রবেশ করেন যা দেখে মনে হয়
data:text/html,<script>alert("hi")</script>
প্রদত্ত জাভাস্ক্রিপ্ট কোডটি কার্যকর করবে। এখন ধরুন আপনার কাছে এমন ইউআরএল রয়েছে যা দেখতে দেখতে (সিউডোকোড):
data:text/html,<script>
myPublicKey="12345678";
cryptoLib=download("http://example.com/somecryptolib.js");
if(sha256sum(cryptoLib) == "12345678")
eval(cryptoLib)
</script>
আপনি যদি এটি কোনও কিউআর কোড হিসাবে ব্যবসায়িক কার্ডে মুদ্রণ করেন , তবে যে কোনও উপযুক্ত ব্রাউজারের সাথে যে ইউআরএল গিয়েছেন তিনি কোনও কিছু ইনস্টল না করেই আপনার সার্বজনীন কী প্রি-লোডযুক্ত একটি পাবলিক-কী ক্রিপ্টো ক্লায়েন্ট পাবেন। হ্যাশ যাচাইকরণের কারণে আপনি আত্মবিশ্বাসী হতে পারেন যে তারা আসল ক্রিপ্টো সফ্টওয়্যার পেয়েছে, এমনকি যদি তাদের আইএসপি ট্র্যাফিকের সাথে হস্তক্ষেপ করে।
দুর্ভাগ্যক্রমে, এই সিউডোকোডের আসল সংস্করণটি কিউআর কোডের জন্য বেশ দীর্ঘ। আমার চ্যালেঞ্জটি: আপনি এটি কতটা সংক্ষিপ্ত করতে পারেন? একটি বাস্তবায়ন হবে:
- ডেটা হোন: ... URL যা ক্রোম এবং ফায়ারফক্সের অ্যাড্রেস বার থেকে সঠিকভাবে কার্যকর করে। (একটি বৈধ ডেটা তৈরি করতে: ইউআরএল, আপনাকে% 25% হিসাবে এনকোড করতে হবে এবং নিউলাইনগুলি স্ট্রিপ করতে হবে)
- একটি URL এবং একটি SHA-256 হ্যাশ এম্বেড করা আছে, প্রায় শুরুতে প্লেইন-পাঠ্য স্ট্রিং আক্ষরিক হিসাবে
- এক্সএমএলএইচটিপিআরকোয়েস্ট (বা অনুরূপ এপিআই) ব্যবহার করে কোনও URL থেকে একটি ফাইল ডাউনলোড করুন । (নোট করুন যে সার্ভারটির অ্যাক্সেস-কন্ট্রোল-মঞ্জুরি-উত্স: * এটি কাজ করার জন্য শিরোনাম অন্তর্ভুক্ত করতে হবে))
- যদি সেই URL টি সফলভাবে লোড হয় এবং ফলাফলটি প্রত্যাশিত হ্যাশযুক্ত কোনও ফাইল হয়, তবে এটি () প্রকাশ করুন। অন্যথায় কিছুই করবেন না বা একটি ত্রুটি বার্তা দেখান।
- সমস্ত বিল্টিন জাভাস্ক্রিপ্ট ফাংশন যা ক্রোম এবং ফায়ারফক্স উভয়ের মধ্যে উপস্থিত রয়েছে তা ন্যায্য খেলা, তবে লাইব্রেরি লোড করা অসম্ভব।
- যতটা সম্ভব বাইট ব্যবহার করুন
আমি ক্রিপ্টোজেএস ( মিনিফাইন্ড সংস্করণ ) ব্যবহার করে একটি নিষ্কলুষ সংস্করণ তৈরি করেছি :
data:text/html,<script>
u = 'http://localhost:8000'
h = '5e3f73c606a82d68ef40f9f9405200ce24adfd9a4189c2bc39015345f0ee46d4'
// Insert CryptoJS here
r = new XMLHttpRequest;
r.open('GET', u, false);
r.send();
if(CryptoJS.SHA256(r.response) == h)
eval(r.response);
</script>
যা মিনিফায়ার থেকে বেরিয়ে আসে:
data:text/html,<script>u="http://localhost:8000";h="5e3f73c606a82d68ef40f9f9405200ce24adfd9a4189c2bc39015345f0ee46d4";var CryptoJS=CryptoJS||function(k,w){var f={},x=f.lib={},g=function(){},l=x.Base={extend:function(a){g.prototype=this;var c=new g;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},t=x.WordArray=l.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=w?c:4*a.length},toString:function(a){return(a||y).stringify(this)},concat:function(a){var c=this.words,d=a.words,b=this.sigBytes;a=a.sigBytes;this.clamp();if(b%254)for(var e=0;e<a;e++)c[b+e>>>2]|=(d[e>>>2]>>>24-8*(e%254)&255)<<24-8*((b+e)%254);else if(65535<d.length)for(e=0;e<a;e+=4)c[b+e>>>2]=d[e>>>2];else c.push.apply(c,d);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<<32-8*(c%254);a.length=k.ceil(c/4)},clone:function(){var a=l.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],d=0;d<a;d+=4)c.push((1<<30)*4*k.random()|0);return new t.init(c,a)}}),z=f.enc={},y=z.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b<a;b++){var e=c[b>>>2]>>>24-8*(b%254)&255;d.push((e>>>4).toString(16));d.push((e&15).toString(16))}return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b<c;b+=2)d[b>>>3]|=parseInt(a.substr(b,2),16)<<24-4*(b%258);return new t.init(d,c/2)}},m=z.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b<a;b++)d.push(String.fromCharCode(c[b>>>2]>>>24-8*(b%254)&255));return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b<c;b++)d[b>>>2]|=(a.charCodeAt(b)&255)<<24-8*(b%254);return new t.init(d,c)}},n=z.Utf8={stringify:function(a){try{return decodeURIComponent(escape(m.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return m.parse(unescape(encodeURIComponent(a)))}},B=x.BufferedBlockAlgorithm=l.extend({reset:function(){this._data=new t.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=n.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,d=c.words,b=c.sigBytes,e=this.blockSize,f=b/(4*e),f=a?k.ceil(f):k.max((f|0)-this._minBufferSize,0);a=f*e;b=k.min(4*a,b);if(a){for(var p=0;p<a;p+=e)this._doProcessBlock(d,p);p=d.splice(0,a);c.sigBytes-=b}return new t.init(p,b)},clone:function(){var a=l.clone.call(this);a._data=this._data.clone();return a},_minBufferSize:0});x.Hasher=B.extend({cfg:l.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){B.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(c,d){return(new a.init(d)).finalize(c)}},_createHmacHelper:function(a){return function(c,d){return(new A.HMAC.init(a,d)).finalize(c)}}});var A=f.algo={};return f}(Math);(function(k){for(var w=CryptoJS,f=w.lib,x=f.WordArray,g=f.Hasher,f=w.algo,l=[],t=[],z=function(a){return (1<<30)*4*(a-(a|0))|0},y=2,m=0;64>m;){var n;a:{n=y;for(var B=k.sqrt(n),A=2;A<=B;A++)if(!(n%25A)){n=!1;break a}n=!0}n&&(8>m&&(l[m]=z(k.pow(y,0.5))),t[m]=z(k.pow(y,1/3)),m++);y++}var a=[],f=f.SHA256=g.extend({_doReset:function(){this._hash=new x.init(l.slice(0))},_doProcessBlock:function(c,d){for(var b=this._hash.words,e=b[0],f=b[1],p=b[2],k=b[3],s=b[4],l=b[5],m=b[6],n=b[7],q=0;64>q;q++){if(16>q)a[q]=c[d+q]|0;else{var v=a[q-15],g=a[q-2];a[q]=((v<<25|v>>>7)^(v<<14|v>>>18)^v>>>3)+a[q-7]+((g<<15|g>>>17)^(g<<13|g>>>19)^g>>>10)+a[q-16]}v=n+((s<<26|s>>>6)^(s<<21|s>>>11)^(s<<7|s>>>25))+(s&l^~s&m)+t[q]+a[q];g=((e<<30|e>>>2)^(e<<19|e>>>13)^(e<<10|e>>>22))+(e&f^e&p^f&p);n=m;m=l;l=s;s=k+v|0;k=p;p=f;f=e;e=v+g|0}b[0]=b[0]+e|0;b[1]=b[1]+f|0;b[2]=b[2]+p|0;b[3]=b[3]+k|0;b[4]=b[4]+s|0;b[5]=b[5]+l|0;b[6]=b[6]+m|0;b[7]=b[7]+n|0},_doFinalize:function(){var a=this._data,d=a.words,b=8*this._nDataBytes,e=8*a.sigBytes;d[e>>>5]|=128<<24-e%2532;d[(e+64>>>9<<4)+14]=k.floor(b/(1<<30)*4);d[(e+64>>>9<<4)+15]=b;a.sigBytes=4*d.length;this._process();return this._hash},clone:function(){var a=g.clone.call(this);a._hash=this._hash.clone();return a}});w.SHA256=g._createHelper(f);w.HmacSHA256=g._createHmacHelper(f)})(Math);r=new XMLHttpRequest;r.open("GET",u,!1);r.send();CryptoJS.SHA256(r.response)==h&&eval(r.response)</script>
এই ন্যূনতম পাইথন সার্ভারের সাথে পরীক্ষিত:
import BaseHTTPServer
class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_HEAD(s):
s.send_response(200)
s._sendHeaders()
s.end_headers()
def do_GET(s):
s.send_response(200)
s._sendHeaders()
s.end_headers()
s.wfile.write('alert("Success!")')
def _sendHeaders(s):
s.send_header("Content-type", "script/javascript");
s.send_header("Access-Control-Allow-Origin", "*");
def run(server_class=BaseHTTPServer.HTTPServer,
handler_class=RequestHandler):
server_address = ('', 8000)
httpd = server_class(server_address, handler_class)
httpd.serve_forever()
run()
জাভাস্ক্রিপ্ট অংশটি 4700 বাইট, তবে এটি আরও ছোট হতে পারে। এটি কতটা ছোট হতে পারে?
script
উপাদান তৈরি করে , এর async
সম্পত্তি সেট করে false
এবং দস্তাবেজে serোকানোর মাধ্যমে?
script/javascript
? আপনি বলতে চাচ্ছেন text/javascript
।
eval
এবং তারপরে লোড করা ক্রিপ্টো লাইব্রেরি দিয়ে দ্বিতীয় অনুরোধ করা কি এই সঠিক বিন্দুকে পরাভূত করবে? আমি একটি সমাধানে কাজ করার জন্য কিছু সময় ব্যয় করেছি এবং ঠিক এটিই শেষ করেছি, তবে তারপরে বুঝতে পেরেছি যে এটি আইএসপি'র উপর নির্ভর করে ক্রিপ্টোর লাইব্রেরিতে ঝামেলা না করা যা একটি সমস্যা।