Link to home
Start Free TrialLog in
Avatar of spoowiz
spoowizFlag for United States of America

asked on

Need code (in Java?) to display html page without showing URL

What needs to be done:
--------------------------------------
An html page which accepts a userid and pageid
Depending on the userid/pageid, I would like to display a specific html page
And, most importantly, I definitely do not want the reader to know url of the html page (and the url should not show up in history)
Can this be done?
My host is on Unix. Java preferred. PHP works but I don't know PHP.
Thanks

For example:
----------------------------------------
userinputpage.htm:
   accepts as input userid and pageid.
   on submit, display a page

If it can be done, I need good direction or example really fast.
Thanks.
Will split 500 points if more than one good participant.
Avatar of j0kStA
j0kStA

You could use XMLHTTP to take a screen scrape of the HTML file you want to display. See the following example.

<HTML>
<SCRIPT>
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.Open("GET", "newpage.html", false);
xmlhttp.Send;
document.write(xmlhttp.responseText);
</SCRIPT>
</HTML>
jokSta,

Even with that solution, whatever page your code is stored in will still be put into the user's browser history.  For security reasons spoowiz, you can't control what is written in the client's browser history.  

You can overwrite the last entry in the browser history by using the:

 location.replace = "somepage.asp"

"The replace method loads the specified URL over the current history entry. After calling the replace method, the user cannot navigate to the previous URL by using browser's Back button."

And if you want a Java or PHP solution, you should have the EE admin transfer this question to one of those are or open point pointer questions to this one.
One way to do this would be to have a single frame with one window. Have the child check referrer and only allow call from your   parent frame page. Do that with any other page you need to hide the code of.
Any solution that downloads the code is going to show the URL to a potential attacker.
The question really needs to be restated slightly. You probably want some form of security, as in you don't want the user to be able to get into the page without logging in. Is that the reason for not knowing the URL? If so, the hidden URL thing is a red herring.

You can't of course prevent a determined user from figuring out how to hit your page, because they can look at the source code of your web page, or if they are more determined, write code that hits your page and/or watch the network traffic in and out of their box to see what's really happening. But you can hide the real implementation from the user.

For example, if I don't want you to know that I am using a Java servlet, I can hide that detail from you. I will give you an example from Tomcat servlets. I would configure a context in servlet.xml:

<Context path="foo" docBase="blah" debug="0"/>

This means that when the user types:  http://mysite.com/foo

they are really in my directory "blah"

Next, I can define an alias to the servlet in web.xml
    <servlet>
        <servlet-name>RunMe</servlet-name>
        <servlet-class>HelloWorld</servlet-class>
    </servlet>

So when the user writes: http://mysite.com/foo/RunMe

they would actually be executing code named HelloWorld.class, which was generated from HelloWorld.java

Similar solutions exist on many platforms such as apache, and doubtless IIS if you really must use Microsoft's buggy, inferior stuff.
This kind of thing is elegant in that the user doesn't need to know that I am using a servlet, and we can allow them to type less, but I don't feel it's useful for security,
unless you are paranoid about someone using some knowledge of HOW you are implemented to attack your system.

That's why I think you really mean to ask "How do I stop someone from just hitting the URL without logging in" which is a totally different question.

That requires some server-side code.

In apache, you can password-lock a directory, so you can allow people to log in and get any file from a directory. That's .htaccess:
http://httpd.apache.org/docs/2.0/howto/htaccess.html

If you want a full-fledged login system of your own, that's more complicated. I will show you one in JSP:

File: Login.jsp

<%
  String userid = request.getParameter("userid");
  String passwd = request.getParameter("passwd");
  if (userid.equals("Me")) {
    // ok, here's my fake successfull login. You could of course go to a database
    session.setAttribute("userid", "Me"); // ok, remember that I'm logged in.
    response.sendRedirect("Secure.jsp");
  }
%>
<form action="Login.jsp">
userid: <input name="userid">
password:<input name="passwd">
</form>


Then, in Secure.jsp:

