示例#1
0
        /// <summary>
        /// Perform any initialisation tasks
        /// </summary>
        /// <param name="pipelines">Application pipelines</param>
        public void Initialize(IPipelines pipelines)
        {
            pipelines.AfterRequest.AddItemToEndOfPipeline(
                context =>
            {
                if (context.Response == null || context.Response.Cookies == null)
                {
                    return;
                }

                if (context.Items.ContainsKey(CsrfToken.DEFAULT_CSRF_KEY))
                {
                    context.Response.Cookies.Add(new NancyCookie(CsrfToken.DEFAULT_CSRF_KEY, (string)context.Items[CsrfToken.DEFAULT_CSRF_KEY], true));
                    return;
                }

                if (context.Request.Cookies.ContainsKey(CsrfToken.DEFAULT_CSRF_KEY))
                {
                    context.Items[CsrfToken.DEFAULT_CSRF_KEY] = HttpUtility.UrlDecode(context.Request.Cookies[CsrfToken.DEFAULT_CSRF_KEY]);
                    return;
                }

                var token = new CsrfToken
                {
                    CreatedDate = DateTime.Now,
                };
                token.CreateRandomBytes();
                token.CreateHmac(CryptographyConfiguration.HmacProvider);
                var tokenString = ObjectSerializer.Serialize(token);

                context.Items[CsrfToken.DEFAULT_CSRF_KEY] = tokenString;
                context.Response.Cookies.Add(new NancyCookie(CsrfToken.DEFAULT_CSRF_KEY, tokenString, true));
            });
        }
        public void Should_return_token_mismatch_if_random_bytes_empty()
        {
            DateTime date = DateTime.Now;
            var tokenOne = new CsrfToken { CreatedDate = date, RandomBytes = ArrayCache.Empty<byte>() };
            var tokenTwo = new CsrfToken { CreatedDate = date, RandomBytes = ArrayCache.Empty<byte>() };
            tokenOne.CreateHmac(this.hmacProvider);
            tokenTwo.CreateHmac(this.hmacProvider);

            var result = this.validator.Validate(tokenOne, tokenTwo);

            result.ShouldEqual(CsrfTokenValidationResult.TokenTamperedWith);
        }
        public void Should_return_token_ok_if_tokens_match_and_no_expiry_set()
        {
            DateTime date = DateTime.Now;
            var tokenOne = new CsrfToken { CreatedDate = date, RandomBytes = new byte[] { 1, 2, 3 } };
            var tokenTwo = new CsrfToken { CreatedDate = date, RandomBytes = new byte[] { 1, 2, 3 } };
            tokenOne.CreateHmac(this.hmacProvider);
            tokenTwo.CreateHmac(this.hmacProvider);

            var result = this.validator.Validate(tokenOne, tokenTwo);

            result.ShouldEqual(CsrfTokenValidationResult.Ok);
        }
        public void Should_return_token_mismatch_if_tokens_differ()
        {
            DateTime date = DateTime.Now;
            var tokenOne = new CsrfToken { CreatedDate = date, RandomBytes = new byte[] { 1, 2, 3 } };
            var tokenTwo = new CsrfToken { CreatedDate = date, RandomBytes = new byte[] { 1, 4, 3 } };
            tokenOne.CreateHmac(this.hmacProvider);
            tokenTwo.CreateHmac(this.hmacProvider);

            var result = this.validator.Validate(tokenOne, tokenTwo);

            result.ShouldEqual(CsrfTokenValidationResult.TokenMismatch);
        }
示例#5
0
文件: Csrf.cs 项目: lukywong/Nancy
        /// <summary>
        /// Creates a new csrf token for this response with an optional salt.
        /// Only necessary if a particular route requires a new token for each request.
        /// </summary>
        /// <param name="module">Nancy module</param>
        /// <returns></returns>
        public static void CreateNewCsrfToken(this INancyModule module)
        {
            var token = new CsrfToken
            {
                CreatedDate = DateTime.Now,
            };
            token.CreateRandomBytes();
            token.CreateHmac(CsrfApplicationStartup.CryptographyConfiguration.HmacProvider);

            var tokenString = CsrfApplicationStartup.ObjectSerializer.Serialize(token);

            module.Context.Items[CsrfToken.DEFAULT_CSRF_KEY] = tokenString;
        }
