private static void InspectBody(ResponseAnalysisContext context)
        {
            string body = context.ReadAsString();

            if (body != null)
            {
                // rewrite HTML
                if (context.IsHtml())
                {
                    foreach (var index in body.AllIndexesOf("http:", StringComparison.OrdinalIgnoreCase))
                    {
                        // make sure it is inside an attribute
                        var attributeName = FastHtmlParser.GetAttributeNameFromValueIndex(body, index);
                        if (attributeName.Equals("src", StringComparison.OrdinalIgnoreCase) ||
                            attributeName.Equals("href", StringComparison.OrdinalIgnoreCase) ||
                            attributeName.Equals("srcset", StringComparison.OrdinalIgnoreCase))
                        {
                            context.AddChange(TextChange.Insert(body, index + "http".Length, "s"));

                            // 'xmlns' excluded
                        }
                    }
                }

                // rewrite CSS
                if (context.IsCss())
                {
                    foreach (var index in body.AllIndexesOf("http:", StringComparison.OrdinalIgnoreCase))
                    {
                        context.AddChange(TextChange.Insert(body, index + "http".Length, "s"));
                    }
                }
            }
        }
Example #2
0
        public void Inspect(ResponseAnalysisContext context, CancellationToken cancellationToken)
        {
            if (context.IsHtml())
            {
                var body = context.ReadAsString();
                if (body != null)
                {
                    foreach (var comment in FastHtmlParser.FindAllComments(body))
                    {
                        if (
                            // respect Knockout.js comments
                            comment.StartsWith("<!-- ko", StringComparison.Ordinal) ||
                            comment.StartsWith("<!-- /ko", StringComparison.Ordinal) ||

                            // respect IE conditional comments
                            comment.StartsWith("<!--[if ", StringComparison.Ordinal) ||
                            comment.StartsWith("[endif]-->", StringComparison.Ordinal)
                            )
                        {
                            continue;
                        }

                        context.AddChange(TextChange.Remove(body, comment.Offset, comment.Length));
                    }
                }
            }
        }
        public void Inspect(ResponseAnalysisContext context, CancellationToken cancellationToken)
        {
            if (context.IsHtml())
            {
                // read content
                string html = context.ReadAsString();
                if (html == null)
                {
                    return;
                }

                string csrfTag = null;

                // enumerate forms
                foreach (var formIndex in FastHtmlParser.FindAllTagIndexes(html, "form"))
                {
                    // check method attribute
                    var method = FastHtmlParser.GetAttributeValueAtTag(html, "method", formIndex);
                    if (method.Equals("post", StringComparison.OrdinalIgnoreCase))
                    {
                        // generate CSRF hidden field
                        if (csrfTag == null)
                        {
                            var tokens = Antiforgery.GetAndStoreTokens(context.HttpContext);
                            csrfTag = $"<input type=\"hidden\" name=\"{HtmlEncoder.Default.Encode(tokens.FormFieldName)}\" value=\"{HtmlEncoder.Default.Encode(tokens.RequestToken)}\" />";
                        }

                        // insert field
                        int close = FastHtmlParser.FindClosePairFlatIndex(html, "form", formIndex);
                        context.AddChange(TextChange.Insert(html, close, csrfTag));
                    }
                }
            }
        }
Example #4
0
        private static void InspectBody(ResponseAnalysisContext context)
        {
            var html = context.ReadAsString();

            if (html != null)
            {
                foreach (var index in FastHtmlParser.FindAllTagIndexes(html, "meta"))
                {
                    if (FastHtmlParser.GetAttributeValueAtTag(html, "name", index).Equals("generator", StringComparison.OrdinalIgnoreCase))
                    {
                        var end = FastHtmlParser.FindEndOfOpenTag(html, index) + 1;
                        context.AddChange(TextChange.Remove(html, index, end - index));
                    }
                }
            }
        }
Example #5
0
        public async Task InspectAsync(ResponseAnalysisContext context, CancellationToken cancellationToken)
        {
            if (context.IsHtml())
            {
                var html = context.ReadAsString();

                // find all script tags
                foreach (var index in FastHtmlParser.FindAllTagIndexes(html, "script"))
                {
                    // get 'src' attribute
                    var src = FastHtmlParser.GetAttributeValueAtTag(html, "src", index);
                    if (src.IndexOf(':') != -1 || src.StartsWith("//", StringComparison.Ordinal))
                    {
                        // check whether there is an 'integrity' attribute alrady
                        var integrity = FastHtmlParser.GetAttributeValueAtTag(html, "integrity", index);
                        if (integrity.Length > 0)
                        {
                            continue;
                        }

                        // compute integrity
                        var sri = await MemoryCache.GetOrCreateAsync($"SRI_{src}", async ce =>
                        {
                            ce.SetAbsoluteExpiration(DateTimeOffset.MaxValue);
                            ce.SetPriority(CacheItemPriority.High);

                            var client = HttpClientFactory.CreateClient();
                            try
                            {
                                // download script
                                using var request = new HttpRequestMessage(HttpMethod.Get, RelativeTo(src).ToString());
                                request.Headers.TryAddWithoutValidation("Origin", $"{context.HttpContext.Request.Scheme}://{context.HttpContext.Request.Host}");
                                using var response = await client.SendAsync(request);
                                if (!response.IsSuccessStatusCode)
                                {
                                    return(null);
                                }

                                if (response.Content == null)
                                {
                                    return(null);
                                }

                                if (!response.Headers.Any(h => h.Key.StartsWith("Access-Control-Allow", StringComparison.OrdinalIgnoreCase)))
                                {
                                    return(null);
                                }

                                var stream = await response.Content.ReadAsStreamAsync();

                                // compute hash
                                var hash   = HashAlgorithmPool.Sha256.ComputeHash(stream);
                                var base64 = Convert.ToBase64String(hash);
                                return($"sha256-{base64}");
                            }
                            catch (HttpRequestException)
                            {
                                return(null);
                            }
                        });

                        // add attribute
                        if (sri != null)
                        {
                            context.AddChange(FastHtmlParser.CreateInsertAttributeChange(html, index, "script", "integrity", sri));
                            if (FastHtmlParser.GetAttributeValueAtTag(html, "crossorigin", index).Length == 0)
                            {
                                context.AddChange(FastHtmlParser.CreateInsertAttributeChange(html, index, "script", "crossorigin", "anonymous"));
                            }
                        }
                    }
                }
            }
        }