public async Task AntiForgeryMiddleware_RequestWithDisallowedReferer_ShouldReturnBadRequest()
        {
            var token   = Guid.NewGuid().ToString("N");
            var options = new AntiForgeryMiddlewareOptions {
                CookieDataProtector = _dataProtectorMock.Object, OriginValidator = origin => origin.Equals(new Uri("http://localhost:123/"))
            };

            using (var server = TestServer.Create(app =>
            {
                app.Use <AntiForgeryMiddleware>(options);
                app.Use((ctx, next) => Task.CompletedTask);
            }))
                using (var client = server.HttpClient)
                {
                    client.DefaultRequestHeaders.Add("Referer", "https://localhost:123");
                    client.DefaultRequestHeaders.Add("Cookie", $"CSRF={Convert.ToBase64String(Encoding.UTF8.GetBytes(token))}");
                    client.DefaultRequestHeaders.Add("X-CSRF-Token", token);
                    var response = await client.PostAsync("/test", new StringContent("content"));

                    Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
                    var error = await response.Content.ReadAsStringAsync();

                    Assert.That(error, Is.EqualTo("Invalid Origin or Referer request header value"));
                }
        }
        public async Task AntiForgeryMiddleware_CustomCookieDomain_RequestExpectedToken_ShouldAppendCookie()
        {
            var options = new AntiForgeryMiddlewareOptions
            {
                SafeMethods          = new[] { "GET" },
                CookieName           = "Brownie",
                CookieDataProtector  = _dataProtectorMock.Object,
                ExpectedTokenFactory = () => "CookieData",
                CookieDomain         = ".domain.com"
            };

            using (var server = TestServer.Create(app =>
            {
                app.Use <AntiForgeryMiddleware>(options);
                app.Use((ctx, next) => Task.CompletedTask);
            }))
            {
                var response = await server.HttpClient.GetAsync("/auth/token");

                var content = await response.Content.ReadAsStringAsync();

                Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK), content);
                Assert.That(content, Is.EqualTo("CookieData"));
                var setCookie = response.Headers.GetValues("Set-Cookie").FirstOrDefault();
                Assert.That(setCookie, Is.Not.Null, "No cookie set");
                Assert.That(setCookie, Is.EqualTo("Brownie=Q29va2llRGF0YQ%3D%3D; domain=.domain.com; path=/; HttpOnly"));
            }
        }
コード例 #3
0
        public void Validate_CookieDataProtectorIsNull_ShouldThrowException()
        {
            var options = new AntiForgeryMiddlewareOptions {
                CookieDataProtector = null
            };
            var ex = Assert.Throws <ArgumentNullException>(() => options.Validate());

            Assert.That(ex.ParamName, Is.EqualTo("CookieDataProtector"));
        }
        public void AntiForgeryMiddleware_UseMiddleware_ShouldValidateOptions()
        {
            var options = new AntiForgeryMiddlewareOptions {
                ExpectedTokenFactory = null
            };
            var ex = Assert.Throws <TargetInvocationException>(() => TestServer.Create(app => app.Use <AntiForgeryMiddleware>(options)));

            Assert.That((ex?.InnerException as ArgumentNullException)?.ParamName, Is.EqualTo("ExpectedTokenFactory"));
        }
コード例 #5
0
        public void Validate_ExpectedTokenFactoryIsNull_ShouldThrowException()
        {
            var options = new AntiForgeryMiddlewareOptions {
                ExpectedTokenFactory = null
            };
            var ex = Assert.Throws <ArgumentNullException>(() => options.Validate());

            Assert.That(ex.ParamName, Is.EqualTo("ExpectedTokenFactory"));
        }