示例#6
0
        /// <summary>
        /// Creates a new csrf token with an optional salt.
        /// Does not store the token in context.
        /// </summary>
        /// <returns>The generated token</returns>
        internal static string GenerateTokenString(CryptographyConfiguration cryptographyConfiguration = null)
        {
            cryptographyConfiguration = cryptographyConfiguration ?? CsrfApplicationStartup.CryptographyConfiguration;
            var token = new CsrfToken
            {
                CreatedDate = DateTime.Now,
            };

            token.CreateRandomBytes();
            token.CreateHmac(cryptographyConfiguration.HmacProvider);
            var tokenString = CsrfApplicationStartup.ObjectSerializer.Serialize(token);

            return(tokenString);
        }
示例#7
0
        /// <summary>
        /// Creates a new csrf token for this response with an optional salt.
        /// Only necessary if a particular route requires a new token for each request.
        /// </summary>
        /// <param name="module">Nancy module</param>
        /// <returns></returns>
        public static void CreateNewCsrfToken(this NancyModule module)
        {
            var token = new CsrfToken
            {
                CreatedDate = DateTime.Now,
            };

            token.CreateRandomBytes();
            token.CreateHmac(CsrfApplicationStartup.CryptographyConfiguration.HmacProvider);

            var tokenString = CsrfApplicationStartup.ObjectSerializer.Serialize(token);

            module.Context.Items[CsrfToken.DEFAULT_CSRF_KEY] = tokenString;
        }
        public void Should_return_token_tampered_with_if_hmac_incorrect()
        {
            DateTime date = DateTime.Now;
            var tokenOne = new CsrfToken { CreatedDate = date, RandomBytes = new byte[] { 1, 2, 3 } };
            var tokenTwo = new CsrfToken { CreatedDate = date, RandomBytes = new byte[] { 1, 2, 3 } };
            tokenOne.CreateHmac(this.hmacProvider);
            tokenTwo.CreateHmac(this.hmacProvider);
            tokenOne.Hmac[0] -= 1;
            tokenTwo.Hmac[0] -= 1;

            var result = this.validator.Validate(tokenOne, tokenTwo);

            result.ShouldEqual(CsrfTokenValidationResult.TokenTamperedWith);
        }
