No access through URL

Is there any way that I can prevent access to the secure part of my site through the URL?  I only want the user to be able to navigate the site by way of the interface, without being able to type in the URL.... any ideas?
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

As you are saying your site is secure, then why do you worry of anyone peeking through the url?
You can set some distracting message for people who are not authenticated. So they don't know what lies underneath.

And what interface are you talking about? I assume it is the browser, so a user has right to type whatever he wishes into his address bar. It is on the server which you can decide whom to show things or not depending on permissions.

I don't think this is an answer to a 250pts problem. Please clarify some more things like how you maintain the secure part etc . etc .

duerraAuthor Commented:
Alright, sorry I didn't give a better explanation... here we go:

Users on my site log in.  This is their authentication.  From there they have access to different functions throughout the site.  However, some of these functions are restricted, and while I have accounted for these restrictions, I would still feel a lot safer knowing that a user wasn't injecting into the URL variables and values.  I've done what I can to account for all scenarios that I can think of in my mind, but I'm still afraid that somebody will be able to figure a way around some of my security precautions.

My biggest risk comes from, as I stated before, injection of variables and values into the URL.  I've spent the past few days going through everything I can think of to stop any occurance of this, but I would still feel safer knowing that a user MUST navigate the site to be properly authenticated, and NOT typing it in via the URL.  

Now... I'm sure this can be done, as directly linking to resources on another server (like a picture or something) is often stopped by the host server, and that sort of thing.  I've also seen an online game where you weren't allowed to navigate to each individual script via the URL, and you had to do it through the game interface.  However, this site was framed, so I'm not sure the details there of how it worked.

Anyway, I hope this helps clarify.

duerraAuthor Commented:
Also note that these values I'm referring to are submitted via a from when done PROPERLY.  However, I've been able to sucessfully hack myself without going through the form.  I've dedicated quite a bit of time now ironing any flaws out, but I'd like to be able to force a user to use a form, rather than directly through the URL.  Also note that these HTML form values are NOT submitted via the URL normally.
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

Frames are not that good.

But do you know what yahoo and other sites are doing?
They print some characters on an image and ask you to type it into a text box so, you can check in the next page if it is correct , then parse the remaining content!

I hered that there is some functions in php which allows this thing. If anyone knows then please tell how to do it.

Else I will tell you tommorrow!

Till then Enjoy!
duerraAuthor Commented:
Actually, I'm already doing that for many other functions in the site.  What I'm doing now is actually related to forums and special permissions.  I don't want to ask a user to type in a security code every time they make a post =)

then why don;t you use the register_globals = Off
and use $_POST[variable] OR $HTTP_POST_VARS[variable] instead of doing $variable

that way any one passing content through the url will not getinto your processing.

duerraAuthor Commented:
I've thought about going that, too.  Unfortuantely, it would be a MAJOR inconvenience to go through my thousands of lines of script right now and change all my registered variables to accommodate for that.  

Now, I know that's not an excuse and it makes me sound really lazy, but if there IS another way around it, that'd be great.  I'm not lazy, it's just that I would much rather worry about other things than accessing all my global variables via $_POST[].  If not, we'll see what happens.  Either way, it's bed time, so I'll be back in a few hours.  

Thanks for the quick replies ;)


You can use these $HTTP_POST_VARS thing in the scripts which you feel is under immediate threat, then slowly you can migrate the entire things into that way.

Any way choice is yours!

Here is what I recommend:

1) You should use $_POST.  Conversion may not be a difficult as you think.  While this is not the prefered method, you can simply assign your old variable names to the $_POST variable names in front of your script.  So the first thing you do on the page is something like this:

$part_number = $_POST['part_number'];
$quantity = $_['quantity'];

Now turn register globals off, and you are converted and more secure.

