2017-01-28 12 views
5

पर AJAX पोस्ट को मूल रूप से मेरे वेब एपीआई नियंत्रक में क्रॉस साइट अनुरोध फोर्जरी के खिलाफ सुरक्षा की आवश्यकता है जो एक एमवीसी अनुप्रयोग का हिस्सा है। मैं किसी भी विचार के लिए खुला हूँ। इस बिंदु पर, मेरे पास एक एमवीसी व्यू है जो जावास्क्रिप्ट एपीआई के लिए आर्कजीआईएस का उपयोग करके एएसआई मानचित्र प्रदर्शित करता है। उपयोगकर्ता मानचित्र पर एक मार्ग बनाता है, और मार्ग और विभिन्न सुविधाओं को पार करता है जिसे AJAX पोस्ट के माध्यम से सहेजा जा सकता है। दृश्य में कोई फॉर्म नहीं है। ऐसा इसलिए है क्योंकि सर्वर पर जो डेटा मैं पोस्ट करता हूं वह स्मृति में होता है और स्क्रीन (या छिपे हुए फ़ील्ड में) पर दिखाई नहीं देता है।वेब एपीआई नियंत्रक और सीएसआरएफ

तो, मैं अपने MVC दृश्य में निम्नलिखित antiforgery टोकन प्राप्त करने के लिए:

@functions{ 
public string GetTokenHeaderValue() 
{ 
    string cookieToken, formToken; 
    AntiForgery.GetTokens(null, out cookieToken, out formToken); 
    return cookieToken + ":" + formToken; 
} 
} 

मैं दृश्य में इस छिपे हुए इनपुट था, लेकिन महसूस किया कि यह बुरा है क्योंकि यह दोनों 'फॉर्म टोकन' और है कुकी AntiForgery.Validation के साथ प्रयोग किया टोकन:

<input type="hidden" id="antiforgeryToken" value="@GetTokenHeaderValue()" /> 

फिर, एक अलग JavaScript फ़ाइल में (नहीं दृश्य में स्क्रिप्ट टैग में), मैं एक HTTP POST मेरी वेब एपीआई नियंत्रक को कर रहा हूँ। यह वह जगह है जहाँ मैं अनुरोध हेडर के लिए टोकन जोड़ें:

var headers = {}; 
headers['RequestVerificationToken'] = $("#antiforgeryToken").val(); 
// Ajax POST to Web API Controller 
$.ajax({ 
    async: true, 
    url: '/api/RouteData', 
    type: 'POST', 
    headers: headers, 
    data: requestData, 
    dataType: 'json', 
    error: function (xhr, statusText, errorThrown) { 
     console.log('Error saving route data! ' + errorThrown); 
    }, 
    success: function (result) { 
    } 
}); 

नोट: डेटा है कि शरीर में तैनात किया जा रहा है सभी के लिए एक कस्टम डोजो विजेट के अंदर स्मृति में है (के बाद से पेज के लिए ArcGIS का उपयोग कर एक ESRI नक्शा प्रदर्शित जावास्क्रिप्ट)। वहाँ पेज के बाद से उपयोगकर्ता डेटा में प्रवेश नहीं करता पर एक रूप नहीं है)

एक वेब एपीआई नियंत्रक में एक साथ यह सब मिला कर सर्वर साइड पर:।

[System.Web.Http.HttpPost] 
[ResponseType(typeof(RouteData))] 
public async Task<IHttpActionResult> PostRouteData(RouteDataViewModel routeDataVM) 
{ 
    try 
    { 
     HttpRequestMessage httpRequestMessage = HttpContext.Current.Items["MS_HttpRequestMessage"] as HttpRequestMessage; 
     ValidateRequestHeader(httpRequestMessage); 
    } 
    catch (Exception ex) 
    { 
     _logger.Log(LogLevel.Error, ex, ex.Message); 
     throw; 
    } 
     // Now that we know user is who they say they are, perform update 
} 

void ValidateRequestHeader(HttpRequestMessage request) 
{ 
    string cookieToken = ""; 
    string formToken = ""; 

    IEnumerable<string> tokenHeaders; 
    if (request.Headers.TryGetValues("RequestVerificationToken", out tokenHeaders)) 
    { 
     string[] tokens = tokenHeaders.First().Split(':'); 
     if (tokens.Length == 2) 
     { 
      cookieToken = tokens[0].Trim(); 
      formToken = tokens[1].Trim(); 
     } 
    } 
    AntiForgery.Validate(cookieToken, formToken); 
} 

