I'm using LAMP hosting on AwardSpace.com.
I have a private folder foobar and when a page </foobar> is requested, it redirects with a 301 to </foobar/> (, allowing pentesters to tell that the folder exists). This is so even after adding a htaccess file:
rewriteengine on
rewriterule foobar$ testpage.php
I believe the server itself is doing the redirection regardless of my hosting content.
How can the redirect be prevented?
(Tried removing traversal access to the folder but it shows 403 and testpage.php doesn't load.)
(For undocumented behavior,) To prevent folders being 301ed‑with‑slash‑appended, you can add a redirect flag to the rewrite rule:
rewriterule foobar$ /testpage.php [r]
With that, no one will know that foobar is actually a folder.
Suppose HTTP redirection is unwanted, r can be appended with =x where x is a value that doesn't cause redirection. This can be 305. This can be 510. This can be 200. In such cases the 3rd argument is ignored (cf):
rewriterule foobar$ yadadadaada [r=200]
Suppose that content is required, content can be added:
errordocument 200 "test page"
, or:
errordocument 200 /testpage.php
Related
Been trying to play with mod_rewrite through .htaccess in one Xampp virtualhost, but I am not getting the results that I am looking for.
What I am tring to do is to rewrite the following: www.example.com/name/billy.html to: www.example.com/billy
Without trying to rewrite the URLs the virtualhost is working fine, I have access to all pages. However, when I add the .htaccess with the corresponding rewrite rule I get a 404 page not found. The regex is working as expected though. I see that the request to www.example.com/name/billy.html it's been rewritten to www.example.com/billy, but the page doesn't load.
The name folder exists in the file structure and the .htaccess is inside the example folder.
Currently, my vh configuration looks like this:
<VirtualHost *:80>
DocumentRoot "/Applications/XAMPP/xamppfiles/htdocs/example"
ServerName www.example.com
<Directory "/Applications/XAMPP/xamppfiles/htdocs/example">
Options Indexes FollowSymLinks ExecCGI Includes
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
And this is the content of the .htaccess file:
RewriteEngine On
RewriteRule ^name\/([a-z]+).html$ /$1 [L,NC,R]
What is missing?
What I am tring to do is to rewrite the following: www.example.com/name/billy.html to: www.example.com/billy
You seem to have the process the wrong way round and possibly mixing up "rewrites" and "redirects"?
You should be internally rewriting from the visible "friendly" URL to the underlying file-path that actually handles the request. You are trying to do the opposite here. How is your system expected to handle a request for /billy? (It doesn't, and generates a 404.)
You may be thinking you can change the URL using .htaccess (mod_rewrite) alone? But no, that is not how this works.
RewriteRule ^name\/([a-z]+).html$ /$1 [L,NC,R]
You mention "rewrite", but this directive is in fact a "redirect" (as indicated by the R flag). Specifically, a 302 (temporary) redirect in this instance.
(You might actually want to implement a redirect like this, if you are changing an existing URL structure, but more on that later*1)
A URL "rewrite" is entirely internal to the server. The user only sees the public URL, they do not see the URL that it might be rewritten to. You (the user) can't "see" a rewrite.
A "redirect" on the other hand, usually refers to an external redirect, ie. a 3xx response sent back to the client with an instruction to make a new request to a different URL. The URL being redirected to is visible to the user. This is used when content has moved to a different URL.
So, following your example, you should be requesting/linking to (in your HTML source) the short/friendly URL /billy and internally rewriting the request to /name/billy.html that actually handles the request.
For example:
RewriteEngine On
# Rewrite from "billy" to "name/billy.html"
RewriteRule ^[a-z]+$ name/$0.html [NC,L]
The $0 backreference contains the entire URL-path that is matched by the RewriteRule pattern.
Only use the NC flag if you do need to match uppercase letters as well. But a request for /Billy won't serve /name/billy.html on a case-sensitive OS.
And that's really it, with regards to the URL-rewritting, you can stop reading here.
*1 Redirect from old to new
Regarding the external "redirect" mentioned above. You might choose to implement a redirect (in the opposite direction) if you are changing an existing URL structure and the old URLs have been indexed by search engines and/or linked (or bookmarked) to by external third parties - in order to preserve SEO and keep users happy.
For example, say your original URLs were of the form /name/billy.html and you later decided to change your URLs to /billy instead. You first change the URLs in the HTML source and implement the "rewrite" as mentioned above so the new URLs now work. You then might implement an external redirect from the old /name/billy.html URL to the new /billy URL.
For this, you would use a directive like you had initially, except you have to be careful of redirect-loops because you are already rewriting the request in the opposite directive. You only want to redirect "direct/initial" requests and not rewritten requests by the earlier rewrite (that is actually later in the file). An easy way to check for "direct" requests is to check against the REDIRECT_STATUS environment variable, which is empty on the initial request and set to 200 (as in 200 OK status) when the request is rewritten.
For example, the following "redirect" would go before the above "rewrite", immediately after the RewriteEngine directive:
# Redirect from "name/billy.html" to "/billy"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^name/([a-z]+)\.html$ /$1 [R=301,NC,L]
This should ultimately be a 301 (permanent) redirect since the URL has presumably changed permanently. However, always test with 302 (temporary) redirects to avoid potential caching issues.
Further reading:
Reference: mod_rewrite, URL rewriting and "pretty links" explained
The scenario: I've moved a WordPress website to a new domain and want to 301 redirect all the pages from the old domain to the new domain. Both sites are on the same hosting account running Apache. The old site is at the root level (public_html), and the new site is in a subfolder (below/inside the root).
I've managed to make this work, but I'd like to learn and understand why it works. So below is a quick overview of my 'journey' and solution, together with three specific questions.
First I tried to do the redirects like this (code added to the root .htaccess file):
# 301 Page Redirects - not working - causes redirect loop
redirect 301 / https://new-domain.com/
redirect 301 /services/ https://new-domain.com/services/
redirect 301 /recipes/ https://new-domain.com/recipes/
But this causes a redirect loop. I'm guessing because the .htaccess file with these rules is at the root level and therefore also affects the subfolders.
Question 1: Is my assumption above about the reason for the redirect loop correct?
Then I tried to be more specific and put this code in the root .htaccess file instead:
# 301 Page Redirects - not working - does nothing at all - not sure why
redirect 301 https://old-domain.com/ https://new-domain.com/
redirect 301 https://old-domain.com/services/ https://new-domain.com/services/
redirect 301 https://old-domain.com/recipes/ https://new-domain.com/recipes/
I was hoping the above code would do the trick, because it's more specific about the old domain. My thinking was that it specifies the old domain exactly and so would circumvent the redirect loop. But instead this code seems to have no effect at all. The redirect loop was gone, but now no redirects were happening anymore at all.
Question 2: Why would the above code not produce any redirects at all?
Then I found this answer and applied the code from that, which works perfectly and creates all the redirects. Plus it's much more elegant than my previous attempts above. This is the code:
# 301 Redirects from old-domain.com to new-domain.com - THIS CODE WORKS - Yay!
RewriteEngine On
RewriteCond %{HTTP_HOST} ^old-domain.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.old-domain.com$
RewriteRule (.*)$ https://new-domain.com/$1 [R=301,L]
Question 3: Why does this code not cause any redirect loops when I place it in the root .htaccess?
I realise I'm copy/pasting code without fully understanding why it works. So I'd love an explanation in simple terms about these behaviours. Thank you.
Answer 1:
From the info that you have provided, I would say no. You did not specify if the new-domain.com website is configured (in apache configuration) with its document root being public_root or public_root/subfolder (judging by the described behaviour I would say it is the former). In that case, when you request https://old-domain.com/anything, the server will (because of the unconditional redirect in your first rule) respond with redirect to https://new-domain.com/anything. Client browser will then request that URL and it will hit the same Apache and same .htaccess, which will again result in the same redirect, causing the loop.
Answer 2:
Redirect syntax:
Redirect [status] [URL-path] URL
The old URL-path is a case-sensitive (%-decoded) path beginning with a
slash.
In your rule, you are specifying [URL-path] as https://old-domain.com/, which is wrong: it can be /, /services/, or /recipes, but not https://old-domain.com/ or https://old-domain.com/services/. The request [URL-path] does not match [URL-path] specified in your rule, so redirect never happens.
Answer 3:
This basically does the same thing as your first rule in Answer 1., with one important difference: the server will respond with redirect only if the hostname in request (or to be more precise, the content of the Host: header in request) is equal to old-domain.com or www.old-domain.com, which will prevent the loop since the second request from the client will use new-domain.com hostname.
Also, from the above, seems like your "new" website in subfolder will never be served: either if old-domain.com or new-domain.com is requested, the site from public_html folder will be shown (and only the hostname in clients browser address bar will change).
I have mod_rewrite and mod_alias enabled. I have some csv files saved in /home/ubuntu/csv. Due to reasons, I can't move files to any other folder.
My website url redirects to /var/www/html. So wesbite-url.com would redirect to /var/www/html.
What I want is somehow website-url.com/files/a.csv should redirect to /home/ubuntu/csv/a.csv? Basically I want to access any file, say x, saved in /home/ubuntu/csv via website-url.com/files/x
How do I go about doing this?
I tried the following commands among others:
RedirectMatch ^/files/$ /home/ubuntu/portalCsv/
RedirectMatch ^/files/ /home/ubuntu/portalCsv/
Redirect /files/a /home/ubuntu/portalCsv/
What is the correct command for this?
You need to capture the url part after /files/ and append it to the Redirect destination
RedirectMatch ^/files/(.+)$ /home/ubuntu/portalCsv/$1
This will redirect your browser from /files/foobar to /home/ubuntu/portalCsv/foobar .
if you want to redirect using mod-rewrite,you can use the following :
RewriteEngine on
RewriteRule ^/?files/(.+)$ /home/ubuntu/portalCsv/$1 [L,R]
I have a standard .htaccess RewriteRule that silently rewrites any request for webroot into a subfolder which contains a MantisBT installation. So the user types in "example.com" and my server secretly serves them files from "example.com/path/to/mantisbt".
The problem now is that MantisBT's index page immediately does some authentication based logic routing and sends a 302 redirect to the FULL "example.com/path/to/mantis/login", which subverts my rewriting. I'm trying to have everyone access my MantisBT installation as if it resided in the webroot.
Now, I'm aware that after MantisBT's 302 redirect to the full path, I could redirect them AGAIN back to webroot. But redirecting people twice every time MantisBT goes through some routing logic seems like a dirty hack. I also know that I could hack up the MantisBT code, but I hate re-hacking code every time a new version comes out.
So, is there a way to trick MantisBT (or any other app for that matter) into thinking it resides in root, and therefore crafts it's redirect paths based on a webroot-relative url? For example: "example.com/login" instead of "example.com/path/to/mantis/login".
I'd really prefer to resolve this using an Apache .htaccess method, or httpd.conf change. Perhaps DocumentRoot or RewriteBase?
Try adding this rule above the internal rewrite rule that you had before
RewriteCond %{THE_REQUEST} \ /+path/to/mantisbt/([^\?\ ]*)
RewriteRule ^ /%1 [L,R]
this redirects the browser when the browser directly requests anything in /path/to/mantisbt/. Then the rule that you already have to internally rewrite into the mantisbt directory would take effect.
I have a site that's coded mainly in PHP, but I'm trying to rewrite my dynamic php URL's into static HTML URL's.
But I want the address bar to still remain as the static HTML link.
I'm trying to accomplish this through .htaccess (I have no access to httpd.conf as I'm hosted on a shared account). Here is what's written in my .httaccess file:
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteRule ^inventory-search-([^.]+)-by-([^.]+).html$ http://www.pianostudiosandshowcase.com/inventory.php?search=$1&by=$2 [R]
But I can't get the address bar to remain as the static HTML link.
Here is a link to show you what I mean:
http://www.pianostudiosandshowcase.com/inventory.php?search=manufacturer&by=1
What am I missing?
You need to remove both the R flag in your rewrite rule as well as the protocol/domain name:
RewriteRule ^inventory-search-([^.]+)-by-([^.]+).html$ /inventory.php?search=$1&by=$2 [L]
Both will cause the server to externally redirect the browser, telling it "what you were looking for is not at that URL, you need to go to this entirely different URL". The forces the browser to display the new location in its address bar.
If you internally rewrite it, the browser has no idea the URI that it sent as a request had been changed, therefore the address bar remains unchanged.