Protect BIRT's report - security

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.

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.

Delphi & Twebbrowser - How to recover a security token supplied by a login page?

I am using the Twebbrowser in Delphi (2009) to log into cpanel on my ISP and add a new remote host IP address for a MySQL database. The user name and password are filled in by code as is clicking the submit button, using code gleaned from several places here.
Navigating directly to the hosts page causes the cpanel login page to be shown first. My program detects this and logs me in.
This uses a line like
WebBrowser1.Navigate'https://thedomain.sgcpanel.com:2083/cpsess1819495779/frontend/Crystal/sql/managehost.html');
which reaches the hosts page OK but I notice that the security token (cpsess1819495779) is changed to something else each time, presumably being supplied by the login page.
However if I try to login first as a separate operation and then navigate to the hosts page using
WebBrowser1.Navigate('https://thedomain.sgcpanel.com:2083');
followed by
WebBrowser1.Navigate'https://thedomain.sgcpanel.com:2083/cpsess1819495779/frontend/Crystal/sql/managehost.html');
I get a server message saying the url for the hosts page has an invalid security token - presumably the cpsess1819495779 bit
Question
How can I use Twebbrowser to get hold of the security token generated by the login page in order to use it to build the correct url for the hosts page so that I pass the correct security token each time.
It's probably something to do with cookies etc but I don't know how to deal with those (yet)
BTW as the Twebbrowser is not visible I did spend quite a few days trying to do the same thing using Indy's TIdHTTP but have given up with that as am getting too many errors I can't sort out.
I may as well answer this myself to close the question and maybe avoid any more down votes for posting a question after extensive research failed to produce the answer and that was framed without much of my code for brevity.
The API documentation for cpanel (the application used by many ISPs to manage MySQL, email etc) is here: https://documentation.cpanel.net/display/SDK/Guide+to+cPanel+API+2
part of that says
Security token After you log in to your server, it automatically appends a security token to the URL for your session. Security tokens
help prevent authorized use of a website through XSRF (Cross-Site
Request Forgery). Security tokens contain the string cpsess and a
10-digit number.
Logging in manually in IE / Chrome etc. does indeed show the token eg cpsess1819495779 inserted into the original url that was navigated to. So if I navigate to
https://thedomain.sgcpanel.com:2083/cpsess0000000000/frontend/Crystal/sql/managehost.html
(to logon to cpanel), the part of the url displayed in the browser after cpsess gets changed to something like this, where the number changes each time.
https://secureukm11.sgcpanel.com:2083/cpsess1819495779/frontend/Crystal/sql/managehost.html
However, using Twebbrowser to show that modified url using
memo1.Lines.Add(WebBrowser1.LocationURL);
or
ShowMessage('URL: ' + Webbrowser1.OleObject.Document.Url);
simply shows the original url with the zeros, not the real security token.
So the answer to my question seems to be it can't be done in Twebbrowser as the url is only changed at the server and and the security token is not transmitted back to the browser.

password token to view pdf

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)

sfGuard token login for wkhtmltopdf

wkhtmltopdf allows to make a screenshot of a browser view with a webkit browser.
I have a Symfony 1.4 application that requires login, which I would like to use wkhtmltopdf to create a "print this page" function.
How can I securely facilitate this. I'm thinking of creating a one-off token on each screen for the print button that allows wkhtmltopdf to login without using the password of the user.
Any suggestions for how to structure this?
We'vbe come to the conclusion to use the built in "keep me logged in" functionality for this problem.
Would you consider a different printing framework ?
What about jquery plugin (e.g. https://github.com/ianoxley/jqueryprintpage#readme) ?
That way you won't have to allow access to the restricted area from outside the session.
If you still want to use wkhtmltopdf, you can easily create an action that receives a url and a user_id and creates a unique token, I might save this token in your DB or in a Key-Value cache (depends what is your system architecture). I wouldn't create the unique token in advance, I think its better creating it on demand (When your user is asking a print).
You have couple of options in order to enable printing in secured actions,
1) Create a custom security filter. In the filter, in addition to authenticated request, you have to allow requests that contain "token" parameter with right combination of url and user
2) Change the action to unsecured. If you don't want the change the security filter, you would have to change each action to "unsecured" and create a function that verifies if either the request is authenticated or it has a proper token parameter.
It would be smart to remove each token after you used it once to make it even harder to guess a token.
In addition you might want to create a periodic worker that clears old tokens that were never in use.
Even though you already decided on an approach, I would still like to add one more alternate option that might help others viewing this issue.
Another alternate route might be to grab the current source of the page being viewed and post that into your printer backend using something like
$.post("/printer", document.documentElement.outerHTML);
This way you can also preprocess the HTML in an easy way. Your backed could first store the HTML and then parse it to for example convert images or perhaps remove some parts of the page that will not be used when printing.

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