Server started to receive requests with invalid cookie _a_d3t6sf - cookies

Starting from 04.06.2018 our production site started to receive requests that contains the cookie with invalid value:
_a_d3t6sf="duUt#<WFf>>nD=9O&lG9y)DN"
values are different, but name is the same for all requests.
Exception looks like this:
System.Web.HttpRequestValidationException (0x80004005): A potentially dangerous Request.Cookies value was detected from the client (_a_d3t6sf="xdZ<et[)27rL^5lBe6rL_<[...").
at System.Web.HttpRequest.ValidateString(String value, String collectionKey, RequestValidationSource requestCollection)
at System.Web.HttpRequest.ValidateCookieCollection(HttpCookieCollection cc)
at System.Web.HttpRequest.get_Cookies()
at System.Web.HttpRequest.FillInParamsCollection()
at System.Web.HttpRequest.GetParams()
at System.Web.HttpRequest.get_Params()
at ASP._sites__shared_svc_getstrings_aspx.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in ___\getStrings.aspx:line 6
at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
at System.Web.UI.Page.Render(HtmlTextWriter writer)
at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
at System.Web.UI.Control.RenderControl(HtmlTextWriter writer)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest()
at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context)
at System.Web.UI.Page.ProcessRequest(HttpContext context)
at ASP._sites__shared_svc_getstrings_aspx.ProcessRequest(HttpContext context) in ___\root\3403aaf9\baa39378\App_Web_zbqbtb3n.2.cs:line 0
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
There is no such cookie in our code and there is no form posts or anything we can validate before that requests. We have validation mode 2.0 in our config
<httpRuntime targetFramework="4.5" requestValidationMode="2.0" />
so only .aspx pages throws that exception. One of them is callback page for a spanish online payment system. And it gets that cookie too from a real paysystem server - there was a payment done, request was sent to us, but was invalid because of that cookie.
There is a three .aspx pages that serves as minimization sources for styles, scripts and javascript localized strings. So one full page load throws three exceptions every time this happens, but only few clients has this cookie. On our computers we was unable to reproduce it.
So:
1. We has no things that adds or reads that cookie.
2. Not every client has it.
3. Secured request from online payment service sends payment data almots every day but also has that cookie once.
4. All windows updates including .net security was installed today - nothing has changed.
5. We can not turn validation off.
6. Last code changes was done month ago and all this started about two weeks ago.
Looking for any ideas and suggestions. Thank you.

Maybe you are using the zp.js or pluso-like.js plugins.
They do some suspisious activity and load 'processor.js' script that adds _a_d3t6sf cookie. If the client is lucky he will get safe cookie value like
duu2BAdLFlYTaTgr_h4WB6
but if he isn't he will get unsafe cookie value like
duu2BAdLFlYTaT#^0[AZ?WB6
There is some article about pluso.ru

My solution to this and all possible third-party invalid cookies:
1) Copy-paste or reflect CrossSiteScriptingValidation.cs class that is used to validate HttpRequest in framework internals:
https://referencesource.microsoft.com/#System.Web/CrossSiteScriptingValidation.cs,3c599cea73c5293b
2) In Global.asax on
protected void Application_BeginRequest( Object sender, EventArgs e ){}
validate cookies
// Validate and remove all invalid cookies
try
{
for( var i = Request.Cookies.Count - 1; i >= 0; i-- )
{
var cookie = Request.Cookies.Get( i );
if( string.IsNullOrWhiteSpace( cookie?.Value ) )
{
continue;
}
if( CrossSiteScriptingValidation.IsDangerousString( cookie.Value ) )
{
Request.Cookies.Remove( cookie.Name );
// Remove cookie from client
Response.Cookies.Add( new HttpCookie( cookie.Name ) { Expires = DateTime.Now.AddDays( -1d ) } );
}
}
}
catch( Exception ex )
{
Log.Error( "Failed to validate cookies. ", ex );
}

Related

No longer working after removing my site from Facebook via "Apps and Websites"

