“Forged request detected” exception – submitting WFFM form after period of activity

Hi all,

Today i am planning to share an issue which we faced in our webforms. I am using WFFM 8.2 Update 3.
The issue can be described as follows :

When a user starts filling a form which has more fields, he/she is filling some fields, and they are waiting for 25-30 mins for filling the rest of the fields, and clicks submit, the form will not get submitted and it displays an errorTechnical dificulty errorAt first we were thinking this issue might be because of the Mail service was not working, but when started investigating in the logs, we could not find any log error which corresponds to mail service.

But at the same time we received following in the logs :

5728 12:57:20 INFO AUDIT (extranet\Anonymous): Upload: example.pdf
5728 12:57:20 INFO Media Item has been uploaded to database: /{11111111-1111-1111-1111-111111111111}/{3D6658D8-A0BF-4E75-B3E2-D050FABCF4E1}/{25D39E8F-719B-4C95-9F43-A106C2C0EC54}/{338F9B9A-75A5-4304-A34B-A1F2F9B5F01C}/{CAA45999-AC9B-4F6F-89C6-B9F949030CDD}/{82D54811-0DA9-4CA8-B4A2-744C47321AD2}/example.pdf
5728 12:57:20 INFO AUDIT (extranet\Anonymous): [WFFM] Form {7100FF18-8969-48B0-833B-49C035C8A19C} is saving to db
5580 13:01:26 WARN [WFFM] Web Forms for Marketers: an exception: WFFM: Forged request detected! has occured while trying to execute an action.
5580 13:01:26 ERROR WFFM: Forged request detected!

In our further analysis we could find that this issue occurs when the session is expired.
Expiration is controlled by timeout value of the session state configuration in the web.config:

As described in the following blogspot : https://sitecoredoc.wordpress.com/2017/01/04/sitecore-wffm-v8-1-2-form-times-out-after-a-period-of-inactivity/, This is because of an anticsrf and the logic is simple. There is some value (guid) stored in the session and another value is on the form (hidden input control with “_anticsrf” postfix in id and name). If at the submission these values are different or session is null, this message about forged request will be logged and the submission will be aborted.
In my case, the session is expired in 20 minutes and session value at submission is null.

Possible workarounds :

1. Increase session timeout to 60 minutes.

2. There is a Sitecore support reference number for this : 456464, Please mention your WFFM version and this reference number to the Sitecore support.

3. We can temporarily bypass the forged request problem by adding some code logic for the same.
Create a class named ForgedRequestBypass.cs with following code

using System;
using Sitecore.Diagnostics;
using Sitecore.Form.Web.UI.Controls;

namespace YourNamespace
{
    /// <summary>
    /// This class is intended to be a temporary bypass for the forged request problem with the WFFM module.
    /// It's an implementation of #2 listed at https://community.sitecore.net/developers/f/10/t/3822.
    /// </summary>
    public class ForgedRequestBypass : SitecoreSimpleFormAscx
    {
        protected override void OnClick(object sender, EventArgs e)
        {
            Assert.ArgumentNotNull(sender, "sender");

            if (bool.Parse(Sitecore.Configuration.Settings.GetSetting("WFM.EnableAntiCsrf", "true")))
            {
                base.OnClick(sender, e);
            }
            else
            {
                object sessionValue = Sitecore.Form.Core.Utility.SessionUtil.GetSessionValue<object>(this.AntiCsrf.ID);

                if (sessionValue == null || !(sessionValue.ToString() == this.AntiCsrf.Value))
                {
                    Sitecore.Form.Core.Utility.SessionUtil.SetSessionValue(this.AntiCsrf.ID, this.AntiCsrf.Value);
                    Log.Info("Successfully Bypass forged request - Session value successfully stored",this);
                }

                base.OnClick(sender, e);
            }
        }
    }
}

Update the Control directive’s inherits attribute in the \Website\sitecore modules\Web\Web Forms for Marketers\control\SitecoreSimpleFormAscx.ascx file:

<%@ Control Language=”C#” AutoEventWireup=”true” CodeBehind=”SitecoreSimpleFormAscx.ascx.cs” Inherits=”YourNamespace.ForgedRequestBypass” %>

Also we need to create a patch for Sitecore.Forms.config and add the following setting to that

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/">
  <sitecore>
<!-- SETTING VALUE FOR ANTICSRF COOKIE-->
      <setting name="WFM.EnableAntiCsrf" value="false" /> 
    </settings>
  </sitecore>
</configuration>

After applying this fix, when you try to submit the same form even after the session is timed out, the form will be submitted successfully and you can see the following message in the logs.

5000 11:28:06 INFO Successfully Bypass forged request – Session value successfully stored
5000 11:28:06 INFO AUDIT (extranet\Anonymous): [WFFM] Form {7100FF18-8969-48B0-833B-49C035C8A19C} is saving to db

