password token to view pdf - security

I know that the title can be better, but I don't know how to define my problem.
my problem is the next, I'm not sure if it's possible to do, but i suppose that it is.
I have some .pdf online and i want to protect them for third people.
My idea, instead of assign a password and show an input like this:
I want to send the password (or token) in the path. something like
file.pdf?tpw=aaaa-bbb-dddd
Is it possible? I'm using C# to create the pdf.
edit: the case
I have an application which create a folder with some pdf, those pdf can be uploaded or created here with a form. (this part works)
All this documents are stored in internet (global access) then I want to prevent that 3rd people or search engines (I'm reading about this, it doesn't looks like a big problem)
Then here is the problem, i want to some users can access to some pdf, for example
user K can access to pdf 33
user j can access to pdf 54
but not k to 54, etc.
my idea is send to the user (they should access throw the link) something like "https://domain.com/pdf/33.pdf?password=222222" and without this password cant access.
if is not possible to do it, i can create an "intermediate page" to put the links there.
and send the url like "http://domain.com/pdf/view.chtml?id=33&password=222222"
edit: and prevent the access if they type https://domain.com/pdf/33.pdf
EDIT 2: SOLUTION (at least per now)
store into the database for each file
- filename - user(in md5) - token (in sha1)
send to the user a link like www.domain.com/api/showpdf.chtml?user=XXXXX&token=KKKKKKKKKKKKKKK
When the user clicks on that just check in the database by the user and the token if any file exist, if is this case show the file.
To solve the problem with the direct access, we are going to put the files out of "localhost" folders
Thanks for all.

I don't think it is a good idea to GET your passwords, they will be visible, the password should only be sent once, start a user session in the server, which will then create a temporary ticket for the user, and this ticket should be sent on each request via POST.
Anyway, you'll need to use a database and store users, passwords, files, and per-file permissions for each user, you could use a file, but it's never a good idea to store the passwords in plain text. I guess you already have a database running, you'll only need to add a files and a per-file permissions table to it.
Also, you should never keep the real password in the database either, but just a checksum of it (SHA-1, or similar)

Related

How to persist data in a command-line application?

I want to build a command-line application using Go or Node.js. I want to make it multiuser, so a login feature is needed. I can implement the login feature but I don't understand where should I store the user data which can be fetched any moment at runtime.
The user data is needed to check if a user is logged in or not if he is logged in which user it is.
Need help with a method to store user data to check logged in status
Edit:
I had thought of this- If the config file is present that the user is logged in else not. Then I realized that if one tampers the file, the whole point of login feature will get invalid. I am guessing there must be a better way to do it, which I am trying to know by asking here
Many cli utilities opt to store their configuration as a plain text file on the user's home directory.
You can use any of the available configuration formats such as JSON, TOML, etc.
Although it's good to mention that this is not a secure way of storing data and if users should not be able to see others information in any way this is not the preferred way.

Protect BIRT's report

I can prevent users opening BIRT report from website that I built. But considering the report's link still in browser's history, any user from this computer still able to open the report by calling the link from history, for instance.
How to prevent the link of BIRT's report stays in the browser, after user close the report? So the only way to open the report is from the website.
Or maybe someone has other better method to achieve the same goal? Like showing a user name and password in BIRT, before user can use the report parameter?
Unless the whole session is encrypted using https, letting the use enter a password in the browser and submit it to the server as suggested by James is a security risk.
The short answer is: Don't use the BIRT servlet directly.
You could use the commercial iHub which probably has an infrastructure for user access control.
If you are using open source BIRT, generate the BIRT Report on the server side as a file (or OutputStream), then return that file to the client under control of your application.
For more details, search the internet for "Integrating BIRT".
If your application isn't written in Java or you don't have enough control/knowledge to do it directly in the application, you could use a "one-time token" approach like this:
Within the application,
generate a random and unique token (it must not be predictable by knowing other tokens)
generate the BIRT report as a file (say, PDF), where the file Name contains the token.
return a "download link" to the user, which links to a simple servlet (see below),
giving the token as part of the URL (e.g. ?token=xxxx)
The servlet:
checks if a token is given in the URL
checks to see if a PDF-file with the filename matching the token exists
if the file exists, return it to the client in the HTTP body and then delete it.
That way, the token is used a one-time key: You can download the BIRT report exactly once if you know the token. This is all done directly from the browser and the token is consumed and therefore useless afterwards
The easiest way to use a password parameter.
select <feilds>
Where 'password' = ?
Use a text box parameter, and when the user runs the report they enter "password" in the text box or the SQL does not return results.
SQL is not case sensitive so, your password would not be case sensitive. Also this is a very low security measure. It is only appropriate to prevent casual access.
JavaScript is case sensitive, so you could write something (like a filter on the query) where your Pa$$worD is in a JavaScrip variable and compare to that for case sensitivity.
Open source BIRT is not intended to provide "Secure" access to data. If you must provide real security of the data, you need to do it before the client has access to BIRT.