My website (Spring MVC) allows users to sign up by using their Facebook accounts and sign into my site later with their Facebook accounts. I use scribejava (version 6.6.3) (https://github.com/scribejava/scribejava) for the Oauth integration with Facebook.
I have tested a use case and am unable to find a way to resolve it. Here is the list of steps:
The tester goes to my site's "Log in" page, clicks "Log in with Facebook", grants permissions at Facebook, gets redirected to my site, and signs out. This is a normal and successful flow.
The tester sign into Facebook at Facebook.com
The tester goes to Settings->Apps and Websites and removes my site
The tester goes to my site's "Log in" page, clicks "Log in with Facebook" button, gets redirected to Facebook, and sees an error message.
At step 4, the tester always gets an error message at the Facebook site instead of asking the tester to grant permissions again. See the following screenshot:
I cannot find a way at Facebook to remove this message when clicking on the "Log in with Facebook" button. Here is my code for the web interface. Did I miss something?
#RequestMapping( value="/facebook", method = RequestMethod.GET)
public void facebook(HttpServletRequest request,
#RequestParam(value = "page", required = true) String page,
HttpServletResponse response) throws Exception {
try {
OAuth20Service service = new ServiceBuilder(config.getProperty("facebook.clientId"))
.apiSecret(config.getProperty("facebook.clientSecret"))
.callback(getCallback())
.build(FacebookApi.instance());
String authUrl = service.getAuthorizationUrl();
response.sendRedirect(authUrl);
} catch (Exception e) {
response.sendRedirect("/oauthFail");
}
}
#RequestMapping( value="/facebook/callback", method = RequestMethod.GET)
public void facebookCallback(HttpServletRequest servletRequest,
#RequestParam(value = "code", required = false) String code,
#RequestParam(value = "error", required = false) String error,
HttpServletResponse servletResponse
) throws Exception {
try {
OAuth20Service service = new ServiceBuilder(config.getProperty("facebook.clientId"))
.apiSecret(config.getProperty("facebook.clientSecret"))
.callback(getCallback())
.build(FacebookApi.instance());
OAuth2AccessToken accessToken = service.getAccessToken(code);
final OAuthRequest request = new OAuthRequest(Verb.GET, "https://graph.facebook.com/v3.2/me");
service.signRequest(accessToken, request);
final com.github.scribejava.core.model.Response response = service.execute(request);
String body = response.getBody();
JSONObject jObject = new JSONObject(body);
String email = jObject.getString("email");
//success. use the email to create an account or if the email address exists, direct a userto their account page
} catch (Exception e) {
response.sendRedirect("/oauthFail");
}
}
How to handle this situation? I feel either something is wrong is my code or scribejava has a framework issue. Or this is a Facebook specific issue?
I have just tested the case. Couldn't reproduce.
Did you try running this Example
https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookExample.java
?
I think your problem can be with API versions logic in Facebook.
You can try to explicitly use the latest one .build(FacebookApi.customVersion("3.2"))

ASP.Net Core 2.0 API Response hangs with large json payload

I am working on an ASP Net Core 2.0 Web API. One of my endpoints returns a json object that includes a text field that can be fairly large. When this field gets around 10Mb in size the controller just stops until the timeout is hit. When I debug, I see that the json object is created in my business logic and passed to the endpoint controller but the controller just stops right after it receives json object with no error and doesn't return to the caller until the request finally times out. I increased my requestTimeout to 20 mins even though the business logic generates the json object in less than 2 minutes. It just hangs until the 20 minute timeout is hit.
Here is my controller action;
[EXAMPLE 1]
[HttpGet(Name = "GetFile")]
public async Task<FileResponseDto> GetFile([FromRoute] int companyId, [FromRoute] int siteId, [FromRoute] int FileId,
[FromHeader(Name = "Accept")] string mediaType, CancellationToken cancellationToken)
{
var fileResponseDto = _fileBll.GetFile(companyId, siteId, fileId, HttpContext);
// This is the point where the controller appears to hang
return await Task.Factory.StartNew(() => fileResponseDto, cancellationToken);
}
and my DTO object;
public class FileResponseDto
{
public string ReferenceId { get; set; }
public string Filename { get; set; }
public string ProcessingFile { get; set; }
}
The property that is the large string is the ProcessingFile property in the FileResponseDto class.
This works fine until my ProcessingFile property gets to around 30K lines (about 10Mb) and then the controller just hangs after it completes the line;
var fileResponseDto = _fileBll.GetFile(companyId, siteId, fileId, HttpContext);
At this point, my assumption was that I have hit some limitation in the size of the json object. So, to test, I changed my controller so that it returns a file instead, like what is shown below;
[EXAMPLE 2]
[HttpGet(Name = "GetFile")]
public async Task<FileContentResults> GetFile([FromRoute] int companyId, [FromRoute] int siteId, [FromRoute] int fileId,
[FromHeader(Name = "Accept")] string mediaType, CancellationToken cancellationToken)
{
var fileResponseDto = _fileBll.GetFile(companyId, siteId, fileId, HttpContext);
var outputFile = Encoding.ASCII.GetBytes(fileResponseDto.ProcessingFile);
return await Task.Factory.StartNew(() =>
new FileContentResult(outputFile, new MediaTypeHeaderValue(MediaTypeNames.Application.Octet))
{
FileDownloadName = fileResponseDto.Filename
}, cancellationToken);
}
Making this change works and I can receive a file download dialog popup and a successful file if I select "Send and Download" in Postman.
So, this leads me to believe that there is something size related to the json object being transferred in the first example.
However, web searches have not turned up anything useful on this issue, which makes me think that perhaps I am missing something here.
I did find this link in StackOverflow and tried it by using...
var outfileJson = JsonConvert.SerializeObject<fileResponseDto>;
outfileJson.MaxJsonLength = Int32.MaxValue;
but outfileJson did not have a MasJsonLength property.
So.. any ideas?
EDIT 6/8/18
After 2 days, 22 views and no actual responses. I figured something must be wrong with my approach. I realized that I did not mention that I was performing these tests in Postman, which is where I was seeing the problem. After further digging, I found a post on GitHub that seemed to be related to what I was experiencing in Postman (the hang on large response payload). It seems that Postman has a limit in the number of "rows" it returns in the response. The GitHub post was a feature request to increase the number of rows.
I am not sure how to handle this StackOverflow question now. Since I didn't mention Postman in the original post, I don't feel right just answering my own question. So, I guess I will leave it as is for a couple of days to see if anyone chimes in with their thoughts before I do that.
As it turns out, the was, if fact, an issue with Postman and the size of the response payload it currently supports. If, instead of selecting Send, I select Send and Download in Postman, It will download the JSON object and pop up a dialog box to allow me to save it to my local drive. Then when I examine the file, I can see the json object is correctly formatted and transferred.
I confirmed that it was only a Postman issue and not a .NET HttpResponse issue by performing the API call in a .Net client application, which was able to receive the Json object without error.

Pass FedAuth cookies from WebApi controller to RestSharp

We have a thinktecture powered identity server used for SSO. There are several services which utilize that identity server. My app uses ASP.net WebApi controllers to handle UI requests. For a particular request I have to make a REST API call to one of the mentioned above services. That service requires authentication of course. What I'm trying to do is to pass FedAuth cookies from the current request to RestSharp client:
[HttpGet]
[Route("api/testroute")]
public IHttpActionResult Test()
{
var client = new RestSharp.RestClient(_someBaseUrl);
var req = new RestSharp.RestRequest(_someUrl);
var cookies = Request
.Headers
.GetCookies()
.SelectMany(x => x.Cookies)
.Where(x => x.Name.StartsWith("FedAuth"))
.ToList();
foreach (var cookie in cookies)
{
req.AddCookie(cookie.Name, cookie.Value);
}
var resp = client.Execute(req);
return Ok(resp);
}
RestSharp client call fails with 500 error code with the following stacktrace inside:
[FormatException: Invalid length for a Base-64 char array or string.]
System.Convert.FromBase64_Decode(Char* startInputPtr, Int32 inputLength, Byte* startDestPtr, Int32 destLength) +14390795
System.Convert.FromBase64CharPtr(Char* inputPtr, Int32 inputLength) +162
System.Convert.FromBase64String(String s) +56
System.IdentityModel.Services.ChunkedCookieHandler.ReadInternal(String name, HttpCookieCollection requestCookies) +424
System.IdentityModel.Services.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken& sessionToken) +99
System.IdentityModel.Services.SessionAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs eventArgs) +173
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +165
Is my approach for user authorization correct? If so, am I doing something wrong with the cookies (from the stacktrace it looks like they are being corrupted)?
I think your FedAuth cookie was encoded. Maybe you can check if your FedAuth cookie contains char like '%'. If yes, just decode FedAuth before you use it.