コード例 #6
0
        public void Validate_HeaderNameIsNullOrEmpty_ShouldThrowException()
        {
            var options = new AntiForgeryMiddlewareOptions {
                HeaderName = null
            };
            var ex = Assert.Throws <ArgumentNullException>(() => options.Validate());

            Assert.That(ex.ParamName, Is.EqualTo("HeaderName"));

            options = new AntiForgeryMiddlewareOptions {
                HeaderName = string.Empty
            };
            ex = Assert.Throws <ArgumentNullException>(() => options.Validate());
            Assert.That(ex.ParamName, Is.EqualTo("HeaderName"));
        }
        public async Task AntiForgeryMiddleware_NonDefaultFailedStatusCode_ShouldReturnFailedStatusCode()
        {
            var options = new AntiForgeryMiddlewareOptions {
                FailureStatusCode = (int)HttpStatusCode.Ambiguous
            };

            using (var server = TestServer.Create(app =>
            {
                app.Use <AntiForgeryMiddleware>(options);
                app.Use((ctx, next) => Task.CompletedTask);
            }))
            {
                var response = await server.HttpClient.PostAsync("/test", new StringContent("content"));

                Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Ambiguous));
            }
        }
        public async Task AntiForgeryMiddleware_SafePathWithoutToken_ShouldReturnOk()
        {
            var options = new AntiForgeryMiddlewareOptions {
                SafePaths = new[] { new PathString("/some/safe/path") }
            };

            using (var server = TestServer.Create(app =>
            {
                app.Use <AntiForgeryMiddleware>(options);
                app.Use((ctx, next) => Task.CompletedTask);
            }))
            {
                var response = await server.HttpClient.PostAsync("/some/safe/path", new StringContent(string.Empty));

                Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK), await response.Content.ReadAsStringAsync());
            }
        }
        public async Task AntiForgeryMiddleware_SafeMethodWithoutToken_ShouldReturnOk()
        {
            var options = new AntiForgeryMiddlewareOptions {
                SafeMethods = new[] { "GET" }
            };

            using (var server = TestServer.Create(app =>
            {
                app.Use <AntiForgeryMiddleware>(options);
                app.Use((ctx, next) => Task.CompletedTask);
            }))
            {
                var response = await server.HttpClient.GetAsync("/test");

                Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK), await response.Content.ReadAsStringAsync());
            }
        }
        public async Task AntiForgeryMiddleware_SafeAuthenticationType_ShouldReturnOk()
        {
            var options = new AntiForgeryMiddlewareOptions {
                SafeAuthenticationTypes = new[] { "jwt" }
            };

            using (var server = TestServer.Create(app =>
            {
                app.Use <DummyJwtMiddleware>(new DummyJwtMiddlewareOptions("jwt"));
                app.Use <AntiForgeryMiddleware>(options);
                app.Use((ctx, next) => Task.CompletedTask);
            }))
            {
                var response = await server.HttpClient.PostAsync("/test", new StringContent("content"));

                Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK), await response.Content.ReadAsStringAsync());
            }
        }
        public async Task AntiForgeryMiddleware_GetRequestToTokenRequestEndpoint_ShouldReturnExpectedToken()
        {
            var token   = Guid.NewGuid().ToString("N");
            var options = new AntiForgeryMiddlewareOptions {
                ExpectedTokenFactory = () => token, TokenRequestEndpoint = new PathString("/fancyendpoint")
            };

            using (var server = TestServer.Create(app =>
            {
                app.Use <AntiForgeryMiddleware>(options);
            }))
            {
                var response = await server.HttpClient.GetAsync("/fancyendpoint");

                var actualToken = await response.Content.ReadAsStringAsync();

                Assert.That(actualToken, Is.EqualTo(token));
            }
        }
        public async Task AntiForgeryMiddleware_NonDefaultFormFieldName_ShouldReturnOk()
        {
            var token   = Guid.NewGuid().ToString("N");
            var options = new AntiForgeryMiddlewareOptions {
                CookieDataProtector = _dataProtectorMock.Object, FormFieldName = "blablabla"
            };

            using (var server = TestServer.Create(app =>
            {
                app.Use <AntiForgeryMiddleware>(options);
                app.Use((ctx, next) => Task.CompletedTask);
            }))
                using (var client = server.HttpClient)
                {
                    client.DefaultRequestHeaders.Add("Origin", "http://localhost");
                    client.DefaultRequestHeaders.Add("Cookie", $"CSRF={Convert.ToBase64String(Encoding.UTF8.GetBytes(token))}");
                    var response = await client.PostAsync("/test", new FormUrlEncodedContent(new[] { new KeyValuePair <string, string>("blablabla", token) }));

                    Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK), await response.Content.ReadAsStringAsync());
                }
        }
        public async Task AntiForgeryMiddleware_MissingCsrfCookie_ShouldReturnBadRequest()
        {
            var options = new AntiForgeryMiddlewareOptions {
                CookieDataProtector = _dataProtectorMock.Object
            };

            using (var server = TestServer.Create(app =>
            {
                app.UseAntiForgeryMiddleware(options);
            }))
                using (var client = server.HttpClient)
                {
                    client.DefaultRequestHeaders.Add("Origin", "http://localhost");
                    var response = await client.PostAsync("/test", new StringContent(string.Empty));

                    Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
                    var error = await response.Content.ReadAsStringAsync();

                    Assert.That(error, Is.EqualTo("Could not extract expected anti-forgery token"));
                }
        }
        public async Task AntiForgeryMiddleware_TokenHeaderMatchesExpectedToken_ShouldReturnOk()
        {
            var token   = Guid.NewGuid().ToString("N");
            var options = new AntiForgeryMiddlewareOptions {
                CookieDataProtector = _dataProtectorMock.Object
            };

            using (var server = TestServer.Create(app =>
            {
                app.Use <AntiForgeryMiddleware>(options);
                app.Use((ctx, next) => Task.CompletedTask);
            }))
                using (var client = server.HttpClient)
                {
                    client.DefaultRequestHeaders.Add("Origin", "http://localhost");
                    client.DefaultRequestHeaders.Add("Cookie", $"CSRF={Convert.ToBase64String(Encoding.UTF8.GetBytes(token))}");
                    client.DefaultRequestHeaders.Add("X-CSRF-Token", token);
                    var response = await client.PostAsync("/test", new StringContent("content"));

                    Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK), await response.Content.ReadAsStringAsync());
                }
        }
        public async Task AntiForgeryMiddleware_RequestExpectedTokenTwice_WithTokenCookieInSecondRequest_ShouldReturnSameTokenTwice()
        {
            var tokenQueue = new Queue <string>(new[] { "AAAA", "ZZZZ" });
            var options    = new AntiForgeryMiddlewareOptions
            {
                SafeMethods          = new[] { "GET" },
                CookieName           = "Brownie",
                CookieDataProtector  = _dataProtectorMock.Object,
                ExpectedTokenFactory = () => tokenQueue.Dequeue()
            };

            using (var server = TestServer.Create(app =>
            {
                app.Use <AntiForgeryMiddleware>(options);
                app.Use((ctx, next) => Task.CompletedTask);
            }))
                using (var client = server.HttpClient)
                {
                    var response = await client.GetAsync("/auth/token");

                    var content = await response.Content.ReadAsStringAsync();

                    Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK), content);
                    Assert.That(content, Is.EqualTo("AAAA"));
                    var setCookie = response.Headers.GetValues("Set-Cookie").FirstOrDefault();
                    Assert.That(setCookie, Is.EqualTo("Brownie=QUFBQQ%3D%3D; path=/; HttpOnly"));

                    client.DefaultRequestHeaders.Add("Cookie", "Brownie=QUFBQQ%3D%3D");

                    response = await client.GetAsync("/auth/token");

                    content = await response.Content.ReadAsStringAsync();

                    Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK), content);
                    Assert.That(content, Is.EqualTo("AAAA"));
                    setCookie = response.Headers.GetValues("Set-Cookie").FirstOrDefault();
                    Assert.That(setCookie, Is.EqualTo("Brownie=QUFBQQ%3D%3D; path=/; HttpOnly"));
                }
        }
        public async Task AntiForgeryMiddleware_RequestExpectedToken_ExpectedTokenFactoryReturnsNullOrEmptyString_ShouldReturnBadRequest()
        {
            var options = new AntiForgeryMiddlewareOptions {
                ExpectedTokenFactory = () => null
            };

            using (var server = TestServer.Create(app =>
            {
                app.Use <AntiForgeryMiddleware>(options);
                app.Use((ctx, next) => Task.CompletedTask);
            }))
            {
                var response = await server.HttpClient.GetAsync("/auth/token");

                Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
                var error = await response.Content.ReadAsStringAsync();

                Assert.That(error, Is.EqualTo("ExpectedTokenFactory did not return a token"));
            }

            options = new AntiForgeryMiddlewareOptions {
                ExpectedTokenFactory = () => string.Empty
            };

            using (var server = TestServer.Create(app =>
            {
                app.Use <AntiForgeryMiddleware>(options);
                app.Use((ctx, next) => Task.CompletedTask);
            }))
            {
                var response = await server.HttpClient.GetAsync("/auth/token");

                Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
                var error = await response.Content.ReadAsStringAsync();

                Assert.That(error, Is.EqualTo("ExpectedTokenFactory did not return a token"));
            }
        }
        public async Task AntiForgeryMiddleware_TokenFormFieldDoesNotMatchExpectedToken_ShouldReturnBadRequest()
        {
            var options = new AntiForgeryMiddlewareOptions {
                CookieDataProtector = _dataProtectorMock.Object
            };

            using (var server = TestServer.Create(app =>
            {
                app.Use <AntiForgeryMiddleware>(options);
                app.Use((ctx, next) => Task.CompletedTask);
            }))
                using (var client = server.HttpClient)
                {
                    client.DefaultRequestHeaders.Add("Origin", "http://localhost");
                    client.DefaultRequestHeaders.Add("Cookie", "CSRF=YQ==");
                    var response = await client.PostAsync("/test", new FormUrlEncodedContent(new[] { new KeyValuePair <string, string>("csrf_token", "actual") }));

                    Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
                    var error = await response.Content.ReadAsStringAsync();

                    Assert.That(error, Is.EqualTo("Invalid anti-forgery token"));
                }
        }
        public async Task AntiForgeryMiddleware_NonSafePathWithoutToken_ShouldReturnBadRequest()
        {
            var options = new AntiForgeryMiddlewareOptions {
                CookieDataProtector = _dataProtectorMock.Object, SafePaths = new[] { new PathString("/some/safe/path") }
            };

            using (var server = TestServer.Create(app =>
            {
                app.Use <AntiForgeryMiddleware>(options);
                app.Use((ctx, next) => Task.CompletedTask);
            }))
                using (var client = server.HttpClient)
                {
                    client.DefaultRequestHeaders.Add("Origin", "http://localhost");
                    client.DefaultRequestHeaders.Add("Cookie", "CSRF=YQ==");
                    var response = await client.PostAsync("/some/nonsafe/path", new StringContent(string.Empty));

                    Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
                    var error = await response.Content.ReadAsStringAsync();

                    Assert.That(error, Is.EqualTo("No anti-forgery token found in X-CSRF-Token header"));
                }
        }
コード例 #19
0
 public static IAppBuilder UseAntiForgeryMiddleware(this IAppBuilder builder, AntiForgeryMiddlewareOptions options)
 => builder.Use <AntiForgeryMiddleware>(options);