Interactions Structure
Interactions that the user had with a rendered page (only applicable when you use UserDiscovery)
Namespace:
Walter.Web.FireWallAssembly: Walter.Web.FireWall (in Walter.Web.FireWall.dll)
Remarks
Examples
inject JavaScript from the same constant used in the rout of the ValidateUser endpoint
<script src="@Url.Content(Links.UserEndpointJavaScript)"></script>
Register interactions of the user
[HttpGet] [Route(Links.UserEndpointJavaScript)] [AllowAnonymous, Ignore(Walter.Web.FireWall.Filters.FireWallGuardActions.EmbeddedResources)] [NoCache] public FileContentResult ValidateUser() { //use the ID to force reloading the script after the user has logged in or logged off//as the firewall will create a different script for logged in users.try { if (_fireWall.TryGetValidateUserJavaScript(page: _page, out var javaScript)) { var file = File(fileContents: javaScript, contentType: "text/javascript"); file.LastModified = DateTime.UtcNow; file.FileDownloadName = _page.OriginalUrl.AbsoluteUri; return file; } else { _logger?.Lazy().LogWarning("ValidateUser javascript generation failed for {Page}", _page.ToString()); javaScript = System.Text.UTF8Encoding.UTF8.GetBytes($"console.log('could not generate userValidation')"); return File(fileContents: javaScript, contentType: "text/javascript"); } } catch (ArgumentException e) { _page.Exception = e; _fireWall.LogException<RunTimeErrors>(RunTimeErrors.ArgumentNullException, e, "Missing a configuration element or using wrong release for your deployment"); var javaScript = System.Diagnostics.Debugger.IsAttached ? System.Text.UTF8Encoding.UTF8.GetBytes($"console.log('could not generate userValidation due to {e.Message}')") : System.Text.UTF8Encoding.UTF8.GetBytes($"//Validate log {DateTime.Now} for errors and update settings"); return File(fileContents: javaScript, contentType: "text/javascript"); } catch (Exception e) { _page.Exception = e; _fireWall.LogException<RunTimeErrors>(RunTimeErrors.ArgumentNullException, e, $"User type discovery will not work as good as it could please fix {e.Message}"); var javaScript = System.Text.UTF8Encoding.UTF8.GetBytes($"console.log('could not generate userValidation due to {e.Message}')"); return File(fileContents: javaScript, contentType: "text/javascript"); } finally { _logger?.Lazy().LogDebug("ValidateUser called"); } } [HttpPost, Route(Links.BeaconPoint), AllowAnonymous] [CrossSite, Ignore(skip: FireWallGuardActions.ALL & ~FireWallGuardActions.RejectCrossSiteRequests)] [ModelFilter(associations : RequestersAssociations.InCurrentPage , generateIncident : false , pageGroupPropertyName :Walter.Web.FireWall.Beacon.PageRequestGroupIdModelCode)] public StatusCodeResult Beacon(string model) { if (!ModelState.IsValid) { _logger?.Lazy().LogInformation("beacon: failed has {errors} errors", ModelState.ErrorCount); return this.Ok();//no need to make a fuss } if (!string.IsNullOrEmpty(model)) { var beacon = JsonConvert.DeserializeObject<Beacon>(model); _fireWall.ModelIsValid(pageContext: _page, model: beacon, out var errors); if (errors.Sum(s => s.BlockingSeverityScore) < 100) { _fireWall.LogPageRequest(beacon, _page); } else { foreach (var error in errors) { _logger?.Lazy().LogInformation("beacon: {warn}", error); } } } return this.Ok(); } [HttpPost] [AllowAnonymous] [Route(Links.IsUserEndpoint)] [CrossSite, Ignore(skip: FireWallGuardActions.ALL & ~FireWallGuardActions.RejectCrossSiteRequests)] [ModelFilter(Associations = RequestersAssociations.InCurrentPage, GenerateIncident = false)] public StatusCodeResult UserDiscovery([FromBody] Discovery model) { if (model is null) { _logger?.Lazy().LogDebug("user discovery called but the model field or data types are not compatible, please wait, update the model to fix the users discovery javascript"); return this.NoContent(); } else { _fireWall.ModelIsValid(pageContext: _page, model: model, out var errors); if (errors.Sum(s => s.BlockingSeverityScore) < 100) { _fireWall.LogPageRequest(model, _page); return Ok(); } else { _logger?.Lazy().LogInformation("An attempt was made to send a tampered model to {url}", _page.OriginalUrl.AbsoluteUri); if (errors.Sum(s => s.BlockingSeverityScore) > 100) { var fwu = _page.User.AsFirewallUser(); using (var scope = _logger?.BeginScope<string>($"User {fwu.Id} from {fwu.IPAddress} tampered with the model send back to {Links.IsUserEndpoint} and triggered {errors.Count} warnings")) { for (var i = 0; i < errors.Count; i++) { _logger?.Lazy().LogInformation("incident:{count} reason:{reason} context:{context} weight:{weight}", i + 1, errors[i].Reason, errors[i].BlockingContext, errors[i].BlockingSeverityScore); } } //tamper detected so return a 404 return this.NotFound(); } //model data is not valid, could be tampered but could also just be not containing required values return this.BadRequest(); } } } [HttpPost, Route(Links.SiteMapEndPoint)] [CrossSite(useDefaultRedirect: false), Ignore(skip: FireWallGuardActions.ALL & ~FireWallGuardActions.RejectCrossSiteRequests)] [ModelFilter(Associations = RequestersAssociations.InCurrentPage, GenerateIncident =false)] public StatusCodeResult SiteMap([FromBody] SiteMapDiscovery model) { _logger?.Lazy().LogDebug("Url SiteMapDiscovery called "); //return await base.SiteMap(model);if (model is null)return NoContent();else { //The firewall will use predictive navigation for user as well as use it in web-statistics to show choices made by the user _fireWall.LogSiteMap(_page, model); return Ok(); } }