AntiForgery.Validate क्या सत्यापित करता है टोकन।

मुझे यह SO पोस्ट (http://stackoverflow.com/questions/4074199/jquery-ajax-calls-and-the-html-antiforgerytoken/12116344#12116344 for more possible solutions) दिखाई देता है, जिसने मुझे कुछ विचार दिए हैं, लेकिन मेरे लिए इस मुद्दे को हल नहीं किया है। एएसपीनेट पर इस पोस्ट के कारण बहुत सारे क्रेडिट हैं: https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks

यह मेरे लिए अलग क्या बनाता है (मुझे लगता है) यह है कि मेरी जावास्क्रिप्ट एक अलग फ़ाइल में है और एंटीफॉर्गेरी टोकन प्राप्त करने के लिए सर्वर-साइड रेजर फ़ंक्शन को कॉल नहीं कर सकता है, है ना? बिना किसी फॉर्म के सीएसआरएफ के खिलाफ सुरक्षा के बारे में कोई विचार?

उत्तर

2

सीएसआरएफ सुरक्षा कुछ ऐसा है जो आपको सही करने के लिए अधिनियमित करना चाहिए, क्रॉस साइट अनुरोध जालसाज़ी से रक्षा करें।

एक quick overview of CSRF यह है:

क्रॉस साइट रिक्वेस्ट फोर्जरी (CSRF) एक हमले कि एक अंत उपयोगकर्ता एक वेब अनुप्रयोग है जिसमें वे वर्तमान में प्रमाणित कर रहे हैं पर अवांछित कार्यों को निष्पादित करने के लिए मजबूर करता है। सीएसआरएफ हमले विशेष रूप से राज्य के बदलते अनुरोधों को लक्षित करते हैं, डेटा की चोरी नहीं, क्योंकि हमलावर के पास जाली अनुरोध के जवाब को देखने का कोई तरीका नहीं है। सोशल इंजीनियरिंग की थोड़ी मदद के साथ (जैसे ईमेल या चैट के माध्यम से एक लिंक भेजना), हमलावर हमलावर के चयन के कार्यों को निष्पादित करने के लिए वेब एप्लिकेशन के उपयोगकर्ताओं को धोखा दे सकता है।

निम्नलिखित अपने वेब एपीआई के खिलाफ एक CSRF हमले का एक उदाहरण हो सकता है अगर यह असुरक्षित थे:

<form action="http://yourapi.com/api/DeleteAccount"> 
    <input type="text" name="id" /> 
    <input type="submit" /> 
</form> 

एक समझौता वेबसाइट से भी इस फ़ॉर्म पोस्टिंग, अगर आप का उपयोग कर अपने जाल एपीआई में प्रवेश थे तक कुकी प्रमाणीकरण (एक उदाहरण के रूप में) एक प्रशासनिक खाते के रूप में, यह आपके सिस्टम से खातों को हटाने में सक्षम हो सकता है।

ऐसा इसलिए होता है क्योंकि जब आप अपने एपीआई पर रीडायरेक्ट होते हैं, तो आपका ब्राउज़र yourapi.com डोमेन के विरुद्ध संग्रहीत कुकी में गुजर रहा है, इस प्रकार उपयोगकर्ता को प्रमाणित करता है और आवश्यक कार्रवाई कर रहा है। यह हमला वेक्टर आपके एपीआई के साथ प्रमाणित करने के लिए, एक भालू टोकन का उपयोग करने से अलग है, क्योंकि तीसरे पक्ष को इस टोकन का कोई ज्ञान नहीं होगा।

जैसा कि आपने सही तरीके से कहा और कार्यान्वित किया है, एंटी-फोर्जरी टोकन का उपयोग क्लाइंट को वेब प्रतिक्रिया में भेजे गए जेनरेट किए गए टोकन के रूप में से बचा सकता है, और फिर क्लाइंट द्वारा बैक अप भेजा जाता है और उसे सत्यापित किया जाता है सुनिश्चित करें कि यह कहीं से हम एक अनुरोध अनुरोध है। एक भालू टोकन की तरह, किसी तीसरे पक्ष को उस टोकन का कोई ज्ञान नहीं हो सकता जिसे आपने सर्वर से आपके अनुरोध में भेजा है। इस संबंध में, आपने जो कार्यान्वित किया है वह बिल्कुल सही है और क्लाइंट को टोकन पास करने का तरीका यह है कि हम इसे कैसे काम करेंगे।

ASP.NET MVC (बिना एपीआई) इस रूप में लागू किया जाता है इस प्रकार है:

<form .. /> 
    @Html.AntiForgeryToken() 
</form> 

.. और साथ मान्य सर्वर साइड:

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Action(MyModel model) 
{ 
    // .. 
} 

जब आप @Html.AntiForgeryToken() फोन, विधि दोनों सेट एक कुकी (कुकी टोकन युक्त) और इसे क्लाइंट को भेजती है, और क्लाइंट को भेजने के लिए <input type="hidden" ..> टैग भी उत्पन्न करती है। ये दोनों बैक अप और सत्यापित सर्वर पक्ष भेजा जाता है।

उस ज्ञान के साथ सशस्त्र, आप देख सकते हैं कि "कुकी टोकन" और "फॉर्म टोकन" दोनों भेजने के बारे में आपकी चिंता निराधार है क्योंकि वैसे भी यही होता है।

मुझे चिंता का कारण दिखाई देता है, लेकिन आप जो भी कम करने की कोशिश कर रहे हैं वह सीएसआरएफ की बजाय मध्य (मिटएम) हमले में एक आदमी प्रतीत होता है। मिटएम हमलों के बड़े अनुपात के आसपास काम करने के लिए आपको यह सुनिश्चित करना चाहिए कि आपकी साइट/एपीआई दोनों एचटीटीपीएस पर चल रही हैं। यदि आपका ग्राहक अभी भी मिटएम हमले के लिए अतिसंवेदनशील है, तो आपका एपीआई शायद हमलावर के लिए कम से कम चिंता का विषय होगा।

+1

आपकी व्याख्या बहुत उपयोगी और पूरी तरह से है। मैं एचटीएमएल.एन्टीफोर्गेरी टोकन के एमवीसी उपयोग के आसपास अपने दिमाग को लपेटने में सक्षम था, लेकिन एंटीफॉर्गेरी.गेटोकोकेंस का उपयोग करते समय मैं वास्तव में रक्षा कर रहा था कि टोकन के साथ विधि का उपयोग करने के लिए थोड़ा अलग दृष्टिकोण के कारण मैं उलझन में था। – iCode

+1

कोई समस्या नहीं @iCode - यदि आपका वेब एपीआई और एमवीसी एप्लीकेशन एक ही डोमेन पर हैं, तो आप अभी भी '@ Html.AntiForgeryToken()' का उपयोग कर सकते हैं और जेएस के माध्यम से फॉर्म टोकन खींच सकते हैं, कुकी टोकन निश्चित रूप से भेजा जाएगा उस डोमेन के खिलाफ एक कुकी होने की प्रकृति द्वारा अगला अनुरोध। अधिक जानकारी आपके लिंक किए गए उत्तर से हैं: http://stackoverflow.com/a/4074289/698179 –

+1

आह हाँ। मेरा वेब एपीआई और एमवीसी ऐप एक ही डोमेन पर हैं। अब मैं अपनी समझ में पूर्ण सर्कल आया हूं। वास्तव में मैं फॉर्म टोकन और कुकी (कुकी टोकन युक्त) उत्पन्न करने के उद्देश्य से एक साधारण रूप बना सकता हूं। ऐसा लगता है कि मैं अपने AJAX पोस्ट पर डेटा पैरामीटर में फॉर्म टोकन डालने के लिए जेएस का उपयोग करता हूं। मुझे लगता है कि इसे JSON ऑब्जेक्ट के अतिरिक्त जोड़ा जा सकता है जिसे मैं पहले ही पोस्ट करने के लिए डेटा के रूप में सेट कर रहा हूं। मैं दोनों विधियों को जानने के लिए इसका परीक्षण करूंगा। – iCode

1

दूसरों के साथ कुछ चर्चा के बाद, ऐसा प्रतीत होता है कि मैंने जो समाधान लागू किया है वह वास्तव में ठीक है। हां, दोनों टोकन छुपा इनपुट फ़ील्ड में हैं। हालांकि, सीएसआरएफ के खिलाफ सुरक्षा के लिए क्या प्रयास कर रहा है - अन्यसाइट आपकी ओर से पोस्ट करने का प्रयास कर रहा है - यह समाधान ठीक काम करता है। अगर मैं अपनी साइट पर हूं, प्रमाणीकृत हूं, और दूसरी ओर ब्राउज़ करता हूं जो मेरी तरफ से पोस्ट करने का प्रयास करता है, तो साइट के पास जरूरी टोकन नहीं होंगे।

संबंधित मुद्दे