Is this a web application vulnerability? - asp.net

I am passing a variable to a SWF file that provides access to several other SWF files. You can see the line I am using to assign the value to the variable beneath the THIS LINE comment below.
<script type="text/javascript">
/*THIS LINE*/
var flashvars = {a: "<%= User.Identity.IsAuthenticated %>"};
/*
Some other stuff here...
*/
swfobject.embedSWF("index.swf", "myAlternativeContent", "100%", "100%", "10.0", "expressInstall.swf", flashvars, params, attributes);
</script>
I am concerned that someone using an HTTP proxy could just switch the value of a from False to True if they wanted access. Am I right to be worried?
Is there a different way I should be controlling whether access to the child SWF is allowed?

I would say don't emit anything that they don't have access to. In this case, if they aren't authenticated, don't send any of that script to the browser.
Yes, you should be concerned.
Assuming you can't change the flow (ie: you have to send the script even if they aren't authenticated), then I'd change the "true/false" value to some type of key. The children should verify the key was passed before executing.
If possible, make the key user specific.
This doesn't completely solve the issue, but it would be harder for someone to provide a key that they don't have.
UPDATE:
Based on the very good comments, I have a different route.
Add a web request handler (.ashx file) to the site. Have the client call that to load the swf file. The handler should first test to see if they are indeed logged in. If they are, serve the file. If not just close the connection.
Basically change the embed line to look something like:
swfobject.embedSWF("grabFile.ashx?id=123", "myAlternativeContent", "100%", "100%", "10.0", "expressInstall.swf", flashvars, params, attributes);
Then have a .ashx request handler on your site test for being logged in prior to response.writing the actual contents of the swf file.

Yes, they could. Security doesn't work on the client side, you'd have to control access to the files from the server.

Yes, what is keeping an attacker from writing a static html page that does this:
var flashvars = {a: "AUTHENTICATED"};

yup, this is a vulnerability and you don't need to use a proxy to exploit it. You should refuse access at the server if your users aren't authenticated.