BOBJ. RESTFull WebService API. Get list of Data Providers returns "404" message

I use RESTFull WebService API (BOBJ 4.1) to retrieve the information about the reports in the repository.
When I try to derive the list of data providers, it works file for most of the reports. However, for some of the reports I get back the "(404) not found" message. I appreciate that it's a valid response for reports which don't have any data providers, but I'm sure that the reports I get the 404 message for definitely have one or more data providers. I also don't expect it to be related to the permissions, because I don't get the "access denied" message and I can open the "problematic" reports using the Rich Client.
I use the following link:
http://{servername}:{port}/biprws/raylight/v1/documents/{reportID}/dataproviders
Has anyone experienced this kind of a problem before? Am I missing something?
I was having the same problem with some of the BO REST services (some of which went away after we rebooted our server).
You don't say which technology you're using to call the web services, but here's how you'd get the error information in a C# application.
In my C# app, below are the functions I use to call a GET & POST Business Objects 4.x REST service, and if something goes wrong, it attempts to read in the error message, so we get more than just "404 not found" or "503 Server error"...
To use these functions, you must've logged into BO and got a Login token.
protected string CallGETWebService(string URL, string token)
{
HttpWebRequest GETRequest = null;
try
{
GETRequest = (HttpWebRequest)WebRequest.Create(URL);
GETRequest.Method = "GET";
GETRequest.Accept = "application/xml";
GETRequest.Timeout = 3 * 60 * 1000; // Wait for upto 3 minutes
GETRequest.KeepAlive = false;
GETRequest.Headers.Add("X-SAP-LogonToken", token);
HttpWebResponse GETResponse = (HttpWebResponse)GETRequest.GetResponse();
Stream GETResponseStream = GETResponse.GetResponseStream();
StreamReader reader = new StreamReader(GETResponseStream);
string response = reader.ReadToEnd();
return response;
}
catch (WebException ex)
{
// If the web service throws an exception, attempt to see if it give us any clues about what went wrong.
string exception = GetExceptionMessage(URL, ex);
throw new Exception(exception);
}
}
protected string CallPOSTWebService(string URL, string token, string XMLdata)
{
try
{
// Call a "POST" web service, passing it some XML, and expecting some XML back as a Response.
byte[] formData = UTF8Encoding.UTF8.GetBytes(XMLdata);
HttpWebRequest POSTRequest = (HttpWebRequest)WebRequest.Create(URL);
POSTRequest.Method = "POST";
POSTRequest.ContentType = "application/xml";
POSTRequest.Accept = "application/xml";
POSTRequest.Timeout = 3 * 60 * 1000; // Wait for upto 3 minutes
POSTRequest.KeepAlive = false;
POSTRequest.ContentLength = formData.Length;
POSTRequest.Headers.Add("X-SAP-LogonToken", token);
Stream POSTstream = POSTRequest.GetRequestStream();
POSTstream.Write(formData, 0, formData.Length);
HttpWebResponse POSTResponse = (HttpWebResponse)POSTRequest.GetResponse();
StreamReader reader = new StreamReader(POSTResponse.GetResponseStream(), Encoding.UTF8);
string response = reader.ReadToEnd();
return response;
}
catch (WebException ex)
{
// If the web service throws an exception, attempt to see if it give us any clues about what went wrong.
string exception = GetExceptionMessage(URL, ex);
throw new Exception(exception);
}
}
protected string GetExceptionMessage(string URL, WebException ex)
{
// If one of the BO web service threw an exception, attempt to see if it give us any clues about what went wrong.
string exception = "An exception occurred whilst calling: " + URL + ", " + ex.Message;
try
{
if (ex.Response == null)
return exception;
if (ex.Response.ContentLength == 0)
return exception;
using (Stream sr = ex.Response.GetResponseStream())
{
// The web service will return a string containing XML, which we need to parse, to obtain the actual error message.
StreamReader reader = new StreamReader(sr);
string XMLResponse = reader.ReadToEnd();
XElement XML = XElement.Parse(XMLResponse);
XElement XMLException = XML.Elements().Where(e => e.Name.LocalName == "message").FirstOrDefault();
if (XMLException != null)
exception = XMLException.Value; // eg "Info object with ID 132673 not found. (RWS 000012)"
}
}
catch
{
// If the web service returned some other kind of response, don't let it crash our Exception handler !
}
return exception;
}
The important thing here is that if BO's REST services fail, the GetResponse() will throw a WebException, and we then use my GetExceptionMessage() function to check the error response (which the BO Rest Services return in XML format) and try to extract the error message from it.
Using this functionality, our C# code can throw an exception with some useful information in it:
Info object with ID 132673 not found. (RWS 000012)
..rather than just throwing a vague exception like this (which, by the way, is what all of SAP's own C# examples will do, as none include any error-handling)...
(404) Page not found
(503) Service unavailable
I've also had cases where the BO REST Services will actually throw a "(503) Service Unavailable" exception... which was completely misleading ! Again, this code will help to give us the real error message.
If BO's REST services are successful, they'll return a string containing some XML data. Let's look at some sample code showing how we'd use my functions to call the REST service to get details about a particular Webi Report.
We'll call the REST services, then convert the XML response string into an XElement, so we can obtain the Report's name from the XML.
string token = /* Your login-token */
string URL = string.Format("http://MyServer:6405/biprws/infostore/{0}", ReportID);
string WebiReportResponse = CallGETWebService(URL, token);
// Parse the web service's XML response, and obtain the name of our Webi Report
XElement ReportDetails = XElement.Parse(WebiReportResponse);
XElement title = ReportDetails.Elements().Where(e => e.Name.LocalName == "title").FirstOrDefault();
string ReportName = (title == null) ? "Unknown" : title.Value;
I thoroughly loathe the SAP documentation (and lack of it).
Life would've been MUCH easier if SAP themselves had provided some sample .Net code like this...
I've regularly had this problem in a Java routine that trawls through all WebI reports in the system to find their data-providers. At the start of the routine it works OK but as time progresses it gets slower and throws up more and more of this kind of error. I'm fairly convinced that the program itself does nothing untoward to slow down the system and it calls other BO RESTful services with no problem.
In the end I went back to getting the information using the Java SDK and it works fine. It's also much faster than Restful, even when it's working normally. Using BO 4.1 SP7

Sitecore: DMS 7.1 Analytics is disabled

I am trying to get Sitecore DMS 7.1 working. I followed the instructions on the sitecore support pages. I triple checked all the steps referred to on this website.
https://www.sitecore.net/Learn/Blogs/Technical-Blogs/John-West-Sitecore-Blog/Posts/2011/08/Troubleshooting-Analytics-is-Disabled-with-the-Sitecore-Customer-Engagement-Platform.aspx#comments
I have looked in the log file and i am getting.
3112 10:20:35 ERROR Application error.
Exception: System.Web.HttpException
Message: Online Marketing Suite is not enabled
Source: mscorlib
Server stack trace:
at Sitecore.Analytics.Reports.ReportDataHandler.AssertState(HttpContext context)
at Sitecore.Analytics.Reports.ReportDataHandler.ProcessRequest(HttpContext context)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.EndInvokeHelper(Message reqMsg, Boolean bProxyCase)
at System.Runtime.Remoting.Proxies.RemotingProxy.Invoke(Object NotUsed, MessageData& msgData)
at Sitecore.Analytics.Reports.ReportDataHandler.RequestProcessor.EndInvoke(IAsyncResult result)
at Sitecore.Analytics.Reports.ReportDataHandler.EndProcessRequest(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar)
Help. We have other sitecore sites and I was able to get it working on sitecore 7 platform.
Here is the logic that is causing the error to be thrown:
public static bool Enabled
{
get
{
if (Settings.GetBoolSetting("Analytics.Enabled", false))
return Sitecore.SecurityModel.License.License.HasModule("Sitecore.OMS");
else
return false;
}
}
So you can see that there are 2 criteria that need to be met.
First, the "Analytics.Enabled" setting in the analytics config file need to be set to true. It should look like the following.
<!--
ANALYTICS ENABLED
Determines whether analytics is enabled or not.
Default: true
-->
<setting name="Analytics.Enabled" value="true" />
Second, your license needs to include DMS (It's refers to it as "OMS" internally).
if (Context.Site.EnableAnalytics)
{
...
}