示例#9
0
文件: Csrf.cs 项目: JulianRooze/Nancy
        /// <summary>
        /// Enables Csrf token generation.
        /// This is disabled by default.
        /// </summary>
        /// <param name="pipelines">Application pipelines</param>
        public static void Enable(IPipelines pipelines, CryptographyConfiguration cryptographyConfiguration = null)
        {
            cryptographyConfiguration = cryptographyConfiguration ?? CsrfApplicationStartup.CryptographyConfiguration;

            var postHook = new PipelineItem<Action<NancyContext>>(
                CsrfHookName,
                context =>
                {
                    if (context.Response == null || context.Response.Cookies == null || context.Request.Method.Equals("OPTIONS", StringComparison.OrdinalIgnoreCase))
                    {
                        return;
                    }

                    if (context.Items.ContainsKey(CsrfToken.DEFAULT_CSRF_KEY))
                    {
                        context.Response.Cookies.Add(new NancyCookie(CsrfToken.DEFAULT_CSRF_KEY,
                                                                     (string)context.Items[CsrfToken.DEFAULT_CSRF_KEY],
                                                                     true));
                        return;
                    }

                    if (context.Request.Cookies.ContainsKey(CsrfToken.DEFAULT_CSRF_KEY))
                    {
                        var decodedValue = HttpUtility.UrlDecode(context.Request.Cookies[CsrfToken.DEFAULT_CSRF_KEY]);
                        var cookieToken = CsrfApplicationStartup.ObjectSerializer.Deserialize(decodedValue) as CsrfToken;

                        if (CsrfApplicationStartup.TokenValidator.CookieTokenStillValid(cookieToken))
                        {
                            context.Items[CsrfToken.DEFAULT_CSRF_KEY] = decodedValue;
                            return;
                        }
                    }

                    var token = new CsrfToken
                    {
                        CreatedDate = DateTime.Now,
                    };
                    token.CreateRandomBytes();
                    token.CreateHmac(cryptographyConfiguration.HmacProvider);
                    var tokenString = CsrfApplicationStartup.ObjectSerializer.Serialize(token);

                    context.Items[CsrfToken.DEFAULT_CSRF_KEY] = tokenString;
                    context.Response.Cookies.Add(new NancyCookie(CsrfToken.DEFAULT_CSRF_KEY, tokenString, true));
                });

            pipelines.AfterRequest.AddItemToEndOfPipeline(postHook);
        }
        /// <summary>
        /// Enables Csrf token generation.
        /// This is disabled by default.
        /// </summary>
        /// <param name="pipelines">Application pipelines</param>
        public static void Enable(IPipelines pipelines, CryptographyConfiguration cryptographyConfiguration = null)
        {
            cryptographyConfiguration = cryptographyConfiguration ?? CsrfApplicationStartup.CryptographyConfiguration;

            var postHook = new PipelineItem <Action <NancyContext> >(
                CsrfHookName,
                context =>
            {
                if (context.Response == null || context.Response.Cookies == null || context.Request.Method.Equals("OPTIONS", StringComparison.OrdinalIgnoreCase))
                {
                    return;
                }

                if (context.Items.ContainsKey(CsrfToken.DEFAULT_CSRF_KEY))
                {
                    context.Response.Cookies.Add(new NancyCookie(CsrfToken.DEFAULT_CSRF_KEY,
                                                                 (string)context.Items[CsrfToken.DEFAULT_CSRF_KEY],
                                                                 true));
                    return;
                }

                if (context.Request.Cookies.ContainsKey(CsrfToken.DEFAULT_CSRF_KEY))
                {
                    var decodedValue = HttpUtility.UrlDecode(context.Request.Cookies[CsrfToken.DEFAULT_CSRF_KEY]);
                    var cookieToken  = CsrfApplicationStartup.ObjectSerializer.Deserialize(decodedValue) as CsrfToken;

                    if (CsrfApplicationStartup.TokenValidator.CookieTokenStillValid(cookieToken))
                    {
                        context.Items[CsrfToken.DEFAULT_CSRF_KEY] = decodedValue;
                        return;
                    }
                }

                var token = new CsrfToken
                {
                    CreatedDate = DateTime.Now,
                };
                token.CreateRandomBytes();
                token.CreateHmac(cryptographyConfiguration.HmacProvider);
                var tokenString = CsrfApplicationStartup.ObjectSerializer.Serialize(token);

                context.Items[CsrfToken.DEFAULT_CSRF_KEY] = tokenString;
                context.Response.Cookies.Add(new NancyCookie(CsrfToken.DEFAULT_CSRF_KEY, tokenString, true));
            });

            pipelines.AfterRequest.AddItemToEndOfPipeline(postHook);
        }
        /// <summary>
        /// Validates a pair of tokens
        /// </summary>
        /// <param name="tokenOne">First token (usually from either a form post or querystring)</param>
        /// <param name="tokenTwo">Second token (usually from a cookie)</param>
        /// <param name="validityPeriod">Optional period that the tokens are valid for</param>
        /// <returns>Token validation result</returns>
        public CsrfTokenValidationResult Validate(CsrfToken tokenOne, CsrfToken tokenTwo, TimeSpan?validityPeriod = new TimeSpan?())
        {
            if (tokenOne == null || tokenTwo == null)
            {
                return(CsrfTokenValidationResult.TokenMissing);
            }

            if (!tokenOne.Equals(tokenTwo))
            {
                return(CsrfTokenValidationResult.TokenMismatch);
            }

            if (tokenOne.RandomBytes == null || tokenOne.RandomBytes.Length == 0)
            {
                return(CsrfTokenValidationResult.TokenTamperedWith);
            }

            var newToken = new CsrfToken
            {
                CreatedDate = tokenOne.CreatedDate,
                RandomBytes = tokenOne.RandomBytes,
            };

            newToken.CreateHmac(this.hmacProvider);
            if (!newToken.Hmac.SequenceEqual(tokenOne.Hmac))
            {
                return(CsrfTokenValidationResult.TokenTamperedWith);
            }

            if (validityPeriod.HasValue)
            {
                var expiryDate = tokenOne.CreatedDate.Add(validityPeriod.Value);

                if (DateTime.Now > expiryDate)
                {
                    return(CsrfTokenValidationResult.TokenExpired);
                }
            }

            return(CsrfTokenValidationResult.Ok);
        }
