ノードは、セキュリティ上の問題に注意を払わなければならないのが比較的容易であるが、Webアプリケーションでは、データがアップロードされたWebアプリケーションの多様性を構築する比較的低レベルのAPIを提供します。ノードとフロントのJavascriptの親戚ので、Javascriptをフロントエンドでも実行するには、サーバーに直接アップロードすることができますが、ここでは、そのような危険な行動については説明しませんが、メモリCSRFと関連するセキュリティの問題について説明します。
1.メモリの制限
ユーザーの解析は、我々が採用している戦略は、すべてのデータを保存するときに、フォーム、JSONやXMLを送信して、プロセスを分析し、最終的にはビジネス・ロジックに渡されます。この戦略は、潜在的な問題は、少量のデータは、リクエストを送信するために、データが大きすぎると、占有メモリ光の状況が発生するのが唯一適していることです。提出につきコンテンツの攻撃者が1メガバイトた場合、攻撃者のクライアントは、非常に簡単に限り、同時要求の数が多い、メモリはすぐに食べられるように、大量のデータを偽造シミュレートすることができます。
この問題を解決するために2つのソリューションがあります。
アップロードの上限サイズが、上限を超えると、データ400とレスポンスステータスコードの受信を停止します。
ノードのみ他の小さなデータファイルのパスを残して、ディスクに向けられたデータストリームを解析してストリーム。
まず紹介する接続制限の方法で採用アップロードフレームデータ量を、次のとおりです。
1024バイト=定数; (REQ、RES) => { 受付LETは = 0 、 CONST LEN = req.headers [ 'のContent-Length']のparseInt(req.headers [ 'のContent-Length']、10):? ヌル。 // コンテンツの長さが制限を超えた場合、エンティティの要求のステータスを返す長い IF(LEN && LEN> バイト){ res.writeHead( 413 ); res.end(); リターン; } // 制限 req.on(「データ」、関数(チャンク){ 受付 + = chunk.length IF(>受信バイト){ //データを受信し、トリガ・エンド()停止 ; req.destroy() } }) ハンドル(REQ、RES) }
我々は、直接、コンテンツ長を含むデータ要求は、パケット長が制限を超えているか否かを判定し、上記のコードから複数の413応答ステータスコードを見ることができます。何のContent-Length要求メッセージが存在しないために、いくつかはあなたが各イベントのデータを決定することができ、より簡単です。一旦限界値を超えると、サーバは、新たなデータセグメントを受け入れる停止します。これはJSONまたはXMLファイルである場合は、最も可能性の高い決意を完了できません。オンラインのWebアプリケーションの場合、アップロードのサイズ制限は、攻撃が発生した場合に、静かに落ち着かことができ、保護サーバーに非常に助長している追加します。
2. CSRF
CSRFは、中国は、クロスサイトリクエストフォージェリを意味し、クロスサイトリクエストフォージェリの略です。一般的には、サーバーを特定し、クッキーによってユーザーとクライアントを認証するために、サーバー側のセッションIDにアクセスするには、ブラウザを介してユーザーは、第三者が知ることができないが、ユーザーを聞かせすることができるようになりますCSRFの攻撃者がセッションIDを知っている必要はありません。トリック。
CSRF攻撃はプロセスである方法の詳細については、ここでは、メッセージを説明するために例を取ります。以下に示すように、ウェブサイトは、そのようなプログラムメッセージ、インタフェースの提出のメッセージを持っていると仮定します。
http:// domain_a.com/guestbook
ユーザが投稿したコンテンツフィールドは、POSTメッセージによって成功することができます。サーバーから自動的にセッションデータは、以下に示すように、データベースにデータを書き込むために、ユーザー名とupdatedAt二つのフィールドを持った後、提出されたデータが誰であるかを決定します。
(REQ、RES)=> { // req.body.contentフレームから接続 =定数コンテンツreq.body.content ||「」; // 自分自身を達成するために必要なセッションは、上記セッション達成されたと仮定する = CONSTユーザ名REQを.session.username; CONSTフィードバック = { ユーザー名:ユーザー名、 コンテンツ:コンテンツ、 updatedAt:Date.now() }; // ここでは、データベースの独自の種類使用する修正 db.save(フィードバック、ERR => { RESを。書込みヘッド( 200で); res.end( 'OK' ); }); }
コメントを提出した通常の状況下では、誰がリストに情報が表示されます。攻撃者はインターフェイスを識別している場合は、次のようにCSRFの脆弱性は、その後、彼は別のサイト(http://domain_b.com/attack)フォームの送信に構築することができ、ここに存在します。
< フォームID = "テスト" 方法= "POST" アクション= "http://domain_a.com/guestbook" > < 入力タイプ= "隠し" 名= "コンテンツ" 値= "VIM是这个世界上最好的编辑器」 /> </ フォーム> < スクリプトタイプ= "テキスト/ javascriptの" > $(関数(){ $(" #test " ).submit(); }); </ スクリプト>
この場合には、限り、攻撃者はこのサイトを参照してくださいDOMAIN_BユーザーログインDOMAIN_Aをおびき寄せるためとして、それが自動的にメッセージを送信します。DOMAIN_Aプロセスの提出以来、ユーザーの知識をブラウザが要求がDOMAIN_Bから来ているにもかかわらず、サーバーに送信されたクッキーをDOMAIN_Aますが、サーバーは知りませんでした。
上記のプロセスは、CSRF攻撃方法です。次に被害の程度を想像することができる抜け穴転送インタフェースは、存在する場合ここで、脆弱性のメッセージの一例です。
著者は、データを受信したノードを渡すことは非常に簡単ですが、一方でセキュリティ上の懸念は依然として無視できません。幸いな防衛CSRF不可能ではない、解決策は、次のようにCSRF攻撃は、ランダムな値であり、追加します。
CONST generateRandom = 関数(LEN){ 戻り crypto.randomBytes(Math.ceil(LEN * 3月4日)) .toString( 'BASE64' ) .slice( 0 、LEN)を }
次のようにそれは、セッション内のランダムな値を与えられたユーザのための各要求、です。
constのトークン= req.session._csrf || (req.session._csrf = generateRandom(24))。
ページのレンダリング処理を行うことで、広告_csrf値のフロントエンドは、次のように:
< フォームID = "テスト" 方法= "POST" アクション= "http://domain_a.com/guestbook" > < 入力タイプ= "隠し" 名= "コンテンツ" 値= "VIM是这个世界上最好的编辑器」 /> < 入力タイプ= "隠し" 名= "_ CSRF" 値= "<%= _ CSRF%>" /> </ 構成>
この値はランダムな値であるため、同じランダムな値を構築することは困難で、攻撃者は非常に大きいので、我々は唯一以下に示すように、チェックが簡単に、要求が受信側で鍛造されているかどうかを識別することができます実行する必要があります。
(REQ、RES)=> { CONSTトークン = req.session._csrf || (req.session._csrf = generateRandom(24 ))。 constの_csrf = req.body._csrf。 場合(トークン==!_csrf){ res.writeHead( 403 ); res.end( "禁止访问" ); } 他{ ハンドル(REQ、RES)。 } }
_csrfフィールドはまた、クエリ文字列または要求ヘッダーに存在してもよいです。