I am having what I believe is a strange problem. I have several sites developed on the same hosting platform. All site seem to be fine except for one of them. The website is set up around 1 page (index.php) that retrieves the correct data to display from the database based on the path_info - this has worked for years - now on one site this has stopped working. By stopped working I mean it the page below now goes to a 404 error - I was under the impress that it should see the index.php as the script to use.
I believe this is an issue with htconfig or another file I don't have access to being misconfigured on the host's end. Perhaps someone can shed light on where I might direct them. My own htaccess file is completely empty:
wwww.testsite.com/index.php/page1
The above used to go to index.php and then using $_SERVER path_info retrieve page1 and get the contents associated with page1 from the database and display that on the page. Can someone confirm I am not going mad - that the above should go to index.php please? and perhaps too explain why the url is now seen as non-existent since it doesn't seem to be going to index.php but to page1. Thanks in advance for any advice.
Can someone confirm I am not going mad - that the above [wwww.testsite.com/index.php/page1] should go to index.php please?
Nope. That should look for a file called page1 in the directory index.php in the document root for www.testsite.com.
I think you used to have an .htaccess file that looked something like this:
RewriteEngine on
RewriteRule ^index.php(.*)$ index.php
Another possibility is that MultiViews were previously enabled and now not anymore. With MultiViews you also get the behavior you described. If it's allowed by the hoster, you can enable it by simply creating an .htaccess file containing:
Options MultiViews
If you put an .htaccess file with either one of abovementioned solutions in it in your document root, you can verify this.
In Apache, if you have AcceptPathInfo on anywhere relevant in the Apache config (including in .htaccess, if the server config allows it) and there's a file /index.php, then /index.php/stuff should indeed go to /index.php, and should set $_SERVER['PATH_INFO'] to "/stuff". The CGI script handler and mod_php* even do this by default, so it should just work unless it's explicitly turned off.
Either way, if it's currently off, you can turn it back on by adding AcceptPathInfo on to your .htaccess file, if AllowOverride FileInfo is set for the site.
I make no promises about other web servers, but PATH_INFO is part of the CGI spec, so i'd think most servers would have a similar setting.
Related
I'm working on a PHP project using Apache 2.2.22 and PHP 5.3.10 and I'm running into an issue where index and index.php are being treated as the same file.
I have an admin/index.php that redirects to admin/index to allow my mod_rewrite rules in .htaccess to take over and reroute the request into a custom framework. The problem is, when the browser goes to admin/index it goes into an infinite redirect loop because the request is being sent to admin/index.php which redirects to admin/index
I've tried removing the htaccess file to see if there was a problem with my mod_rewrite rules that was causing it and it didn't change anything. It just redirects to admin/index endlessly.
I've never heard of this behavior before, skimming over some Google results and skimming through the apache configuration files didn't show anything really obvious. Has anyone seen this before and know how to fix it?
EDIT:
Below is the code being used by the index.php to redirect to index.
<?php
header("Location: index");
die();
This may be due to MultiViews being enabled:
The effect of MultiViews is as follows: if the server receives a
request for /some/dir/foo, if /some/dir has MultiViews enabled, and
/some/dir/foo does not exist, then the server reads the directory
looking for files named foo.*, and effectively fakes up a type map
which names all those files, assigning them the same media types and
content-encodings it would have if the client had asked for one of
them by name. It then chooses the best match to the client's
requirements.
— https://httpd.apache.org/docs/2.2/content-negotiation.html#multiviews
Try adding Options -MultiViews to your .htaccess
Enable rewrite Logging inside Apache and raise the log level. That way apache will tell you exactly, step by step, what request is rewritten how, in which order and why.
I have a problem trying to hide .php extension from the url
I have been asked to hide it and because they are on a shared host i don't think i have access to .htacess so is there another way to hide it through a php function that i would call everytime an anchor is being selected?
Is this truly about hiding .php or is it more about having cleaner URLs?
If you truly can't access .htaccess (i.e. your host has this turned off via AllowOverride None) and assuming you also can't have your Apache conf settings updated for your VHost, the best you can do may be
http://example.com/page.php/my/clean/url
By default, Apache will send this URL to page.php even with everything else after it. This is the most common way of creating "cleaner" URLs without access to mod_rewrite.
.htaccess is what you would have access to on a shared server, as opposed to httpd.conf, which you wouldn't.
Put a .htaccess file in your document root with the following
FAIL
If your site stops loading, then you can use .htaccess :)
Of course, ^ that is a joke.
I have always understood (unless im mistaken) that Apache's modrewrite engine requires
Options +FollowSymLinks
in order to work.
We have used modrewrite to hide the .php extension in addresses on a particular system in order to not reveal the chosen technology - PHP. We understand that one can still learn the server technology but you'd at least need to know how web servers work etc.
The problem is, the server tech's have brought up the risk in using +FollowSymLinks which i completely understand and agree with.
https://serverfault.com/questions/195570/htaccess-security
Aaron Copley: Symlinks aren't necessarily bad but you have to have a clear understanding of your implementation of Apache. To a non-chrooted
Apache, symlinks certainly pose a significant risk to exposing files
outside of your document root.
At the moment the system parses REQUEST_URI as such:
All rewrite rules are written to index.php
URL domain.com/request
REQUEST_URI = /request (trimmed as "request")
Using PHP switch () we check case 'request' : inlclude xyz.php;
exit;
This is a fairly common technique, but how would i implement the same result without the need for +FollowSymLinks and without having to go through every script in the system and change navigation links?
modrewrite will also work if you enable the following:
Options +SymlinksIfOwnerMatch
This causes Apache to check the owner of the link and the target, and only follows the link if the owners match.
Perhaps your server guys would accept that as a reduced risk?
More info here: http://onlamp.com/pub/a/apache/2004/02/19/apache_ckbk.html
The Apache documentation states
If your administrator has disabled override of FollowSymLinks for a user's directory, then you cannot use the rewrite engine. This restriction is required for security reasons.
Check this link:
http://httpd.apache.org/docs/current/mod/mod_rewrite.html
Ok I know im answering my own question, but im going out on a limb...
I should probably have mentioned before that the site will NOT be public as it is an administrative system so we don't care about search engines
Would i be able to do this instead of the existing implemented modrewrite:
.htaccess file:
ErrorDocument 404 /index.php
index.php
header("Status: 200 OK");
header("HTTP/1.0 200 OK");
I know this is messy, but we do not have time and the server tech guys will not budge, the $_SERVER['REQUEST_URI'] should still contain the same info???
Please feel free to comment and down/upvote, but please remember i know this is extremely cowboy and it's merely a temporary workaround
Important Note
POST requests do NOT work this way because Apache redirects to index.php (losing the POST data) you could still use GET info
I believe I'm looking for the Apache setting or mod that accomplishes this behavior because I need to turn it off or alter it in some fashion. Here's the deal:
I have my own CMS that has its own router to handle redirects, includes, 404 errors, and pretty URLs. The mod_rewrite rules work perfectly to direct the appropriate requests to this router, but there's a strange case that causes Apache to freak out and never even send the request to the router.
File located at www.example.com/contact.form.php
CMS content located at www.example.com/contact/contact-us
Requests for the CMS content should be going to the router because it does not match a file or directory that exists in the file system. What is actually happening is some sort of bizarre request that finds the contact.form.php file but somehow still causes Apache to give its own 404 error.
The router is designed to catch 404 errors, so Apache's 404 screen should never be seen. All URLs entered for this domain outside of the contact "directory" (no matter how absurd) make it to my router and either retrieve the correct content or show my 404 page.
The work-arounds I've come up with so far:
Change the filename to form.contact.php -- which disables any CMS content that may eventually exist in www.example.com/form/...
Create an empty directory at www.example.com/contact/
The conflict is clearly tied to the "directory" name matching the first part of a PHP filename. This behavior exists any time this condition is met, and it is non-existent when it is not met. Unfortunately, with a CMS, I can never guarantee that "directory" names won't collide with PHP file names. For this reason, my focus is on tweaking Apache.
I've searched with all kinds of keyword combinations, and I can't find the answer anywhere. Any ideas?
Found the answer elsewhere after a lot of searching.
The problem is Options MultiView is turned on.
For me, I am using virtual hosts, but I am configuring most of my settings in the user.conf file for apache on Mac OSX Lion. I am not sure if I added this, or if it was already there...
Here is what I did
Open Terminal App
type: cd /etc/apache2/users
type: ls
From the list that prints out, you should see a file that matches your username: USERNAME.conf, where USERNAME is your actual username
type: sudo nano USERNAME.conf
You will probably have to enter your password
Find this line: Options Indexes MultiViews
Change it to: Options Indexes
ctrl+x to exit, hit "y" when prompted to save the file and enter when it asks about the filename
Alternatives
You can add Options -MultiViews if you don't see anything there.
Also you can edit your httpd.conf file if the above does not apply.
And if you use virtual hosts, you can edit your httpd-vhosts.conf file. For each site, edit the MultiViews Option within the tags. Either by adding "Options -MultiViews" or removing "Options MultiViews" if it exists.
Hope this helps somebody else...
I use Minify to minify and cache all my script requests. I only want my users to be able to access the minified versions of the JavaScript files.
Minify lies at www.example.com/min and my scripts are at www.example.com/scripts. How can I block direct access to doc_root/scripts which is where my unminified JavaScript files lie. I'd rather not put them out of the document root but it's an option.
Please note that I'm using Zend Framework, so the actual root of my application is shifted to www.example.com/public. An htaccess file handles the rewrite.
Can't you just use an .htaccess file inside doc_root/scripts to prevent all access over the web to .js files over HTTP?
It won't stop minify, since that provides indirect access.
So in doc_root/scripts/.htaccess, something along the lines of
<Files ~ "\.js$">
order allow,deny
deny from all
</Files>
Note that the location of the .htaccess file matters in this case.
You effectively can't block end-user facing code. Even if you served it with PHP or another server-side language and blocked direct requests, it's of course still possible to read it directly with a number of tools.
You should code with this in mind and be mindful with javascript comments, business knowledge, etc.
UPDATE:
However, if you're talking about code that doesn't ever need to be accessed by an end-user, you could as you mentioned move it out of the server root, or you can block the files in your directory (or an entire directory). It's easy with Apache's .htaccess.
order deny, allow
deny from all
You could also redirect the source files to the minified versions with mod_rewrite in your .htaccess file.
RewriteEngine On
RewriteRule /scripts/(.*)$ /min/$1 [L,NC]
Depends on the server you're using. Assuming it's Apache, you can add this to your .htaccess file:
<Directory ~ "\scripts">
Order allow,deny
Deny from all
</Directory>
Or something to that effect..
The only way is to check referers, and not everyone sends them, or sends a real one. In other words, you can't block direct access to anyone who really wants something. It's impossible to determine with 100% accuracy if a request is a direct one or is being done via a <script src=....> type request.
For your Javascript to actually run the user's browser must be able to read it ultimately.
As such there's no real way to "block" access to your scripts folder (well to be precise you can but that would break your website since the browser would not see the files in order to run them.)
One solution could be obfuscation, which makes the javascript code harder to read / understand but ultimately the user will see the code, and with a bit of persevering reverse engineering it can be de-obfuscated.
Another thing i've seen someone do is creating an "empty" js.html page, and insert all their javascript into script tags in the page (embedded, not external), and from his main page make ann ajax request to js.html and embed it at the bottom of the page. kind of a round about way but the user will not see the js when viewing the source unless using developper tools such as firebug.
Note that the last option also might cause some delay depending on the abount of code you are loading. but here the key is not blocking access to your scripts, but just making them harder to obtain / read / copy.
Edit: oops, misread as well. I think the best solution in this case would be to go with an htaccess file in your scripts folder denying all access
This answer is little bit newer, than question (only several years, that’s nothing)
You cannot deny access to JavaScript file, because they wont’t be accessible from <script> tag.
But I found a workaround:
RewriteEngine On
RewriteRule ^.*\.js$ /invalid.html [R=301,L]
Place it in your .htaccess file in your home folder of web. (under htdocs or public_html).
This will automatically redirect everyone from it. So they don’t see it.