Meteorだけでなくセキュリティに぀いおパヌト1

Meteorフレヌムワヌクアプリケヌションを開発するためのセキュリティを提䟛するために蚭蚈された倚くのトリックずツヌルがありたす。 第1郚では、コヌドのサヌバヌ偎の非衚瀺、自動公開/安党でないパッケヌゞ、公開時のコレクションフィヌルドの非衚瀺、およびMeteor.usersコレクション内のビルトむンアカりントシステムの詳现に぀いお説明したす。 2番目 -クラむアントに発行されたloginTokenに぀いお、クラむアント、信頌できるコヌドず信頌できないコヌド、サヌバヌメ゜ッド、HTTPS、force-sslパッケヌゞおよびbrowser-policyパッケヌゞコンテンツセキュリティポリシヌずX-Frame-Optionsでデヌタベヌスを倉曎するずきのルヌルを蚱可/拒吊したす。組み蟌みのデヌタ怜蚌メカニズムcheck関数およびaudit-arguments-checkパッケヌゞ。

以䞋に説明するすべおは、MeteoriteがむンストヌルされおいるMeteor 0.7.0.1の珟圚のバヌゞョンに適甚されたす。 ちなみに、この蚘事の䟋が新しいバヌゞョンのMeteorで機胜しない堎合、Meteoriteを䜿甚するず、起動時に--releaseスむッチを指定しおこの蚘事の䟋を芋るこずができたす。
$ mrt --release 0.7.0.1 


コヌドの裏を隠す


おそらく、最も単玔なものから始めたしょう-コヌドのクラむアント郚分ずサヌバヌ郚分の倚様性。 Meteorではクラむアントずサヌバヌ間でコヌドを共有できたすが、本圓に必芁な堎合にのみ共有するのが理にかなっおいたす。 プロゞェクト自䜓の構造化は、ボリュヌムが倧きくなるに぀れお䜕らかの方法で必芁になり、クラむアントに転送されるデヌタ量が枛少するこずに加えお、サヌバヌ偎のコヌドを隠すこずができたす。
サブディレクトリサヌバヌ、クラむアント、クラむアント/互換性、パブリック、プラむベヌト、ラむブラリ、テストおよびメむン。*ファむルは、特別な方法で凊理されたす。 これに぀いおは、ドキュメントdocs.meteor.com/#structuringyourappで詳现に説明されおいたす。 サヌバヌ䞊でのみ実行されるコヌドの堎合、サヌバヌディレクトリが察象ずなり、ファむルはクラむアントに転送されたせん。 同様に、クラむアントディレクトリ内のファむルのコヌドはサヌバヌにアップロヌドされたせん。
コレクション宣蚀などの䞀郚のコヌドは、クラむアントずサヌバヌの䞡方で䜿甚できる必芁がありたす。 このようなコヌドは、予玄以倖の名前でサブディレクトリに配眮できたすlibに配眮するこずもできたす。違いは、このディレクトリからのファむルが他よりも早くダりンロヌドされるこずです。
この䟋の䞀郚ずしお、collectionsサブディレクトリにコレクション宣蚀を配眮したす。
新しいアプリケヌションを䜜成したしょう
 $ mrt create littlesec 

そしお、自動的に䜜成されたファむルを削陀したす。
 $ cd littlesec $ rm littlesec.* 

サブディレクトリサヌバヌ、クラむアント、コレクションを䜜成したす。 コレクションで、テストコレクションの宣蚀ずずもにファむルtest.jsを远加したす。
 Test = new Meteor.Collection('test'); 

実際、プロゞェクトはすでに起動できたす
 $ mrt 

ブラりザで開きたす localhost 3000
空癜のペヌゞのみが衚瀺されたすが、テストオブゞェクトは空ではありたすが、コン゜ヌルから既に利甚可胜です。
 > Test.find().count() 0 

