Service Call on Page Generates Zone Security Error - asp.net

This error is received on an ajax call
WebSocket Error: SECURITY_ERR, Cross zone connection not allowed
with a 500 error code also returned. I am able to get other responses which don't seem to be related to the error upon further testing. See below for where the reported error is.
From this Angular call
$http.post("Status.aspx/GetDataAsync", {})
.then(function(response){ $scope.theData = data;},
function(response){ $scope.result = "Error!";}
);
when attempting to call a page's code behind WebMethod which tellingly also makes a webservice call to a rest web service.
[System.Web.Services.WebMethod]
public static async Task<string> GetDataAsync()
{
var httpresult = await (new HttpClient()).GetAsync("{Internal site rest service Url}");
return await httpresult.Content.ReadAsStringAsync();
}
This reminds me of an old Silverlight cross-domain issue call...but I digress.
Question
Can the zone issue be resolved or does one have to call rest services directly?
Attempt The use of CORS (see Enabling Cross-Origin Requests (CORS)) at the method level such as
[System.Web.Services.WebMethod]
[EnableCors("AllowAllOrigins", "AllowHeaders", "AllowAllMethods")]
to no luck.
Error
This is where the error is found, in the F12 tools on Edge (and IE). Chrome does not report the issue.

You will need to set the Content Security Policy (CSP) of your page so that your {Internal site rest service Url} is not blocked by the browser.
Here are links, combined, that helped me solve this issue:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/connect-src
http://caniuse.com/#feat=contentsecuritypolicy
For MVC, I placed the following in the web.config:
<httpProtocol>
<customHeaders>
<add name="Content-Security-Policy" value="connect-src 'self' wss://localhost:7717" />
</customHeaders>
</httpProtocol>
I was then able to create a websocket connection to wss://localhost:7717, but wasn't able to connect to any other port.
Browsers block these kinds of requests to prevent cross-zone script attacks, so you need your page to set the policy, done through the http header. I'm working on a similar issue. I'm missing something, but I think this is the right direction. I need others input because this isn't quite solving the issue. It's closer, though.

Related

web api POST returns 500 error with AllowAnonymous Requests

I have a DNN 9.2 website set up on a local server. I use a HttpPOST to send JSON to the web.api. This was working last week and has now stopped working when I am attempting to upgrade from Angular 4.1 to 4.3.
When I try to access the api endpoint from within my app or a postman call I get a 500 error and no message.
Here is my Controller Code:
[HttpPost]
[ActionName("postPost")]
[AllowAnonymous]
public ApiResult UpsertPost([FromBody]Post post)
{
try
{
DO STUFF HERE
}
catch (System.Exception ex)
{
CATCH ERROR
}
}
What is funny here is that this was working and All I did was change to use the new httpClient from Angular 4.3. I know the api endpoint is taking requests.
What I tried:
I tried to take angular out of the loop by using postman calls. However, I also can not use the postman calls I had set up as tests and I get the same error.
I tried changing the security attribute from [AllowAnonymous] to ** a DNN built in security attribute: [DnnModuleAuthorize(AccessLevel = SecurityAccessLevel.Anonymous)]** but I get the following error instead of a 500 error:
Authorization has been denied for this request.
The same error is given as above if I change the security attribute to [DnnModuleAuthorize(AccessLevel = SecurityAccessLevel.View)]
I made sure the POST action was supported in my web.config file:
add name="ExtensionlessUrl-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"
I know the api endpoints are getting hit because if I use GET instead of POST I can hit all my breakpoints in the web.pai code. As well as the given "Authorization has been denied for this request" is given from the api service.
QUESTION
Can someone help me figure out why my DNN api's with post are not accepting requests?
I know that you got an answer by yourself, but can be usefull these links:
You can find a "scafolding angular project" here: DNN-Angular-6-7-CLI
And DNN module where to deploy your project: SPA DNN9: DNN-9.x-SPA-and-Angular-6-7
ASCX for all DNN: DNN-7.x-8.x-9.x-and-Angular-6-7
all works with dnn webapi and security.
I used these projects with my customers.
Matteo
Okay, so no surprise that it was my fault. I had moved the authorization process for the http requests to the new httpClient interceptors. I had an error in the interceptor function that was creating a poorly formed request. Once I fixed the interceptor the API requests work properly now.
Hope this might help someone