2) In addition to doing this, you should always check the referer to make sure it is your domain.  This way you can stop someone who is really smart from getting around even this level of protection.  Fail if it is not your domain (I send a 404 or 500 error using PHP's header() function).

3) If you are using the data in an SQL statement for a database, you MUST also prevent SQL Injection.  There are many things you can do to prevent this.  The two best things to do are to a) use addslashes() if magicquotes are not turned on and the field is a string and b) Always, always, always, confirm the type of the data passed in to you for all non-string data!  So if you expect an integer, check that the data is an integer, and do this on the server.  Don't trust that your nifty javascript to check input will be used before getting to the server.

4) Turn off indexing in your .htaccess file so someone can't look at your unportected files just in case you forgot to protext an important file

5) Protect all PHP and other server-side scripts in a directory that can not be read from the web.  I always have a simple php page as my index file that includes the protected php file that contains my application.  That way you prevent another smart person from reading your files and getting insight into how they may further inject bad things.

6) This may be controversial, but I use my .htaccess file to make all 403 (forbidden access) errors looke like 404 (file not found) errors.  My reasoning is that if someone gets a 403, they know that the file or directory they are looking for exists and are more likely to try other means to get that file or directory whereby when they get a 404, they assume you don't have such a file.

7) While this one is not to help prevent query_string or SQL injection, don't foget to protect your client-side files (javascript, images, etc.) from bandwidth stealing in you .htaccess as well.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
duerraAuthor Commented:
Wonderful!  Thank you for the great tips!  Based on what you posted, I'd like to request just a little more help =)

Can you instruct me on how to do option numbers 2 and 7?  

Then just a little bit more questioning here...

In reference to #5, how could somebody read a PHP script from the web if it's server-side only??  I don't quite understand that.  Quite a bit of my functions are done in the script itself (which have to be in the web tree, I would think???)

And in response to #6, I'm doing something similar to that as well.  I personally think it's a good way to get rid of the stupid hackers (won't stop the smart ones much).  And just out of curiosity... how are 403 errors set???

In case you need to know, I'm on apache 2.xx (don't remember what), and php 4.3.1