示例#12
0
        /// <summary>
        /// Creates a new csrf token with an optional salt.
        /// Does not store the token in context.
        /// </summary>
        /// <returns>The generated token</returns>
        internal static string GenerateTokenString(CryptographyConfiguration cryptographyConfiguration = null)
        {
            cryptographyConfiguration = cryptographyConfiguration ?? CsrfApplicationStartup.CryptographyConfiguration;
            var token = new CsrfToken
            {
                CreatedDate = DateTimeOffset.Now
            };

            token.CreateRandomBytes();
            token.CreateHmac(cryptographyConfiguration.HmacProvider);

            var builder = new StringBuilder();

            builder.AppendFormat("RandomBytes{0}{1}", ValueDelimiter, Convert.ToBase64String(token.RandomBytes));
            builder.Append(PairDelimiter);
            builder.AppendFormat("Hmac{0}{1}", ValueDelimiter, Convert.ToBase64String(token.Hmac));
            builder.Append(PairDelimiter);
            builder.AppendFormat("CreatedDate{0}{1}", ValueDelimiter, token.CreatedDate.ToString("o", CultureInfo.InvariantCulture));

            return(builder.ToString());
        }
        /// <summary>
        /// Validates that a cookie token is still valid with the current configuration / keys
        /// </summary>
        /// <param name="cookieToken">Token to validate</param>
        /// <returns>True if valid, false otherwise</returns>
        public bool CookieTokenStillValid(CsrfToken cookieToken)
        {
            if (cookieToken == null || cookieToken.RandomBytes == null || cookieToken.RandomBytes.Length == 0)
            {
                return false;
            }

            var newToken = new CsrfToken
            {
                CreatedDate = cookieToken.CreatedDate,
                RandomBytes = cookieToken.RandomBytes,
            };
            newToken.CreateHmac(this.hmacProvider);

            if (!newToken.Hmac.SequenceEqual(cookieToken.Hmac))
            {
                return false;
            }

            return true;
        }
示例#14
0
        /// <summary>
        /// Validates a pair of tokens
        /// </summary>
        /// <param name="tokenOne">First token (usually from either a form post or querystring)</param>
        /// <param name="tokenTwo">Second token (usually from a cookie)</param>
        /// <param name="validityPeriod">Optional period that the tokens are valid for</param>
        /// <returns>Token validation result</returns>
        public CsrfTokenValidationResult Validate(CsrfToken tokenOne, CsrfToken tokenTwo, TimeSpan? validityPeriod = new TimeSpan?())
        {
            if (tokenOne == null || tokenTwo == null)
            {
                return CsrfTokenValidationResult.TokenMissing;
            }

            if (!tokenOne.Equals(tokenTwo))
            {
                return CsrfTokenValidationResult.TokenMismatch;
            }

            if (tokenOne.RandomBytes == null || tokenOne.RandomBytes.Length == 0)
            {
                return CsrfTokenValidationResult.TokenTamperedWith;
            }

            var newToken = new CsrfToken
                               {
                                   CreatedDate = tokenOne.CreatedDate,
                                   RandomBytes = tokenOne.RandomBytes,
                               };
            newToken.CreateHmac(this.hmacProvider);
            if (!newToken.Hmac.SequenceEqual(tokenOne.Hmac))
            {
                return CsrfTokenValidationResult.TokenTamperedWith;
            }

            if (validityPeriod.HasValue)
            {
                var expiryDate = tokenOne.CreatedDate.Add(validityPeriod.Value);

                if (DateTime.Now > expiryDate)
                {
                    return CsrfTokenValidationResult.TokenExpired;
                }
            }

            return CsrfTokenValidationResult.Ok;
        }
        /// <summary>
        /// Validates that a cookie token is still valid with the current configuration / keys
        /// </summary>
        /// <param name="cookieToken">Token to validate</param>
        /// <returns>True if valid, false otherwise</returns>
        public bool CookieTokenStillValid(CsrfToken cookieToken)
        {
            if (cookieToken == null || cookieToken.RandomBytes == null || cookieToken.RandomBytes.Length == 0)
            {
                return(false);
            }

            var newToken = new CsrfToken
            {
                CreatedDate = cookieToken.CreatedDate,
                RandomBytes = cookieToken.RandomBytes,
            };

            newToken.CreateHmac(this.hmacProvider);

            if (!newToken.Hmac.SequenceEqual(cookieToken.Hmac))
            {
                return(false);
            }

            return(true);
        }