<%
  if (session.getAttribute("userid" == null) {
    response.sendRedirect("Login.jsp");
  }
%>

... secure stuff goes here

You will never get the secure page unless you logged in and set the session first. If you try, you get instantly redirected to Login.jsp
That if statement must be at the top of every secure page. The same technique works in ASP
Avatar of spoowiz

ASKER

dbkruger - you're right on the nose. I will try your solution...
894359 - frame method doesn't hide how you get the "secure" url
jrram  - i'll try this too. simple and might be all i need.
Avatar of spoowiz

ASKER

jrram - not working. perhaps i'm doing it incorrectly?
alert doesn't show change of location and history shows url of page.

<html>
<head>
<script ty="text/javascript">
function changeload() {
  location.replace = 'xyz.htm';
  alert(location);
}
</script>
</head>

<body onload="changeload()">
<img src="abc.htm" >
</body></html>
Avatar of spoowiz

ASKER

dbkruger -
I tested and the result is that top.htm appears both in URL address and history. Did I miss something?

I simplified to:
testLogin.jsp:
<%
    response.sendRedirect("testSecure.jsp");
%>

testSecure.jsp:
<%
   response.sendRedirect("top.htm");
%>
sendRedirect actually changes the URL. It doesn't attempt to hide it.
If you want the redirection (and I still don't understand why except for esthetic reasons) then you must:

1. define a servlet mapping (which maps the name of the servlet to the code of the servlet).
2. define a url mapping to the servlet (which is a second layer that maps the URL to the servlet).

(Assuming you are testing on your own computer)

If you just put your code in the tomcat examples directory, you can just type:

http://localhost:8080/examples/servlet/MyServlet

This will automatically execute the class MyServlet.class

If you write your own context, add it to server.xml in the conf directory, then you can add a web.xml file to the WEB-INF directory:

webapps/yourapp/WEB-INF/web.xml

Inside that file, define a mapping

<servlet>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>com.righttrak.MyServlet</servlet-class>
</servlet>

<servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/foo</url-pattern>
</servlet-mapping>


There may be a way to hide simple html files, but I am not aware of it. What you can do, however, is write a servlet that echoes the file, and redirect that. I know that's not a very satisfying technique, and I still think there may be a better way to do whatever you want to do, but that is the answer to your question.

As a final note, suppose for arguments' sake that there is a way in Apache, tomcat, etc. to map some arbitrary name  "foo" to some specific html file "blubwat.html"
Aside from the name change for esthetic reasons, there is no security here, as everytime I ask for "foo" I will get the file. So please be sure that whatever you are trying to do, you have thought out what's really happening.
ASKER CERTIFIED SOLUTION
Avatar of dbkruger
dbkruger

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
oops^2

correction to the previous:

String file = (String)s.getAttribute("file"); // HttpSession built on old, unsafe HashMap, must cast to get compiler to swallow it.
Avatar of spoowiz

ASKER

dov - good idea! i think what you are trying to do is actually "read" the htm file and then "write" it like document.write. yes?
unfortunately, this code is way beyond my current knowledge of java. how do i call it with "xyz.htm" as parameter? thanks
Avatar of spoowiz

ASKER

dov - i'm accepting your solution. thanks for the idea. i'm going to repost in JSP since now I believe I want a JSP code for your idea. thanks.
Don't bother, it's exactly the same thing. For this reason, there isn't much point to a jsp version of this, but suit yourself.
Yes, this reads the file in and writes it out. As long as you're going to the trouble, if you want higher performance and have a small set of a few files, you could preload them all into a hash table, and if asked, just spew them out already in RAM. Just a thought. In order to do that, you would of course have to load them application wide, not just based on a session, or each user. JSP has an application object (used just like session) for just that reason.

Again, I'm curious why not letting the user know the filename is so important to you?

cheers,
Dov


<%@ page contentType="text/html" %>
<%
    String file = session.getAttribute("file"); // session is a predefined variable
    BufferedReader br = new BufferedReader(new FileReader(file)); // open the file
    String line;

    while ((line = br.readLine()) != null) {
      out.print(line); //predefined variable
     }
     br.close();
%>
Sorry, I notice you asked how to call it, which is fairly part of this question (and hey, I also gave you the JSP, though I warn you, there's no point!)

From a jsp page:

<%

  session.setAttribute("file", "abc.htm");
  response.sendRedirect("servlet/RedirectorServlet"); // assuming no name mapping, this is the class I wrote above
%>

Now of course, the $64k question is how do you intend to pick the filename. Based on what? If it's a straight mapping from user input, then this is no more secure than the original situation.
I just showed you one hardcoded to abc.htm because you asked how to set it. But if you get it from the url:

http://localhost:8080/yourapp/Login.jsp?file=abc.htm

and then your code gets the parameter from the command line:

<%
   String file = request.getParameter("file");
   session.setAttribute("file", file);

....

then what's the point? You just gave away the show. So you're going to tell me you are encoding it, and that:

http://localhost:8080/yourapp/Login.jsp?file=q11

means "go get abc.htm"

to which I say, any attacker that knows that will simply duplicate the query, so how are you planning to change it each time? Anyway, I'm sure you'll have follow on questions, which I will be happy to answer.
Avatar of spoowiz

ASKER

dov - it's not too important that the current user knows the actual file. What I'm trying to prevent is someone coming after this user and finding out which file was read. So as long as the file or method doesn't show up in the "history", then we're cool. and i think your method would do that.

unfortunately, i'm getting errors:
500 Servlet Exception
Note: sun.tools.javac.Main has been deprecated.
/testSecure.jsp:5: Incompatible type for declaration. Explicit cast needed
to convert java.lang.Object to java.lang.String.
    String file = session.getAttribute("file"); // session is a predefined variable
           ^
/testSecure.jsp:7: Class BufferedReader not found.
    BufferedReader br = new BufferedReader(new FileReader(file)); // open the file
    ^
/testSecure.jsp:7: Class BufferedReader not found.
    BufferedReader br = new BufferedReader(new FileReader(file)); // open the file
                            ^
/testSecure.jsp:10: Variable br may not have been initialized.
    while ((line = br.readLine()) != null) {
                   ^
4 errors, 1 warning

I just ordered a JSP book, but it won't arrive for a week or so. Is this something you can help with in short order? thanks.
String file = (String)session.getAttribute("file");

and you need to import java.io, using the page directive in JSP:

<%page import="java.io.*" %>