(CORS error) Can't send POST request (OPTIONS gets denied) with Angular to ASP.net REST services

So, when I try sending POST request it doesn't succeed. Chrome prompts me with this error:
OPTIONS http://localhost:49475/api/Kpi/new (anonymous function) # angular.js:10661sendReq # angular.js:10480serverRequest # angular.js:10187processQueue # angular.js:14634(anonymous function) # angular.js:14650Scope.$eval # angular.js:15878Scope.$digest # angular.js:15689Scope.$apply # angular.js:15986(anonymous function) # angular.js:23376n.event.dispatch # jquery-2.1.4.min.js:3r.handle # jquery-2.1.4.min.js:3
Index.html:1 XMLHttpRequest cannot load http://localhost:49475/api/MYLINK. Response for preflight has invalid HTTP status code 405
I highly doubt my request is the problem, but it looks like this:
return $http.post(apiAddress + 'mylink', dataObj)
.then(function (response) {
console.log("succeeded");
return response.status;
}, function (response) {
console.log("failed");
return response.status;
});
I have installed CORS on my API part, server one, and enabled it in WebApiConfig:
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
I have also edited my Web.config file and enabled all of Access Controls variables with:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, OPTIONS" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
</customHeaders>
</httpProtocol>
My client side is running on localhost:57810 and the server one is on localhost:49475. I have been looking for this to work for nearly 6 hours now. I've tried every possible snippet and "solution" I could find online and it is unsuccessfull. I wouldn't have posted this question if it was...
I appreciate any answer I get...
EDIT: Post method works as expected, I have tested it with Postman. Now, sending OPTIONS request to the mentioned url (api/mylink) doesn't work.
It returns:
{"Message":"The requested resource does not support http method 'OPTIONS'."}
For some reason the configs within WebApiConfig and Web.config answer got mixed up and didn't work together. I will find more time to learn why was this a problem, but in the meantime the working solution was to:
Erase all the data in Web.config between <httpprotocol> tags (4th snippet in my post)
In WebApiConfig, in EnableCorsAttribute initialization, sending '*' as first parameter didn't work, but typing explicitly: 'http://localhost:57810' did work! This is a second snippet in my original post.
I have no idea why the second one obstructed my server. Maybe it's some sort of a bug, since documentation clearly says that '*' is a wildcard, or maybe some other configurations prevented it from working.
If someone can expand on the answer, be my guest.
Ok. I might have a clue.
I guess its a problem in routing: web api can't find the action, and can't find an options hadler for it.
The default routing method in Asp.Net webapi is that it decides the action in controller based on the request method.
I tend to dislike this approach and change the WebApiConfig file from
routeTemplate: "api/{controller}/{id}"
to
routeTemplate: "api/{controller}/{action}/{id}"
Also, you might put [RoutePrefix("api/AAA")] on your controller and [Route("BBB")] on your actions. Also, put [HttpPost] on your action, so you've explicitly set everything.
Now your url becomes /api/AAA/BBB
Please give it a try, test it in your server domain (port) and make sure your routing is working as expected. Then proceed to test it in the client domain(port).
Please tell me if it's gonna work

Securing http headers