示例#16
0
文件: Csrf.cs 项目: rdterner/Nancy
 /// <summary>
 /// Creates a new csrf token with an optional salt.
 /// Does not store the token in context.
 /// </summary>
 /// <returns>The generated token</returns>
 internal static string GenerateTokenString(CryptographyConfiguration cryptographyConfiguration = null)
 {
     cryptographyConfiguration = cryptographyConfiguration ?? CsrfApplicationStartup.CryptographyConfiguration;
     var token = new CsrfToken
     {
         CreatedDate = DateTime.Now,
     };
     token.CreateRandomBytes();
     token.CreateHmac(cryptographyConfiguration.HmacProvider);
     var tokenString = CsrfApplicationStartup.ObjectSerializer.Serialize(token);
     return tokenString;
 }
示例#17
0
        /// <summary>
        /// Perform any initialisation tasks
        /// </summary>
        /// <param name="pipelines">Application pipelines</param>
        public void Initialize(IPipelines pipelines)
        {
            pipelines.AfterRequest.AddItemToEndOfPipeline(
                context =>
                    {
                        if (context.Response == null || context.Response.Cookies == null)
                        {
                            return;
                        }

                        if (context.Items.ContainsKey(CsrfToken.DEFAULT_CSRF_KEY))
                        {
                            context.Response.Cookies.Add(new NancyCookie(CsrfToken.DEFAULT_CSRF_KEY, (string)context.Items[CsrfToken.DEFAULT_CSRF_KEY], true));
                            return;
                        }

                        if (context.Request.Cookies.ContainsKey(CsrfToken.DEFAULT_CSRF_KEY))
                        {
                            context.Items[CsrfToken.DEFAULT_CSRF_KEY] = HttpUtility.UrlDecode(context.Request.Cookies[CsrfToken.DEFAULT_CSRF_KEY]);
                            return;
                        }

                        var token = new CsrfToken
                        {
                            CreatedDate = DateTime.Now,
                        };
                        token.CreateRandomBytes();
                        token.CreateHmac(CryptographyConfiguration.HmacProvider);
                        var tokenString = ObjectSerializer.Serialize(token);

                        context.Items[CsrfToken.DEFAULT_CSRF_KEY] = tokenString;
                        context.Response.Cookies.Add(new NancyCookie(CsrfToken.DEFAULT_CSRF_KEY, tokenString, true));
                    });
        }
        public void Should_return_token_expired_if_it_has()
        {
            DateTime date = DateTime.Now.AddHours(-1);
            var tokenOne = new CsrfToken { CreatedDate = date, RandomBytes = new byte[] { 1, 2, 3 } };
            var tokenTwo = new CsrfToken { CreatedDate = date, RandomBytes = new byte[] { 1, 2, 3 } };
            tokenOne.CreateHmac(this.hmacProvider);
            tokenTwo.CreateHmac(this.hmacProvider);

            var result = this.validator.Validate(tokenOne, tokenTwo, validityPeriod: new TimeSpan(0, 30, 0));

            result.ShouldEqual(CsrfTokenValidationResult.TokenExpired);
        }