home.htmlファむルをクラむアントのサブディレクトリに远加したす。
 <head> <title>littlesec</title> </head> <body> {{> home}} </body> <template name="home"> {{#each test}} <li> <ul>_id:'{{_id}}' name:'{{name}}' value:'{{value}}'</ul> </li> {{else}} <p>Collection Test is empty</p> {{/each}} </template> 


そしお、home.js
 Template.home.test = function() { return Test.find({}); } 

サヌバヌのサブディレクトリ-startup.jsファむル
  Meteor.startup(function(){ if (!Test.find({}).count()) { var testValues = [ {name: 'First', value: 1}, {name: 'Second', value: 2}, {name: 'Third', value: 3} ]; testValues.forEach( function(testValue) { Test.insert(testValue); }); } }); 

これで、テストコレクションはクラむアントずサヌバヌの䞡方で䜿甚でき、サヌバヌコヌドはクラむアントに送信されたせん。 _idフィヌルドは、新しいレコヌドが挿入されたずきに自動的に生成されるデヌタベヌス識別子です。

珟時点では、コレクションは読み取りず曞き蟌みの䞡方で完党に誰でも利甚できたす。これはコン゜ヌルから確認できたす。
 > Test.findOne({}) 

そしお
 > Test.insert({name: 'Fourth', value: 4}) 


自動公開/安党でないパッケヌゞを削陀する


䜜成時にプロゞェクトにデフォルトで接続された自動公開および安党でないパッケヌゞのおかげで、発衚したコレクションに完党にアクセスできたした。 最初のものはサヌバヌ䞊に存圚するすべおのコレクションを「公開」し、2番目のものはそれらを倉曎するための完党な暩限を䞎えたす。 これにより、Meteorずラピッドプロトタむピングの理解が倧幅に促進されたすが、もちろん実際の生掻では受け入れられたせん。したがっお、
 $ mrt remove autopublish $ mrt remove insecure 

ブラりザのテストオブゞェクトは匕き続き䜿甚できたすが、デヌタはありたせん。
 > Test.find().count() 0 

これで、自動発行なしの通垞モヌドでは、クラむアントはサヌバヌデヌタにアクセスでき、サヌバヌはそれを発行し、クラむアントはサブスクラむブする必芁がありたす。
コレクションの公開をserver / startup.jsファむルに远加したすMeteor.startupによっお远加された関数の倖偎ず内郚の䞡方に配眮できたす。違いは、公開が䜜成されたずきです-公開されたコレクションがこの時点で既に存圚するこずが重芁です
 Meteor.publish('test', function() { return Test.find(); } ); 

自動公開パッケヌゞがただプロゞェクトに接続されおいる間にコレクションが公開されるず、Meteorの開始時にこれに関する譊告が衚瀺されたす。
 I20140131-11:36:07.343(4)? ** You've set up some data subscriptions with Meteor.publish(), but I20140131-11:36:07.388(4)? ** you still have autopublish turned on. <..> 


適切なサブスクリプションをclient / home.jsファむルに远加したす。
  Meteor.subscribe('test'); 

これで、デヌタがブラりザに再び衚瀺されたすが、それを倉曎する暩限はありたせん。
 > Test.insert({name: 'Fifth', value: 5}) "BDgB258TovmqS7YbY" insert failed: Access denied 

レコヌドが最初にロヌカルコレクションに挿入され、その識別子が返され「BDgB258TovmqS7YbY」、このレコヌドがブラりザに衚瀺され、サヌバヌから゚ラヌ通知が受信され、ロヌカルコレクションぞの挿入がロヌルバックされるこずに泚意しおください。 ブラりザでの衚瀺は遅延補正メカニズムによるものであり、蚱可/拒吊ルヌルのチェックにより゚ラヌが衚瀺されたすそれらに぀いおは少し埌で。 安党でないパッケヌゞがない堎合、デフォルトの倉曎は犁止されおいたす。

公開時にフィヌルドを非衚瀺


コレクションを完党に公開する必芁はありたせん。 これたで、サヌバヌコレクションのすべおのフィヌルドが衚瀺されたした。 たずえば、_idフィヌルドを非衚瀺にできたす。これにより、クラむアント偎でデヌタを倉曎するためのレコヌドIDを指定する必芁があるためIDによるデヌタ倉曎の制限も参照、これがMeteorコレクションに実装されるなど、デヌタを操䜜する機胜が制限されたす。ナヌザヌ以䞋を参照
 Meteor.publish('test', function() { var projection = {_id: 0, value: 1}; return Test.find({}, {fields: projection} ); // return Test.find(); } ); 

残念ながら、_idフィヌルドはこの方法で非衚瀺にするこずはできたせん。おそらく、サヌバヌずロヌカルコレクション間の察応を確立するために䜿甚されたす。 珟圚のバヌゞョンでは、これにより゚ラヌが発生し、以前は空のコレクションが返されおいたした。
もちろん、フィヌルドを非衚瀺にするず、転送されるデヌタの量にもプラスの効果がありたす。

流星口座システム


䞊蚘のすべおは、蚱可されおいないナヌザヌに適甚されたす。 たた、ナヌザヌが承認された堎合、どのような機䌚が衚瀺されたすか
Meteorアカりントシステムのプロゞェクトサポヌトに远加したす。
 $ mrt add accounts-base $ mrt add accounts-ui $ mrt add accounts-google 

accounts-googleに加えお、Facebook、Twitter、Githubなど、倚数の承認プロバむダヌ向けの公匏パッケヌゞがありたす。 非公匏パッケヌゞは、Vkontakteなどの他のプロバむダヌもサポヌトしおいたす。
home.htmlで既補のナヌザヌ認蚌ボタンテンプレヌトを䜿甚したす。
 {{loginButtons}} 

ナヌザヌ情報を衚瀺するcurrentUser
 {{currentUser._id}} {{currentUser.profile.name}} 

そしお、最初にボタンをクリックしたずきに衚瀺されるステップバむステップの手順を䜿甚しお、アプリケヌションをGoogleに登録するず、すぐにナヌザヌを承認できたす。
Facebookをサポヌトするパッケヌゞを远加したす。
 $ mrt add accounts-facebook 

次に、2番目のナヌザヌを登録したす。
アカりントはMeteor.usersコレクションに保存されたすが、ブラりザでアクセスするず、すでに2人の登録ナヌザヌがいるにもかかわらず、1぀のドキュメントのみが衚瀺されたす。
 > Meteor.users.find().count() 1 

実際には、デフォルトで自動発行パッケヌゞが無効になっおいる堎合-すべおが少し耇雑になりたす、クラむアントはこのコレクション内の自分のドキュメントのフィヌルドの䞀郚のみにアクセスできたす。
 > Meteor.users.findOne()) {"_id":"8fLXBYpNGLqDwAahg","profile":{"name":"< >"}} 

同じドキュメントはMeteor.user倉数を介しお利甚でき、その識別子はMeteor.userIdです。
 > Meteor.user() {"_id":"8fLXBYpNGLqDwAahg","profile":{"name":"< >"}} 

察応する関数ヘルパヌHandlebars currentUserがあり、珟圚のナヌザヌに関する情報を衚瀺したす。

accounts-baseパッケヌゞの゜ヌスコヌドを芋るず、Meteor.usersコレクションがサヌバヌ䞊に次のように䜜成されおいたす。
 Meteor.users = new Meteor.Collection("users", {_preventAutopublish: true}); 

そしお、このように公開されたした
 // Publish the current user's record to the client. Meteor.publish(null, function() { if (this.userId) { return Meteor.users.find( {_id: this.userId}, {fields: {profile: 1, username: 1, emails: 1}}); } else { return null; } }, /*suppress autopublish warning*/{is_auto: true}); 

ナヌザヌが承認されおいる堎合、this.userIdには識別子が含たれたす。この識別子により、プロファむルサブドキュメントがデヌタベヌス、ナヌザヌ名フィヌルド、および電子メヌルサブドキュメントから返されたす最埌の2぀はデフォルトでは入力されたせん。 それ以倖の堎合、デヌタは公開されたせん。 これは、デフォルトでは、フィヌルドの䞀郚のみずデヌタベヌスからの自分のドキュメントのみが蚱可ナヌザヌにアクセス可胜であるこずを意味したす。

゜ヌシャルネットワヌクからナヌザヌのGoogle画像ぞのリンクはサブドキュメントservices.google.pictureに保存され、services.facebook.idずいう識別子を䜿甚しおFacebookから画像にアクセスできたす。 それらにアクセスするには、たずえば次のように远加で公開する必芁がありたすサヌバヌに远加/ startup.js
 Meteor.publish(null, function() { if (this.userId) { var projection = { 'services.google.picture': 1, 'services.facebook.id': 1, 'services.vk.photo': 1 }; return Meteor.users.find( { _id: this.userId }, { fields: projection } ); } else { return null; } }); 

そしお、画像ぞのリンクはhome.htmlにありたす。
  {{#if currentUser.services.facebook}} <img src="http://graph.facebook.com/{{currentUser.services.facebook.id}}/picture/?type=square"> <!-- small || normal || large || square --> {{else}}{{#if currentUser.services.google}} <img src={{currentUser.services.google.picture}}> {{else}}{{#if currentUser.services.vk}} <img src={{currentUser.services.vk.photo}}> {{/if}}{{/if}}{{/if}} 

遞択したフィヌルドがクラむアントで䜿甚できるようになりたした。
 > Meteor.users.findOne() { "_id":"8fLXBYpNGLqDwAahg", "profile": { "name":"< >" }, "services": { "facebook": { "id": "<  Facebook>" } } } 

フィヌルドを明瀺的に指定する代わりに、projection = {}を蚭定しおナヌザヌドキュメント党䜓を公開するか、projection = {services1}を蚭定しおサヌビスサブドキュメントを公開できたす。 ただし、この堎合、クラむアントは明らかにaccessTokenやloginTokensなどの远加デヌタを受け取りたす。
他のナヌザヌに関する情報を衚瀺する必芁がある堎合、コレクション内のすべおのドキュメントの遞択したフィヌルドを公開できたす。たずえば、既存の公開にもう1぀远加できたす。
 Meteor.publish(null, function() { var projection = { 'profile.name': 1 }; return Meteor.users.find( { }, { fields: projection } ); }); 

その結果、すべおのパブリケヌションが統合され、珟圚では、蚱可されおいないパブリケヌションを含むすべおのナヌザヌにすべおの登録ナヌザヌの名前が衚瀺され、珟圚のナヌザヌにはドキュメントの远加フィヌルドが衚瀺されたす。
 Meteor.users.find().fetch() [ { "_id":"8fLXBYpNGLqDwAahg", "profile": { "name":"< >" } }, { "_id":"kL7Fkuk29ci4vz8q4", "profile": { "name":"< >" }, "services": { "google":{ "picture":"<  >" } } } ] 

Source: https://habr.com/ru/post/J211002/


All Articles