Yes. If the user has Firebug, they could simply look at what the appliation's code looks like when logged in, and then change it to mirror that when they're not logged in. You should handle authentication on a per request basis, and server-side. If you try:
If User logged in:
Put Flash in page
Else:
Put angry message
The user can still copy the Flash snippet when they're logged in, and paste it when they're not logged in, with Firebug, etc.
However, if you use:
Put Flash in page
Listen for requests from the Flash app to the server (for database content):
If the User who requests content is logged in:
Return content
Else:
Return angry message
This will work.
If the entire app is Flash based (ie, it doesn't need database access), the only way to secure it will be to protect folders at the server level (see Amember, et al). Even if you make the Flash application rely on a dongle with the server for authentication purposes, the user can simply download your Flash scripts, decompile them and distribute them for free use. They can still do this with the folder protection, but at least free users won't have that access. Your best bet is to make the application rely on content that comes from your server.

Related

in Xamarin/App how do I Secure Files on ASP.NET Restful Server in folders from other users and general public

I have an APP using restful server. I want to store PDF's, images, etc. in folders on my server. How can I make the folders private on server, yet allow App to access only certain folders depending on their app access.
I have different users in app and security/tokens established, etc. But if they upload an image for their avatar (and now PDF's), they get stored in folders on the server, and I just display with image source=https://blahblah.com/org1/images/user232.jpg.
How can I make that not accessible to outside (like just going to browser), yet make accessible to app if they have correct login privilege's for that organization/user? And then further extend that logic to more sensative PDF's, and other docs uploaded through app. I didn't want to store in SQL since then harder to use simple image display tools and I already have upload and media managers using folders structures.
I can see how to secure if logging onto server through browser (credentials), but can't see how you connect App with that security level and maintain it for the session.
For future readers. Most of the work was done on the restful (ASP.NET) side. I first tried using authorization/Authentication in web.config and having Allow and deny. This allowed a redirect of a user to a login page; however, it didn't do it if they entered an image exactly correct on website.
Found HTTPHandlers (adding in webconfig ) where I could write code that would be executed once the user entered the specific Image address xyz/abc/image.png. I found this a bit feeling like a hack.
So lastly modified my
routes.MapRoute(
name: "staticFileRoute",
url: "publicstor/{*file}",
defaults: new { controller = "Home", action = "HandleStatic" }
And add a function like this to home controller.
[System.Web.Http.HttpGet]
public ActionResult HandleStatic(string file)
{
if (Session["OrgId"] == null) //todo need to add full security check.
{
return View("Login");
}
else //Either coming from app or coming from web interface
{
string mimeType = MimeInfo.GetMimeType(Path.GetExtension(file));
return File(file, mimeType);
}
}
The final bit is on the Xamarin side to now pass security when getting an image. Since just a simple Xamarin.Forms.Image doesn't have a way to pass login info or tokens/authentication I used
https://forums.xamarin.com/discussion/145575/image-from-url-needing-auth
And established an appwide webclient that logged in generally once forcing my restful to go through security validation, then just accessed the images/documents through out my app from that webclient. So far so good. Hopefully there are no holes.
This gives the gist to a future reader.

Windows authentication without a backend?

We have a web application that runs on ASP.Net. I don't know much on authentication for ASP.Net, but the application never asks me for a username and password (when on a Windows machine) and that's really great. The app has this in the web.config file: <authentication mode="Windows" />.
I've been assigned the task to re-create this application. I noticed that the only use for the backend is to get the user's AD account username. After that, it makes some HTTP requests that require the username. Besides that, the back-end is useless. If that's the case, then is there a way for be to get the user's credentials without needing a back-end (ASP.Net server)?
Really, a "backend" is anything on the server. You can't have a website without a web server, and that server is the "backend". It's always doing some kind of processing, even if it's not using ASP.NET.
But if I understand your requirements, you just want a way to inject the username into an otherwise static HTML file.
IIS handles the Windows Authentication, so you don't need ASP.NET to have Windows Authentication. But technically, static means static, so you can't modify an plain HTML file before it's served (unless you change stuff in IIS that would slow down actually static files).
But, the next best thing is to use a feature in IIS called Server-Side Include Directives (SSI). By default, IIS is setup to send files with extensions of .stm, .stm, and .shtml through its SSI engine, which processes the file and looks for specific "directives".
One of the features is the #echo directive, which lets you inject any IIS server variable into the content. If Windows Authentication is enabled and working, IIS stores the DOMAIN\username in the LOGON_USER server variable.
You can inject that into your page, and use JavaScript to split the domain and username into separate pieces. But you can't inject LOGON_USER directly into the JavaScript because of the slash, which JavaScript interprets as an escape character. So you have to put it in an HTML element, and use JS to pull it from there.
Here's an example of a simple page that stores the domain and username into JavaScript variables and displays them on the page. You'd have to save this file as .stm, .stm, or .shtml.
<html>
<body>
<span id="domainUsername" style="display:none"><!-- #echo var = "LOGON_USER" --></span>
Domain: <span id="domain"></span><br>
Username: <span id="username"></span>
<script>
var domainUsername = document.getElementById("domainUsername").innerText.split("\\");
var domain = domainUsername[0];
var username = domainUsername[1];
document.getElementById("domain").innerText = domain;
document.getElementById("username").innerText = username;
</script>
</body>
</html>
And remember you still need <authentication mode="Windows" /> in your web.config.
Then you can also set that file as the Default Document for your website (since IIS won't, by default, use a file with those extensions as the default doc).

Add IBAN check to widget validation

For an employee questionnaire I would like to add an IBAN check to a textbox widget. Is it possible to add a library like https://github.com/arhs/iban.js as an external resource in App Maker? How do I have to implement a validation method once the library has been added.
You can easily add any external library. If library is available via CDN (Content Delivery Network) you can just add URL in Application Settings -> External Resources -> JavaScript URLs
otherwise you can upload the js file as app resource (Settings -> Resources) and use resource's URL instead.
The library will help you to validate input on client:
// onValidate event of input widget:
if (!IBAN.isValid(newValue)) {
return 'Please, provide valid account number';
}
But it will not help you with server side validation... So, end user can in theory compromise your system through dev console. You can try to copy/paste library's code to server script and make extra validation in onBeforeCreate and onBeforeSave model's events but most likely it will require some additional tweaks.
You may also consider using Regex to validate the IBAN - you won't need to worry about pulling in external JS then. This answer may be useful. With this regex, you can validate the string server side, which is more secure. This link has more information on validating RegEx in Javascript.

Is Request.IsLocal secure or can it be spoofed?

I have a webpage which checks for an encrypted cookie on page load to determine user identity. However, when I'm testing the page locally on my development box, I don't have access to that cookie.
Previously I used an appsetting to tell the page whether it was in development mode or not, and when in dev-mode it would load a fixed user identity. Then I discovered Request.IsLocal
I can simply check like this:
if(Request.IsLocal){
FormsAuthentication.SetAuthCookie("testUser", false);
}else{
FormsAuthentication.SetAuthCookie(/*EncryptedCookieValue*/, false);
}
Is this secure? Is there any way a malicious user could spoof IsLocal?
I think your actual question is, how do you have development only functionality?
You could you use: Environment.UserInteractive
http://msdn.microsoft.com/en-us/library/system.environment.userinteractive.aspx
It returns false when running in IIS or a Windows Service, true when their is a user interface i.e. Visual Studio when your developing.
I think this is better than a DEBUG pre processor variable because the behaviour is more consistent, you could accidentally upload a DEBUG version of your dll to your live environment unless you have a very tight build/release process.
As a rule of thumb it's not a good idea to trust anything from the client.
I'd also be pragmatic, what are you protecting and how much effort would someone go to hack in?
The below SO post goes into some of the reasons why you shouldn't trust it:
Can I fool HttpRequest.Current.Request.IsLocal?
Reference
You can view the source at http://referencesource.microsoft.com
public bool IsLocal {
get {
String remoteAddress = UserHostAddress;
// if unknown, assume not local
if (String.IsNullOrEmpty(remoteAddress))
return false;
// check if localhost
if (remoteAddress == "127.0.0.1" || remoteAddress == "::1")
return true;
// compare with local address
if (remoteAddress == LocalAddress)
return true;
return false;
}
The code for IsLocal appears to be robust - I can't see any flaws in its logic so for your purposes it should be fine.
However, you should be aware that if your application (or any other application running on the same server) makes any HTTP requests whose destination can be influenced by the end user then you should add an extra layer of security such as a secret/expiring key or token to your request or you could secure the HTTP request when made so that it is not possible to request a local resource.
e.g. Say your website has an end point such as http://www.example.com/DeleteAllUsers and in the code that handles this request you are checking IsLocal to make sure that users can only be deleted if it is a local, trusted request.
Now let's say you have a function on your website Enter a web address to view headers: and the user enters http://www.example.com/DeleteAllUsers in this text box, causing your application to request DeleteAllUsers and satisfy the IsLocal security check because the HTTP request is made from your app. This is how IsLocal can be exploited, and I realise it is a contrived example to prove the point, but lots of websites do similar things such as grabbing a preview image of a URL to display. If nothing on your server can be made to make a local HTTP request you should be good to go.
You should not put this code on a production server, for the reasons mentioned in the other answers.
However, you could do
#if DEBUG
if (Request.IsLocal)
{
FormsAuthentication.SetAuthCookie("testUser", false);
}
else
{
#endif
FormsAuthentication.SetAuthCookie(/*EncryptedCookieValue*/, false);
#if DEBUG
}
#endif
On your development box, run a Debug build. In production, deploy a Release build.
Determining the remote IP is tricky and depends on configuring the server correctly.
For example a misconfigured server might use X-Forwarded-For to determine the IP, but it can be chosen by the client. But when using a reverse proxy that sets it to its own IP, this is the correct way to determine the IP.
Using the IP from the socket can be wrong as well, consider a reverse proxy running on the machine as the webserver.
=> If possible use a different authentication mechanism

asp.net secure images against static requests from other users?

I work on a site that generates dynamic images for each specific user. Sometimes these images contain depictions of very sensitive data. Lately we have started to see requests for images that belong to a different user in the form of
http://myapp/images/someuid/image1.jpg
obviously, someone figured out they could access another users images if they created the proper URL. we store the images to the file system to help reduce bandwidth.
how can we protect this - some sort of http handler?
is there a way of serving the image to take advantage o -f caching without having to write it to the file system and letting IIS do the dirty work?
Use an .ashx:-
TimeSpan maxAge = new TimeSpan(0, 15, 0); //!5 minute lifetiem.
context.Response.ContentType = "image/gif";
context.Response.Cache.SetCacheability(HttpCacheability.Private);
context.Response.Cache.SetExpires(DateTime.UtcNow.Add(maxAge));
context.Response.Cache.SetMaxAge(maxAge);
context.Response.Cache.SetLastModified(lastModified); // last modified date time of file
context.Response.WriteFile(filenameofGif);
You can include what ever code checks you need to ensure the correct users is accessing the image.
I think the best option would be to deny direct access to the images from the web and create an aspx that will check users permissions and return the right image.
If the images are to be private to a particular user, then you should either store them outside the main application folder or put a web.config in each of those image folders (like someuid) and limit the access in the configuration file - either cutting out everyone (deny="*") or allowing access just for the particular user (allow="john").
In both cases you can use a handler to stream the image to the user, but at least you can check for permissions now. If the requesting user does not have permissions then throw a 401 at him or even display another image like imagenotfound.gif.
However, I am afraid the handler will generate a lot of traffic as there will be one call per image, I don't know how many images you're displaying per user.

Resources