Thanks again for the great tips!
Some important exceprts from my .htaccess file to illustrate my points (change '' to your domain:

# Use .htm and .html extensions on public PHP scripts so
# mailcious users don't know you are using PHP
AddType application/x-httpd-php .html .htm

# Always have an error document.  If you don't, your host
# may provide information about where you are hosted that
# may help them get into your site (yes, they can go to
# other public databases to get this, but why give them
# easy access to this information)
#Also make 403 errors look like 404 errors.
ErrorDocument 403
ErrorDocument 404

# Don't let them look at yout .htaccess file or they'll
# know some of your secrets
<Files *.htaccess>
  order deny,allow
  deny from all
  allow from

# Turn off indexing so they can look at your directory
# structure or file names
Options -Indexes

# This whole next section prevents other sites from
# stealing bandwidth.  Without this, a site can use a
# hyperlink from their site to yours to use a graphic or
# script or other client-side file.  Edit to suit your
# needs.
SetEnvIfNoCase Referer "^" locally_linked=1
SetEnvIfNoCase Referer "^" locally_linked=1
SetEnvIfNoCase Referer "^" locally_linked=1
SetEnvIfNoCase Referer "^" locally_linked=1
SetEnvIfNoCase Referer "^$" locally_linked=1
<FilesMatch "\.(gif|png|jpe?g|js)$">
  Order Allow,Deny
  Allow from env=locally_linked

# These lines stop some other malicious viruses by
# preventing atackers from seeing important information
# they need about your site.  Most of the above covers
# some of these, but it is always better to be safe than
# sorry.  This needs to be constantly updated to
# work properly.  You can redirrect to the 404 page if
# you so desire, I just send them to non-existent land.
redirect /scripts http://www.stoptheviruscold.invalid
redirect /MSADC http://www.stoptheviruscold.invalid
redirect /c http://www.stoptheviruscold.invalid
redirect /d http://www.stoptheviruscold.invalid
redirect /_mem_bin http://stoptheviruscold.invalid
redirect /msadc http://stoptheviruscold.invalid
RedirectMatch (.*)\cmd.exe$ http://stoptheviruscold.invalid$1

duerraAuthor Commented:

Last little things before I award you your points...

First, this stuff:
SetEnvIfNoCase Referer "^" locally_linked=1
SetEnvIfNoCase Referer "^" locally_linked=1
SetEnvIfNoCase Referer "^" locally_linked=1
SetEnvIfNoCase Referer "^" locally_linked=1
SetEnvIfNoCase Referer "^$" locally_linked=1
<FilesMatch "\.(gif|png|jpe?g|js)$">
 Order Allow,Deny
 Allow from env=locally_linked

Can I do this, except for, say, one or two directories of my choosing?  I would want to allow one or two directories public access, since I often link to graphics hosted on my server in signatures for forums and stuff.

Then finally, any last security tips?  The points are yours anyway, I was just wondering if you had any other nifty pointers for me to secure myself with.  Thanks a fortune!

(Of course add or remove URLs as needed and replace with your domains and your IP address or addresses if you have more than one that will use the script)

$referer = $_SERVER['HTTP_REFERER'];
if (substr("$referer",0,strlen($goodurl))==$goodurl OR
substr("$referer",0,strlen($goodurl2))==$goodurl2 OR
substr("$referer",0,strlen($goodurl3))==$goodurl3) {
    // Do your work here, it is a good referer
} else {
    header("HTTP/1.0 404 Not Found");

#7: See my post with the .htaccess file

#5: If you have not protected your PHP script, a malicious user can construct a request to download your PHP file without it going through the PHP processor, in much the same way you can download an image on the web.  It takes a little more effort than getting an image, but it is quite easy once you know the name of a file.  If you have indexing turned on, then it is very easy to see your unprotected script names to later download.

#6: I am not sure what you mean by "how are 403 errors set", but there are two ways I can answer this.  If you meant how is one generated, then, for example, if you have an .htaccess file with just the section the prevents a user from seeing a .htaccess file or just the line to prevent indexing, a user who happens to try to look at these files will get a 403 error if the file exists on your server, but they are not permitted to see it.  Of course, if the file does not exist on your server, then they will always get a 404.

If you meant how do I set a 403 to be a 404, see my previous post with parts of my .htaccess file.

If you meant something else, please let me know and I will respond.
duerraAuthor Commented:
LoL... I think our synching is a bit off =)

Everything's answered, 'cept for the one little thing... allowing a certain directory to be accessed by any other server.

For example, I have an image on my server at:

And I want that to be accessible from anywhere.  I see in your wonderful explanation how to stop this from occuring throughout the whole server.  Do you know how I stop it everywhere, except in this case, the /public directory?

Yes, you can do it for specific directories.  The hard way is to put a different .htaccess file in each directory with the rules for that directory.  It is hard because you then need to always update every instance of the file when you add new protections or rules that apply globally.

The easier way is to use <DIRECTORY> and <LOCATION> within the global .htaccess file.  It is esasier to give you a reference than to try to explain it.  See this: and other parts of the Apache documentation.

duerraAuthor Commented:
Awesome!  Thanks a bunch.  Hopefully everything will be 10x better now =)
One more point for #5, just to make it clear, you need to create a directory with file protection like rwx------ or if PHP needs group access, rwxr-x--- and put your script files in there.  That way a simple HTTP request can not get the files.  Since the files are only accessed by the server, there is absolutely no reason to make the accessible to the world.  In fact, make sure the files themselves have protections like rw------- or rw-r----- as an added level of protection.

Nothing is foolproof, ever, but with these protections, you will thwart off most casual and mid-level hackers.  It is kind of like putting one of those "Club" devices on your car.  You deter most, but not the criminal with a flatbed truck.  :-)
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.