My website on GAE (Java 8 Environment) is working fine. However, I found out that files that are not in the WEB-INF folder, is accessible by the public simply by opening it in the browser e.g. https://example.net/resources/file.txt.
Several files, including javascript files, contain sensitive and security information that I wish to make inaccessible to the public. How do I this?
I had issues putting them in the WEB-INF folder since I couldn't figure out the proper way to reference them for the website to use e.g. < script >relative path to web-inf folder + resource< /script >.
If I could be taught to use WEB-INF properly, I would accept that as an answer to this question as well.
Edit:
There's some need for clarification. What I need to protect are the resource files. I understand that scripts need to be publicly accessible, in order for them to execute on the client side, though it would be great if I could somehow put them in the WEB-INF folder while still having them accessible for the site's execution.
But ultimately, if there was a method to fetch info from resources in the WEB-INF folder, via Javascript (or whatever can do the job outside a Servlet), then this will solve my issue. The resources are simply files containing text like keys, certain email addresses etc.
Related
I searched around the web and here and couldn't find a conclusive answer to this rather simple question. I am using Java+MySQL+HTML and CSS.
I created a webapp, and in this webapp the user can upload the photos path to the database .At the same time I am creating a folder completely outside of tomcat to copy inserted images there. The folder is on my desktop as I am on localhost, but I want to make the storage on the server not on my desktop.
After checking stackoverflow I saw that it is bad to store photos/images in tomcats webapp/AppName folder because this will overwrite the images all the time at redeployment which I don't want to do.
My tomcat folder is on desktop. Can I create a folder to store the images for this specific app here:
\Desktop\ApacheTomcat\apache-tomcat-9.0.24\ ?
The folder would be called TripAppImages like \Desktop\ApacheTomcat\apache-tomcat-9.0.24\TripAppImages and will be besides all of tomcats other folders like bin, conf, etc. I will also use this folder to display the images that the user inserted , back to him in a html page.
EDIT: ok so I have finally come upon a message from here how to create a folder in tomcat webserver using java program? from BalusC which says:
"Please note that you shouldn't store the files in the expanded WAR folder, or they will get lost every time you redeploy the webapp. Store them on a fixed path outside Tomcat's /webapps folder."
This I believe means that I can store the images like this \Desktop\ApacheTomcat\apache-tomcat-9.0.24\TripAppImages. As long ass they are not in the webapp folder it means they won't be overwritten.
The only folders you should avoid are temp, webapp, work and its subfolders, because yes, those folders can have its content replaced or deleted during deploys and cleanings, every other folder inside tomcat can be considered as 'just a folder' that, if you don't modify its contents, you can use the way you want. Of course it would not be normal or standard to, for example, store videos inside Tomcat\bin but if you don't touch the original files there you can do it.
So technically speaking, you can create a folder like \Desktop\ApacheTomcat\apache-tomcat-9.0.24\icecream and put images there it will not be erased or replaced by a deploy.
If it is just for you, temporary or not production, just avoid the three folders mentioned at the beginning and you are good to go.
As i know it returns the application path? But what exactly the use of it.
In many environments the application user is not allowed to read any files outside of the deployment directory. This is mostly done for security purposes - for example if someone hacks your application they won't be able to read a passwords file.
And in professionally managed environments developers often don't have a say in which directory the application will be placed.
So if you need to read a file like properties, images, certificates, etc. you can place it in the application directory (or .war file) and use getRealPath("") to get the path you need to load.
As an alternative you can place the external files on the classpath but there are sometimes issues with this. For large files most app servers will try to load the entire file into memory and cache it if it is on the classpath.
The getRealPath() gives the absolute path (on the file system) leading to a file specified in the parameters of the call. It returns the path in the format specific to the OS.
The getContextPath() on the other hand returns the URI or the relative path to the resource.
As far as I remember, I've used it to save images or other data files, since it allows you to see where your application is deployed at the moment. For example, Eclipse and Tomcat will create a temporary folder that's buried deep somewhere within your Eclipse profile and deploy the app there.
This is a real path in file system.
From javadoc:
The real path returned will be in a form appropriate to the computer and operating system on which the servlet container is running, including the proper path separators. This method returns null if the servlet container cannot translate the virtual path to a real path for any reason (such as when the content is being made available from a .war archive).
I think it is very clear. Why do we need this? Sometimes web applications perform some manipulation in file system. For example read stuff from files, write files etc. This API allows you to access the place where your JSPs and other stuff is really stored.
I have source folder test, in what there is package Resources.Data, that among others contains files data[0].xml, that I want to reference in webpage (it is acceptable that all files in that directory are visible). After I build the war, files are in war\WEB-INF\classes\Resources\Data. I can make a manual duplicate, to top level, but it seems a dumb thing to do.
My question is: How do I refence data[0].xml or is duplicate 'not a dumb thing to do'?
If you need the resource to be visible to the browser, then don't put it under /WEB-INF. Files in there are not visible.
It looks like you need to chance your build so that those resources are stored elsewhere, rather than copying them around.
You can read the file directly in the war.
InputStream in = MyClass.class.getResourceAsStream("/Resources/Data/data[0].xml");
You can then do whatever you need with the InputStream. This should occur inside of Java code, not in JSP.
You should consider storing this above the WEB-INF folder, though, so that it can be served directly. Duplicating the file is unnecessary.
I am attempting to store the change made to my application's properties. The .properties file is located in resources package, which is different from the package that contains my UI and model.
I opened the package using:
this.getClass().getClassLoader().getResourceAsStream("resources/settings.properties")
Is there a functional equivalent of this that permits me to persist changes to the Properties Class in the same .Properties file?
In general, you cannot put stuff back into a resource you got from the classloader:
Class loader resources are often read-only; i.e. held in read-only files / read-only directories.
If you got the resource from a JAR file, JAR files are not simply updateable. (To "update" you need to extract the old JAR's contents and create a new JAR with the updated contents. It is all to do with the structure of ZIP files ...)
In some cases, the class loader resource will have been downloaded on-the-fly, and there is no way to push changes back to the place where you downloaded from.
Even if you can update a resource you got from the classloader, it is a bad idea / bad practice.
Doing this "pollutes" the clean application installation with a user's preferences. Among other things, this means that the installation cannot be shared with other users (unless you handle preferences for multiple users ...).
There are security issues with having applications installed as writeable so that embedded preferences can be updated. Think viruses! Think one user who might be inclined to trash another user's preferences!
There are administration issues with having user-specific copies of applications. And if the user has to install his own copy of an app, there are potential security issues with that as well.
There may be technical issues with file locking or caching on some platforms that either get in the way of (safe) updates or make it difficult for an application to load the updated resource without a restart.
Finally, this is NOT the way that system administrators (and educated users) expect software to behave. Java applications should deal with user preferences in the expected way:
You can use the Java Preferences API.
You can write a Properties file containing the preferences to an OS-appropriate user-writable directory.
On Windows, you could use a Windows-specific API to store the preferences in the Windows registry, except that this makes your application Windows dependent. (I can't see any real advantage in doing this, but I am not a Window expert.)
When you wrap your app up as a JAR file, your properties file will be one (possibly compressed) file within that JAR, and it would be a bad idea to try to write to your own JAR.
getResourceAsStream() is meant to open resources for reading, and these can be anywhere on the classpath. You can't write to URLs or inside JARs, you can only write to files, so it doesn't make sense to give you the same API for output.
Find yourself a directory you're allowed to write into, and write your properties there.
It may be a good idea to copy your properties from your installation classpath (possibly inside a JAR) directly out to a file if it doesn't yet exist, as a first operation upon application startup. This will give you a properties file you can write to, yet the master copy of this properties file will come from your project deliverable.
It sounds like you want to store user preferences. Consider using the Java Preferences API for that.
In addition to Carl's answer, if you're going to read and write to this file frequently, and expect that your application will expand in scope, consider whether to go one step (or several steps) further and use a file-based database like SQLite. There are a few JDBC wrappers for SQLite that would allow you to go beyond the basic string key-value lookup that the Java Properties interface provides.
even though writing the file into resources is not good practical, we still need to do it when our application only run in IDEA locally without deployment, then we can do it as below:
URL resource = Thread.currentThread().getContextClassLoader().getResource("settings.properties");
String path= resource.getPath();
OutputStream outputStream = new FileOutputStream(path);
//outputStream write
I need some ideas on how I can best solve this problem.
I have a JBoss Seam application running on JBoss 4.3.3
What a small portion of this application does is generate an html and a pdf document based on an Open Office template.
The files that are generated I put inside /tmp/ on the filesystem.
I have tried with System.getProperties("tmp.dir") and some other options, and they always return $JBOSS_HOME/bin
I would like to choose the path $JBOSS_HOME/$DEPLOY/myEAR.ear/myWAR.war/WhateverLocationHere/
However, I don't know how I can programatically choose path without giving an absolute path, or setting $JBOSS_HOME and $DEPLOY.
Anybody know how I can do this?
The second question;
I want to easily preview these generated files. Either through JavaScript, or whatever is the easiest way. However, JavaScript cannot access the filesystem on the server, so I cannot open the file through JavaScript.
Any easy solutions out there?
Not sure how you are generating your PDFs, but if possible, skip the disk IO all together, stash the PDF content in a byte[] and flush it out to the user in a servlet setting the mime type to application/pdf* that responds to a URL which is specified by a link in your client or dynamically set in a <div> by javascript. You're probably taking the memory hit anyways, and in addition to skipping the IO, you don't have to worry about deleting the tmp files when you're done with the preview.
*****I think this is right. Need to look it up.
Not sure I have a complete grasp of what you are trying to achieve, but I'll give it a try anyway:
My assumption is that your final goal is to make some files (PDF, HTML) available to end users via a web application.
In that case, why not have Apache serve those file to the end users, so you only need your JBOSS application to know the path of a directory that is mapped to an Apache virtual host.
So basically, create a file and save it as /var/www/html/myappfiles/tempfile.pdf (the folder your application knows), and then provide http://mydomain.com/myappfiles (an Apache virtual host) to your users. The rest will be done by the web server.
You will have to set an environment variable or system property to let your application know where your folder resides (/var/www/html/myappfiles/ in this example).
Hopefully I was not way off :)
I agree with Peter (yo Pete!). Put the directory outside of your WAR and setup an environment variable pointing to this. Have a read of this post by Jacob Orshalick about how to configure environment variables in Seam :
As for previewing PDFs, have a look at how Google Docs handles previewing PDFs - it displays them as an image. To do this with Java check out the Sun PDF Renderer.
I'm not sure if this works in JBoss, given that you want a path inside a WAR archive, but you could try using ServletContext.getRealPath(String).
However, I personally would not want generated files to be inside my deployed application; instead I would configure an external data directory somewhere like $JBOSS_HOME/server/default/data/myapp
First, most platforms use java.io.tmpdir to set a temporary directory. Some servlet containers redefine this property to be something underneath their tree. Why do you care where the file gets written?
Second, I agree with Nicholas: After generating the PDF on the server side, you can generate a URL that, when clicked, sends the file to the browser. If you use MIME type application/pdf, the browser should do the right thing with it.