Node.js user system

I'm currently working on a web application which deals with multiple users. Whilst it currently works, it relies on some real bad practises which I'll outline in a minute.
We're using MySQL as the database system, since we're updating our current application, we want to ensure everything is backwards compatible. Otherwise I'd look at MongoDB etc.
Our users are stored in a table aptly named login. This contains their username, email, hashed password etc and a field which contains a JSON encoded object of their preferences. There is no real reason for doing this over using a meta table.
So the bad practises:
We're storing the entire users login row, excluding their password (although this is an internal-only app) in a cookie. It's JSON encoded.
Once the user logs in we have a secure HTTP cookie, readable only via Node.js for their username and their password so that we can continue to keep the user logged in automatically.
We have a app.get('*') route which constantly ensures that the user has their three cookies and updates their acc cookie with new preferences. This means that every time the user switches page or accesses a new AJAX item (all under the same routes) they have an updated cookie.
Every time a user performs an action we do this to get their user id: JSON.parse(res.cookies.acc).agent_id yuck!
Now, each user is able to perform actions to certain elements on the page, this effects everyone as the application is internal and anybody can work on the data inside of it.
I know what I want to achieve and how it should be done in say PHP, but I can't figure out the most effective way in Node.js.
I've started creating a User module which would allow us to get the user who performed the action and neatly update their preferences etc. You can see this here bearing in mind that it's a WIP. The issue I'm having with the module is that it doesn't have access to the users cookies, since it's not "a part of" Express. Which explains the last bad practise.
What would be the best way to handle such a system and remain bad-practise free?
I doubt it meets all of your requirements but its worth checking out out Drywall; A website and user system for Node.js
Hopefully it (or parts of it) could be helpful to you.
http://jedireza.github.io/drywall/

How to migrate passwords to a different hashing method

