web-dev-qa-db-fra.com

Comment puis-je définir l'indicateur «sécurisé» pour les cookies dans un site Web ASP.NET MVC?

J'ai défini les éléments suivants dans web.config:

<system.web>
  <httpCookies httpOnlyCookies="true" requireSSL="true" />
</system.web>

Lorsque je visite le site Web à l'aide d'une connexion HTTP, il redirige vers ma page de connexion (en spécifiant le schéma comme HTTPS). Lorsque le navigateur récupère cette page, la réponse définit des cookies (le cookie de session ASP.NET et le jeton de vérification de la demande pour mon formulaire de connexion):

Set-Cookie: __RequestVerificationToken = IHx8a2zQU374d5CtsoEVW ... YtIc1; chemin = /; HttpOnly Set-Cookie: ASP.NET_SessionId = pfbkkxx2seqhdrxxiodxfbmh; chemin = /; HttpOnly

Ceux-ci ont le drapeau HttpOnly, ce qui est bien - mais ils n'ont PAS le drapeau secure comme décrit ici sur Wikipedia .

Si je me connecte ensuite, un cookie d'authentification est créé, et ceci le fait a le drapeau secure défini:

Set-Cookie: MyWebSite.Authentication = RE3UD ... BDW4; chemin = /; sécurisé ; HttpOnly

Comment puis-je m'assurer que l'indicateur secure est défini sur tous mes cookies?


[~ # ~] mise à jour [~ # ~] : comme demandé, c'est la sortie cURL que j'obtiens (lors de la récupération directe de la page de connexion):

curl https://www.mywebsite.com/Account/Login --verbose --insecure

donne:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
*   Trying 194.73.98.116...
* Connected to www.mywebsite.com (111.11.11.111) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
} [5 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [85 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [2618 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [401 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [138 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
{ [1 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*    subject: OU=Domain Control Validated; CN=*.mywebsite.com
*    start date: 2015-07-29 13:37:38 GMT
*    expire date: 2018-07-29 13:37:38 GMT
*    issuer: C=US; ST=Arizona; L=Scottsdale; O=GoDaddy.com, Inc.; OU=http://certs.godaddy.com/repository/; CN=Go Daddy Secure Certificate Authority - G2
*    SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
} [5 bytes data]
> GET /Account/Login HTTP/1.1
> Host: www.mywebsite.com
> User-Agent: curl/7.43.0
> Accept: */*
> 
{ [5 bytes data]
< HTTP/1.1 200 OK
< Cache-Control: no-cache, no-store, must-revalidate
< Pragma: no-cache
< Content-Type: text/html; charset=utf-8
< Expires: -1
< Server: Microsoft-IIS/8.5
< Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
< X-Frame-Options: Deny
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Content-Security-Policy: default-src 'self';script-src 'self' www.google-analytics.com www.googletagmanager.com;object-src 'none';style-src 'self' fonts.googleapis.com;img-src 'self' www.google-analytics.com placehold.it placeholdit.imgix.net data:;media-src 'none';frame-src 'none';font-src 'self' fonts.gstatic.com;connect-src 'self';base-uri 'self';child-src 'none';frame-ancestors 'none';report-uri /WebResource.axd?cspReport=true
< X-Frame-Options: SAMEORIGIN
< X-Frame-Options: SAMEORIGIN
< Set-Cookie: __RequestVerificationToken=bPWxIp8e4F4I0Jt26t5oZyvDM6059tAWSRbgc-b6Df5IMjyYFDD9fJKgRsKVjbtN3EGgtFuHcf1sTjlYSwDWgnlhSUuNW1q5yv3cGMxmEwE1; path=/; HttpOnly
< Date: Fri, 04 Dec 2015 10:03:35 GMT
< Content-Length: 12596
< 
{ [12596 bytes data]
100 12596  100 12596    0     0  31101      0 --:--:-- --:--:-- --:--:-- 31101
* Connection #0 to Host www.mywebsite.com left intact
13
Gary McGill

La solution suggérée consiste à sécuriser l'ID de session et les cookies de demande de formulaire lors du traitement des demandes de page, par ex.

// This code will mark the forms authentication cookie and the
// session cookie as Secure.
if (Response.Cookies.Count > 0)
{
    foreach (string s in Response.Cookies.AllKeys)
    {
        if (s == FormsAuthentication.FormsCookieName || s.ToLower() == "asp.net_sessionid")
        {
             Response.Cookies[s].Secure = true;
        }
    }
}

ainsi qu'une ligne supplémentaire dans le webconfig pour sécuriser les jetons d'authentification de formulaire:

<authentication mode="Forms">
   <forms ...  requireSSL="true" />
</authentication>

Sources: Sécurisation des cookies Request-Response - Authentification sécurisée des formulaires via Web.config

13
Moby