How i tested the issue : I changed the session timeout to 1 minute and then tried to submit form after 2-3 minutes, so before i applied the fix, it showed the error and after applying the fix, the form was submitted successfully.

And Finally the issue was solved !!!

I guess everyone liked my post. If anyone faces such type of issue and requires help please feel free to contact me. You are also welcome for any suggestions on the above post.

Happy Sitecoring !!!

Advertisements

ISSUES FACED IN SITECORE PROJECT

Hello everyone,

This time I am sharing some issue that we have faced in our project and the solution we had provided.

#1 : Media Items are served with extensions .ashx instead of .jpg, .pdf etc
By default media items(.jpg, .pdf, .xls etc) will be rendered as .ashx.
This can be handled from Media.requestExtension setting in Sitecore.config. By Default the value is

1

By setting the value to blank, we can render media url with relevant extension. We used custom patch for the setting

2

#2 : Sitecore Hyperlink manager/Mail template editor not clickable/broken
a) One morning we faced an issue that when we select hyperlink manager, a link builder dialogue opens, and the bottom of this dialogue has two small square. They look like small versions of buttons, but content is not there and are not clickable.
b) Similarly when we open mail template editor, to send email message through WFFM, The mail template editor opens, but:
* The content field of the template is blank
* It’s not possible to click the HTML button
* No values can be selected from the field dropdown
* If you start resizing the window it goes completely haywire with weird alert boxes

We could find that both of these are related to single issue. Because in the Console we were getting errors related to ScriptResource.axd.

This can be handled using the IgnoreURLPrefixes setting in Sitecore.config, adding script resource.axd.

3

After that, everything started working fine
(These two are the issues which we faced, there can be some other issues also due to unavailabilty of ScriptResource.axd in IgnoreURLPrefixes)

#3 : We have observed that there are multiple failed connections sparks on the Azure PaaS SQL DB causing application unavailability issue which looks transient error.

When we reached to Microsoft about this issue with the Error log for SQL DB, they replied that Reconfigurations happened in the databases.
Reconfiguration (briefly)
Reconfigurations are a common part of SQL Azure databases. Due to high availability architecture of Azure, its database has three replicas.Every time we need to point your application to a secondary replica, send an exception to the application so you can handle the error and resubmit the request to the database. These disconnections may occur during maintenance of database, or due to some error in the system, updating, patching the operating system, etc. Adding a retry logic to your code should help resolve these errors.

Reconfigurations generally occurs within 5-30 seconds for no impact to be seen, but application must reconnect to the healthy copy of the database. With an appropriate retry logic this would be transparent as the application could automatically connect as soon as the database is available. Below is more information on the connection recommendations for Azure SQL DB as well as retry logic configurations and suggestions.

So we enabled the retryer logic in Sitecore config file

By default it will be

4We had modified it to

8

#4 : Sitecore Media Library is very slow
The Sitecore Media Library is extremely slow at loading. The initial load is ok, but unfolding a main folder can take several minutes.

Based on the sitecore recommendation from the below blog

https://kb.sitecore.net/articles/723979

Set the value of the Media.MediaLinkPrefix setting in the Sitecore.config to the alternative prefix:

6

Add the following line to the customHandlers section (make sure NOT to remove the existing one that is mapped to “~/media”):7

Now the Media Library is loading better compared to previous.

These are some of the issues we faced in our Sitecore project. These might not be the Only solution for the same kind of issue. If you face such kind of issue, you could try these fixes also as part of your investigation. Please feel free to contact me if you have similar kind of issue or any doubts or you have any other solution.

TO GET BUILD DEFINITIONS USING VSTS API

Hello all,

It had been a long time since i have written my first blog post.

Here comes by second post on How to get build definitions through C# code.

Last month we had a requirement to see the build definitions and the corresponding build details on a page.

First step for that is create a personal token for authentication from your VSTS account. The details about this is given in
https://www.visualstudio.com/en-us/docs/setup-admin/team-services/use-personal-access-tokens-to-authenticate

As mentioned in the website, please copy the token and save it for yourself. It wont be available after that.

Create a .cs file for getting the build definitions

public void GetBuilds(int id, List myList)
 {
 try
 {
 var username = "/*Please enter the username for logging in VSTS*/";
 var password = "/*Please enter the token you received from VSTS*/";
 BuildValues values = new BuildValues(); 
 using (HttpClient client = new HttpClient())
 {
 client.DefaultRequestHeaders.Accept.Add(
 new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

 client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
 Convert.ToBase64String(
 System.Text.ASCIIEncoding.ASCII.GetBytes(
 string.Format("{0}:{1}", username, password))));

 using (HttpResponseMessage response = client.GetAsync(
 "https://{youraccount}.visualstudio.com/DefaultCollection/_apis/build/builds?definitions=" + id + "&statusFilter=completed&$top=5&api-version=2.0").Result)
 {
 response.EnsureSuccessStatusCode();
 string responseBody = response.Content.ReadAsStringAsync().Result.ToString();
 JObject json = JObject.Parse(responseBody);
 values = JsonConvert.DeserializeObject(json.ToString());
 myList.Add(values); 
 }
 }
 }
 catch (Exception ex)
 {
 Console.WriteLine(ex.ToString());
 }

 }