When changing the password-hashing algorithm for an application, how should the system migrate the values already saved in the database? I am well aware of the fact that I can't migrate them in their hashed form but that I need to have the input data in order to calculate the new hash.
There are two situations in which I have access to the input data:
During login
When the user changes her password in her profile settings
obviously only during one of these I am able to save the new hash to the database to migrate the password.
Although all of my colleagues are voting for method one my gut tells me to not do that. Is there a recommended way?
I see no reason not to do this on logon. Is there a reason you don't want to do #1? You validate against the new hash, if that fails, validation against the old hash algorithm. If that works, I'd then write the new hash over the old one. This means that your passwords will be converted faster, since users probably logon more than they go to change their password. Unless you force people to, I doubt most will change it on their own.
Here's an alternative solution if you don't won't to touch the old authentication code (ie. switching to a new framework) or just want to rid yourself of the old password fields:
Backup the existing table of passwords and then delete all the existing entries in the passwords column in this table (and update the column type if necessary of course) so that it is ready to receive fresh passwords with the new encryption.
The next time users try to log in, check the passwords table and if the user exists with no password, then prompt them with "We have implemented a system wide upgrade and all accounts will need to be re-verified from email. We have sent you an email, please use the email to complete your account upgrade. We apologize for the inconvenience."
The users will go to their email and click a link that may say something like "Re-confirm my account". They will be taken to a page that requires some secure token parameter, received from the link given in the email. This page will now ask them to enter their username and password (more importantly password) to complete the upgrade. You can require they enter the password twice, to guard from typos. Technically, you are creating their password here. Just simply ask for it in 2 inputs labeled "password" and "confirm password".
There are of course both pro's and con's to this solution as well, in comparison to the others. The good thing is you don't have to add old hashing code in your new environment and have it sit there until the one day all your users have finally logged in again. But this solution comes with the price of writing extra code as well (code to send emails/token and so on). You'll have to compare that work to the work involved with your proposed solution of intercepting the form input coming in, checking against old hashing, and then passing onto new authentication code. Just another idea for you.
Look at this IT scenario: Company A Took over Company B with similar business model, All the customers need to be merged into one bigger system owned by Company A, while decommissioning user system in company B which has different password hashing algorithm,
The best Implementation to getting this done is to Force password Change for all migrated users via their registered email address.
It's hard to get specific advice without knowing specifics about the problem. I'm going to assume that the reason you want to change your password storage strategy is because your new strategy is going to be significantly more secure than your existing strategy.
If that's the case, then what's the possible advantage to waiting? The idea is to mitigate the existing risk. Users, realistically, very rarely change their passwords. If you want to migrate to a new storage strategy, you should probably do it at login or you're just going to have a big database full of passwords with dubious security.

Displaying PDF to user

We're providing a web form whereby users fill in their personal information; some of it is sensitive information (SSN, Birthday, etc). Upon user submission, the data is prefilled into a PDF which is then made available via a link.
We are creating the PDF in a folder that has write access on the website.
How can we safely create and add PDFs in this folder, with whatever naming scheme (use a GUID?), such that another user cannot guess/spoof the PDF file location, type this in the URL and access another person's PDF?
Maybe the PDF folder has rights only specific to the user, but that may be a different question on how that is accomplished. (The number of users is unknown, as this will be open to public).
Any thoughts on this? In a nut shell, we need to allow the user to view a PDF of the data they just entered while preventing more-savvy users to figure out the location of PDF files, allowing access to other files.
Thanks!
trying to obfuscate the path to a file isn't really making it secure. I would find a way to email or another way to fetch it for the user instead of allowing access to an open directory.
Make the web app fetch the file for the user instead of relying on web server open folder permissions.
just keep in mind obfuscation isn't really security.
If it's really just for the moment, create a completely random file (20384058532045850.pdf) in a temporary directory, serve that to the user immediately and remove it after a certain period of time.
Whether your web app has write rights on that directory or not (I assume you are talking about chmod user rights) is not important, it can't be breached trough the web server and I don't see a problem in revealing the directory path per se - you have to reveal something in giving the user a URL to download. If your PDF names are random enough, there is practically no risk of somebody being able to guess the name of another PDF file in the same directory.
As the PDF contains sensitive data: Don't forget to turn off caching to prevent a local copy of the PDF being saved on the client's browser cache.
I don't know for sure whether turning off caching through the appropriate headers is enough to prevent local caching in all browsers. You might have to look into that.
For the purpose of pdf's, would it not be better (I know I will get flamed for this) to store the actual pdf into the database as a BLOB, which would be on the back-end of the website in question?
There will be no reference to the URL anywhere nor will there be a specific path highlighted in any links on that form.
Hope this helps,
Best regards,
Tom.
The simplest way is to proxy the file through your application (fpassthru() in php for example), this allows you to use what ever access control/identification system you already use for the dynamic content.
If you don't have any means of identifying your users and restricting access, and assuming your platform has a secure session mechanism, you can protect the file by storing the filename in the user's session and then returning that file (and only that file) to the user when requested. This should mean that an attacker would have to spoof a session to access the file so this should be as secure as your session mechanism is.

Resources