I have an asp.net page that allows a user to select an excel file on his computer and then (1) upload it to the server, and (2) import into a SQL server table. This works fine.
Now I want to enhance the pages functionality to allow the user to select a directory on his computer and then automatically upload/import EACH file (Only of types xls, xlsx) in the clients directory. How can I do this? (Alternatively the user can select a file and then check a checkbox that says "upload all files in this directory", then it will process each file, etc.)
I found a way to loop thru the directory on the server side. But I can't figure it out for client side. Thanks!
You can't. Or at least, you shouldn't be able to.
A properly written browser specifically prevents direct access to the file system of the computer it is running on as a security precaution. The only "correct" way to access a file on a remote machine is to use the browser's File Upload form control on the page and have the user specify the file (or files) they want to send you.
Basically, no.
Many advances have been made in browser security to stop people doing this sort of thing.
The main solution is to use some kind of local plugin that gives this sort of access, but as this can be used for many nefarious deeds, it's very much frowned upon now.
You can of course let the user choose many files, there are various methods for doing this - but you can't automate it by the browser.
What's to stop someone searching for 'creditscards.txt' and uploading it without the user being aware?
One way I can think of is a Java applet. This is executed locally and has full access to the computer and the browser. They are being shut down for similar reason: it's just not safe.
I have outlined a way, but I must emphasize that this must be avoided. It's not because you can that you should.
Related
I'm trying to create software that will add a computer to an Active Directory domain. One criteria I need to meet is the machine must be added to the proper OU. In order to do this I have a set list of site locations with addresses (this is how we determine OU). This list is currently in the form of an ACCDB file, and I want to include this within the application as the Access list will not be changed.
Everything I see wants the DB file to be connected to in a different location such as server or on the local machine. My preference is to use the DB file as a reference or something inside the program's .exe file itself. I may be missing something horribly obvious, but it's been messing with me for a couple days so I'm reaching out for help.
To clarify, this software MUST be self contained (no installer). It must also be able to determine the proper OU to join to the domain (no access to shares until the PC joins the domain). It must also be user-friendly enough to avoid mistakes, meaning I want to avoid copying distributing multiple files that must go to a correct location. This is why I want to embed the ACCDB file into the application for on the fly use.
Things get much easier because this is static data. You don't have to worry about persisting this data, reclaiming changes into your program, or users accidentally deleting something, etc. You will be able to just use an embedded resource in your application. In the link, follow the examples using the image file. Text file examples will corrupt your database.
However, there is still a trick to doing this. The problem is the Access engine included with Windows will not be able to open the database as a resource, and so you will need to save this file to the local hard drive. The good news is its not as bad as it seems, because your program can do this as needed, and make sure it's right, rather than asking the user to put a file in a specific place.
As for where to put the file when you extract it... the safest and best place is the Application Data folder. You can easily get the path for this folder by checking the results of this call:
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
This will give you a path where standard privilege users do have write access, no matter which user.
In summary:
Embed the ACCDB as a resource.
When your program runs, get the Application Data path using the Environment object.
Open a FileStream for writing to a file based on the path from #2
Open the embedded resource as a Stream object in C#
Copy the stream from #4 to the stream from #3. Make sure to use a mechanism intended for binary data, rather than text.
Close/Dispose your streams, so no locks remain on the file. This is as simple as putting using blocks in the right places.
Open a normal Access connection to the file you just made, using any of the thousands of tutorials or examples available on the web as a guide.
In this way, you only need to distribute the final .exe file, and users won't need any special permissions to use the database. You don't have to worry if a user deletes your file; it's still embedded in the application, which will recreate it if needed every time it starts up.
The downside is a clever user may be able to manipulate the database to end up in an undesirable OU. If you need to worry about this, you should consider having the program check a web service, rather than using embedded data. Anything you embed can ultimately be altered by an end user. A web service is also nice because you can update your mapping data as your organization evolves, without needing to rebuild or redistribute the program.
I have a web form which takes in user information. The value of various text boxes is used to build a html file. I write this html to a file( with specific name) and then prompt user to Save this file.This html is used for creating outlook email signatures. Currently I have this html within the application.This has been deployed to the server. I had to set write permission on this file for all users for it to work.
Are there any security risks? What happens if multiple users access this applications and write to the file at the same time.
When you say the file has "a specific name", do you mean that it is always the same name? If so, then yes, there will be problems if multiple users use this functionality at the same time. They'll be overwriting the one file and downloading each other's data. You would need to generate a unique filename each time the process runs to avoid this.
But do you actually need to save the file?
Or is your goal purely to produce some HTML for the user to download, and the way you are doing this is by writing it to a file, and then prompting them to download that file?
If you don't need to save the file, but rather just need to generate HTML and prompt the user to save, just serve it up as a normal page, and set response headers such that their browser will download it. Something along these lines:
Response.AddHeader("content-disposition", "attachment;filename=my_file.html");
From what I understand, the user fills the web form and submits. Immediately, an html file pops up for download from the server. I think this is very neat implementation of this scenario. You just need to make sure that resources are released properly in order to prevent locking of files.
When multiple users access this application, it should not break since separate files are created with a specific name (as you have mentioned). I don't know what logic has been used to create unique names. At some peculiar situation (this is purely dependent on your name calculation logic) if the calculated specific file name somehow becomes similar to an existing file, you should have code in place to replace or create a different version of the same file name. Locking could occur if you are writing captured data from web form into the same file again and again without disposing your stream/File objects . Make sure you dispose your objects after use in the code.
It would be great if you give access to the application pool of the web application to a user who has write access to that file/folder instead of giving everyone the write access. In this way, your application gets full rights to perform write operations rather than users having rights. If users have write access on the file/folder, it is very easy for anyone to peek in and do something unexpected.
Hope this helps.
I want to download Word file with FTP (thanks to webClient object). It's working fine but not in this case :
Users of my company can open this Word files. So, when a user has opened a file the DownloadData command returns an exception :
error 550 : File unavailable (e.g., file not found, no access).
There is a way to download an opened file with FTP ? If not, what can i do ?
Thanks !
This is almost assuredly a poor architecture for whatever project you are working on. You probably want to separate the user editable document store from the downloadable document store. There are many solutions for keeping the two directories in sync when a change is made by a user (dropbox, mesh, or even custom scripts using robocopy and such).
When an Office program opens a file for modification, it intentionally opens it exclusively. As a result, no FTP server is going to be able to open it, unless it uses the backup API. If it uses the backup API, it may well get some intermediate state, since Office may be in the middle of writing something at any time. So no sane person implements an FTP server to use the backup API.
I am trying to develop a web page which will allow users to download to the Directory of there Choice. In my search to find away to do this, I had found that you can't use "FolderBrowserDialog". I am also finding that the examples online will only search the websrver directeory path and not the local machine. Is there anyway to get the Directory Path? I have the code to FTP the File Down, I just have to replace the code for "FolderBrowserDialog".
This isn't really up to you as a website, it's really the browsers job to store where they want files downloaded to. There is a pretty necessary separation between the website and client machine going on here.
In a web application you can't arbitrarily read or write stuff on the user's computer. That would be a gaping security hole, so it just can't be done. The 'Save As' dialog is something that happens entirely client-side. Your control over the download process ends as soon as you set the MIME type and send the file data away.
Browsers wont usually let you to choose location for individual download. you can change your browser settings to update the download folder. If you want to have this in your webpage, you probably need to have an activex control. this activex control can show the directories in the client machine so that user can select those. You need to write code to download the file to that location using the WebClient.DownloadFile method.
http://msdn.microsoft.com/en-us/library/ez801hhe.aspx
Don't expect this activex control works with all your users.Browsers usually block activex control or prompt the user (if the setting is like that).
I have a windows Application that stores certain files in a directory. I would like to know if there is a way in .net that I can restrict users not to have access to that directly (by just going to that directory in windows, and grab files) so only my application can add/verify/delete a file in that directory.
Could you use the Isolated Storage in .Net? While, it isn't necessarily restricted away from your users it may be a lot harder to find.... (stores under the local settings\application data\isolated storage for the logged in user)
Via code you work with it by using / importing the System.Io.IsolatedStorage and then you can create directories, files, etc... normal.
You also don't have to keep track of the actual directory on the HD it's in as .Net manages this. Maybe a nice plus.
This is only possible if your application runs with different credentials than the user running the application.
By default all applications run with the credentials of the user who launched the process. This means the application has the same directory and file restrictions as the user. Without a different account, the application can only decrease it's ability to access the file system, not increase it.
Dealing with the file system is evil in general. Even if you could get the user to not play in that directory you still can't trust the results will be in the exact same state as you left them. It's possible for other users, physical disk corruption or any number of other things to corrupt your files.
The only way to sanely program the file system is to expect failure from the start and count yourself lucky when it actually works.
The application needs to run as a specific user - and that user will always have the same rights as your application. You can, potentially, make a service that runs as an administrator to prevent standard users from accessing a directory, but the administrator will still be able to change things in the directory.
I suggest you look for another approach for your problem. There are potentially alternatives - perhaps you should consider keeping some type of encrypted hash on the directory contents. That would at least allow you to verify that the contents have not been changed, although it won't prevent the change from occurring.
As others have mentioned, you need the application to act as a different user than the ones currently logged in. You should look into 'impersonation', here are some links that can get you started on getting your application to act as a different user when performing certain tasks:
http://csharptuning.blogspot.com/2007/06/impersonation-in-c.html
http://www.codeproject.com/KB/cs/cpimpersonation1.aspx
The easiest (although not secure in any way) method, would be to use a hidden folder, which the users know nothing about. so \servername\hiddenfiles$
A more secure alternative would be to change the credentials the program is using to access the folder. Is it necessary for them to access it as themselves?
An alternative would be to create a dummy account for each user, where they do not know the password. Make it relate to their windows login, so domain\myname becomes domain\mynamehidden. Then use this to connect to the directory.
This will ensure everything can be audited nicely too.
Look at FileSystemWatcher - it doesn't prevent from changes in directory, but allows to notify program about changes in dir.