Buildvalues is a model which i had created from the json file which i received from the above code. Here i had used only the required fields in the model class

public class BuildValues
 {
 public List value { get; set; }
 }
 public class Build
 {
 public string status { get; set; }
 public string result { get; set; }
 public string buildNumber { get; set; }
 public string startTime { get; set; }
 public string finishTime { get; set; }
 public RequestedFor requestedFor { get; set; } 
 public Definition definition { get; set; }
 public RequestedBy requestedBy { get; set; }
 }
 public class RequestedFor
 {
 public string displayName { get; set; } 
 }
 public class RequestedBy
 {
 public string displayName { get; set; }
 }
 public class Definition
 {
 public string name { get; set; }
 }

You can see i am passing an id in the GetBuilds method. We are getting the id using the same code as in GetBuilds method except for we change the following snippet :

BuildDef obj = new BuildDef(); 
using (HttpResponseMessage response = client.GetAsync(
 "https://{youraccount}.visualstudio.com/DefaultCollection/_apis/build/definitions?api-version=2.0").Result)
 {
 response.EnsureSuccessStatusCode();
 string responseBody = response.Content.ReadAsStringAsync().Result.ToString();
 //var test = JsonConvert.DeserializeObject(responseBody);
 JObject json = JObject.Parse(responseBody);
 obj = JsonConvert.DeserializeObject(json.ToString());
 PassObj(obj);
 }

Here we use a similar model class which takes only id

 public class BuildDef
 {
 public List value { get; set; }
 }
 public class Value
 {
 public int id { get; set; }
 }

Since we have more build definitions we get almost 10 build IDs and in foreach loop we can call the GetBuilds

 foreach (var x in obj.value)
 {
 GetBuilds(x.id, myList);
 }

Then get the values to a List. and populate it accordingly into a nested repeater. Below screenshot shows how I got the values and displayed in my Sitecore project.

build

Hope this post was useful. Please contact me if any doubts/clarifications. Also you can share your ideas on the same if you have used any.

SITECORE BLOBS TABLE GROWING OUT OF CONTROL

This is my introduction post. And I am wishing to share an issue which made us worried  for about 1 month.

Over a past few days, I was facing abnormality in our Production WEB database. The size got increased from 37 GB to 110 Gb within 15 days.
But the issue was happening only in the WEB database not master. Then we ran the following query in SQL server Web database to check the size of each tables.
sql_query_size
After executing the query we were able to see the size of all tables in the Web database and dbo.Blobs database size has got a rapid increase of 60GB in last 2 weeks. And as we all know this table will store all media library assets and also it can quickly inflate the size of your content database.
So we wanted to stop this out of control growth of Blobs table and we tried 3 solutions which I have described below :
1) We tried to run a Cleanup Database task from Sitecore on the WEB database . But after running a number of times, each time we were getting an SQL timeout error.

Then we found a useful blog of Kiran Patil
Clean Up Database

We found that It was causing an error due to Default timeout for running SQL query was not enough for job to get its job done. So we tried increasing the “DefaultSQLTimeout” value to 12 hrs because the database size was very large.

But the cleanup job was not completed again it ran for more time and would suddenly stop in the middle and we had to start from beginning. So we stopped this approach for sometime and implemented a alternate solution.

2) Took a bacpac(database backup) of a clean Sitecore 8.0 web database. We did not want to disturb the Production database. So restored the new database to the QA SQL
server. Then changed the connection string information of the QA CM server to point to the master database in production and the web database that was restored from the
bacpac. Then using the QA Sitecore server to log in and do a full publish with all languages included.

As it was a full republish, it took more time and sometimes in the middle it stopped. So from the second time instead of going for Republish, we did Smart publish and finally the
publish was done successfully.

Then we restored the new WEB database to the production server and changed the Connection string to point to the new database. And finally the database size was reduced.

3) But after executing the above solution, there was no increase of Blobs table for 2 weeks, But after that we found again the size was increasing.
Now as suggested by Sitecore and in one of the blogs, we tried to delete top 1000 unused blobs from the table and automated it with Azure automated scripts(since our website is
hosted in Azure) and kept the time interval for 4 hours. Now after every 4 hours top 1000 rows from the table in which there is unused blobs will get deleted.

Here is the script we used :sql_query_delete

And it worked 🙂

But after the release of Sitecore 8.2 onwards, we have an admin page “/sitecore/admin/DbCleanup.aspx” which has an option for Selecting the option for only cleaning Blobs table as shown in the image.
cleanup_database

I hope this post was useful. Please do share other approaches that you may have adopted in your Sitecore implementations.