I Have website that is in production server and it supposed to be very secure so i want to secure http header so that no unwanted information is leaked.
I have searched on net about securing http headers and so far found that we can remove un anted information like removing
'Server Microsoft-IIS/7.5
X-AspNet-Version 4.0.303319
X-Powered-By ASP.NET -'
I have found solution for X-Aspnet and X powered by :
1. For X-AspNet i have added below code in system.web section
<httpRuntime enableVersionHeader="false"/>
For X-Powered i have added below code in system.webserver section
But for Server header removal code is not working :(
Code i am using for is :
I have added a class with name CustomHeaderModule and inside that class code is as below
///
/// Summary description for CustomHeaderModule
///
public class CustomHeaderModule : IHttpModule
{
public void Dispose()
{
throw new NotImplementedException();
}
public void Init(HttpApplication context)
{
context.PostReleaseRequestState += PostReleaseRequestState;
}
void PostReleaseRequestState(object sender, EventArgs e)
{
//HttpContext.Current.Response.Headers.Remove("Server");
// Or you can set something funny
HttpContext.Current.Response.Headers.Set("Server", "CERN httpd");
}
}
and then registered this in web.config under system.webserver section
<modules runAllManagedModulesForAllRequests="true">
<add name="CustomHeaderModule" type="CustomHeaderModule" />
</modules>
Now this code is not working ..i am still seeing server in header in chrome browser..
how can i fix this and apart from these 3 setting is there any other to secure more ?
Considering your problem what I would suggest you is to use ASafaWeb to test your Website!
Second is to read these articles from Troy Hunt and Paul Bouwer:
Shhh… don’t let your response headers talk too loudly
Clickjack attack – the hidden threat right in front of you
ASafaWeb, Excessive Headers and Windows Azure
Following this articles you will finally have a look at NWebSec!
Sorry if this doesn’t answer your question directly but I wouldn’t really bother removing those headers. Someone can easily find out what server are you using by looking at the html code on the browser side.
If I look at source code and I see things like __VIEWSTATE I’ll immediately know this is ASP.NET and if I dig a little deeper I’ll probably be able to figure out the version too.
What I’d suggest is that you focus on standard security and risk procedures such as making sure you are not open to SQL injections, validating everything on the server side, making sure you have all backups in place and ready to be up in several mins, adding additional layer of authentication if needed, making sure you have all security updates on the server and such…
I have found one solution which works on IIS but not on local but i am okay with that...Removing/Hiding/Disabling excessive HTTP response headers in Azure/IIS7 without UrlScan
anyways apart from these 3 settings ..is there any other way i can more secure http headers..

Preventing upload of large files in ASP.NET 4.0

We'd like to restrict the maximum upload file size in our web site. We've already set the appropriate limits in our web.config. The problem we're encountering is if a really large file (1 GB, for example) is uploaded, the entire file is uploaded before a server-side error is generated, and the type of the error is different whether the file is huge or not.
Is there a way to detect the size of a pending file upload before the actual upload takes place?
Here's my relevant web.config settings that restrict requests to 16 MB:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<httpRuntime maxRequestLength="12288"/>
</system.web>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="12582912"/>
</requestFiltering>
</security>
</system.webServer>
</configuration>
I've tried creating an HTTP module so I could intercept a request early in the request lifecycle, but the uploads seem to take place even before the BeginRequest event of HttpApplication:
public class UploadModule : IHttpModule
{
private const int MaxUploadSize = 12582912;
public void Init(HttpApplication context)
{
context.BeginRequest += handleBeginRequest;
}
public void Dispose()
{
}
private void handleBeginRequest(object sender, EventArgs e)
{
// The upload takes place before this method gets called.
var app = sender as HttpApplication;
if (app.Request.Files.OfType<HttpPostedFile>()
.Any(f => f.ContentLength > MaxUploadSize))
{
app.Response.StatusCode = 413;
app.Response.StatusDescription = "Request Entity Too Large";
app.Response.End();
app.CompleteRequest();
}
}
}
Update:
I know that client-side technologies like Flash can detect file sizes before upload, but we need a server-side workaround because we're wanting to target platforms that have no Flash/Java/ActiveX/Silverlight support. I believe that IIS or ASP.NET has a bug that's allowing large files to be uploaded despite the limits, so I've filed a bug here.
Would an ISAPI extension give me more control over request processing than HTTP modules and handlers, such as allowing me to abort an upload if the Content-Length header is seen to be larger than the allowed limit?
Update 2:
Sigh. Microsoft has closed the bug I filed as a duplicate but has provided no additional information. Hopefully they didn't just drop the ball on this.
Update 3:
Hooray! According to Microsoft:
This bug is being resolved as it has been ported over to the IIS product team. The IIS team has since fixed the bug, which will be included in future release of Windows.
The problem is that the upload happens all at once using the HTTP Post request so you can only detect it after it's done.
If you want more control over this you should try Flash based upload widgets which have this and more. Check out this link http://www.ajaxline.com/10-most-interesting-upload-widgets
Microsoft has responded on their Microsoft Connect site with the following:
This bug is being resolved as it has been ported over to the IIS product team. The IIS team has since fixed the bug, which will be included in future release of Windows.
If you are requesting a fix for the current OS, a QFE request must be opened. Please let me know if this is the route that you want to take. Please note that opening a QFE request does not necessarily mean that it would be approved.
So I guess we have to wait for the next version of IIS for the fix (unless a QFE request is fulfilled, whatever that is).
Is there a way to detect the size of a
pending file upload before the actual
upload takes place?
No. That would require access to the file size on the client. Allowing a web server direct access to files on the client would be a bit dangerous.
Your best bet is to place a line of text stating the maximum allowed file size.
OR you could create some sort of ActiveX control, java applet, etc so that you're not dependent on browser restrictions. Then you have to convince your users to install it. Probably not the best solution.
Well.... Depends how low-level you want to get.
Create a service app that acts as a proxy for IIS. (All incoming port 80 socket requests go to the service.) Have the service pass everything it receives to IIS (website listening on a different port or IP), but monitor the total request size as its received.
When the size from a give connection exceeds you're desired limit, close connection. Return a redirect to an error page if you want to be polite.
Silly, but it'll let you monitor data in transit without waiting for IIS to hand over the request.

ASP.NET and the Output Cache - how can see if it's working?

Problem: I've got an ASP.NET website and i don't believe that my code is getting OutputCached correctly. I'm using IIS7 performance counters to show me the hits or misses a second.
i've got a simple ASP.NET MVC website. I'm using the built in ASP.NET Output Cache magic.
Here's some sample code :-
[AcceptVerbs(HttpVerbs.Get)]
[ApiAuthorize] // <-- this checks the querystring for a "key=1234".
// Doesn't find it, then it throws a 401 NOT AUTH exception.
[OutputCache(CacheProfile = "HomeController_Foo")]
public ActionResult Foo(string name, byte? alpha, byte? beta)
{
}
so this means that each url query can be like the following :-
http://www.mydomain.com/Foo?name=hello+word&key=1234
http://www.mydomain.com/Foo?name=hello+word&alpha=1&key=1234
http://www.mydomain.com/Foo?name=hello+word&alpha=1&beta=2&key=1234
Now, notice how i've got the OutputCache referencing a config file? here it is...
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="HomeController_Foo" duration="3600" varyByParam="key;name;alpha;beta"/>
</outputCacheProfiles>
</outputCacheSettings>
</caching>
Nothing too hard ...
so here's the kicker! When I confirm that this is happening by using the IIS7 performance counters, it's saying that the output cache misses/sec are 100% of the requests i'm making a sec. Output cache hits are 0/sec.
I'm using a 3rd party web load stress testing program to bast my site with queries. Now, what's the source data? a list of names. The program keeps looping through all the names, then goes back to the start, rinse repeat. So it's BOUND to call the same query string at least once. IIS log files confirm this.
I'm not passing in any data for the alpha or beta.
this is my query string i'm hitting....
http://www.mydomain.com/Foo?name=hello+word&key=1234
... where i keep substituting the 'hello+world' with the names from the data source file and IIS logs confirm this.
So .. am i looking at the wrong performance counter? Are there any other tricks to see if it's getting outputcached? The code is very fast, so it's hard to tell if that is a cached result or not.
Probably way too late but to help others : If you had a cookie in your response header, that will prevent it from being cached. The outputcache (http) module has a lot of silent check to ensure the response is subject to being cached. Looking into it through reflection might give anyone candidate of failure to put in cache.
Use a tool like firebug and look at the response from the request. You'll be able to tell by the 200 or 304 whether the cache response was used (304) or if a successful response was sent (200).

Resources