Exposed folders in MVC application - php

Well, as a start please excuse me for my beginner English..
I want to know more about security in PHP MVC applications
I've created my own MVC, I still haven't finished it.
My application directory is exposed by URL access with child elements.
How to make this hidden from visitors?
Following is what I am trying
Apache mod_rewrite ?
I still don't know to make it empty index.html in each folder like the framework Codeigniter ?
What to use for something to indicate ?
and,
... how to make ?
Edit
I know a litte something about rewrite_rules
Below is my .htaccess
Options -MultiViews
RewriteEngine On
RewriteBase /ligia
#RewriteCond %{REQUEST_FILENAME} -f [OR]
#RewriteCond %{REQUEST_FILENAME} -l [OR]
#RewriteCond %{REQUEST_FILENAME} -d
#RewriteRule .+ -
#I know, it is commented
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule "^(.+)$" "index.php?uri=$1" [QSA,L]
But I am afraid if this is the best way to hold my MVC application
security!?
I need help!

First make sure that your .htaccess file is in your document root (the same place as index.php) or it'll only affect the sub-folder it's in (and any sub-folders within that - recursively).
Next make a slight change to your rule so it looks something like:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]
At the moment you're just matching on . which is one instance of any character, you need at least .* to match any number of instances of any character.
If you want the whole shebang installed in a sub-directory, such as /mvc/ or /framework/ the least complicated way to do it is to change the rewrite rule slightly to take that into account.
RewriteRule ^(.*)$ /mvc/index.php?path=$1 [NC,L,QSA]
And ensure that your index.php is in that folder whilst the .htaccess file is in the document root.
NC = No Case (not case sensitive, not really necessary since there are no characters in the pattern)
L = Last (it'll stop rewriting at after this Rewrite so make sure it's the last thing in your list of rewrites)
QSA = Query String Apend, just in case you've got something like ?like=penguins on the end which you want to keep and pass to index.php.

Related

Remove index.php with the GET superglobal from the URL

I have this code in my htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^(.+)$ index.php/?url=$1 [QSA,L]
And in PHP, I grab the current url request and give it it's controller so if there was http://example.com/index.php?url=about -> this will give me the about controller so it displays the about page (MVC)
Now my question is that how can I remove the index.php?url from every page. For example I want to access the about page then I need it to be -> http://example.com/about
You can see in the htaccess that I am replacing the index.php/?url with whatever I type ($1) But it doesn't seem to work because when I request this url: (example) http://example.com/about I get Object not found! Error 404. And when I have http://example.com I get the controller_home page. However, when i type http://example.com/home it also displays error 404.
If I do this: http://example.com/?url=about or http://example.com/index.php?url=about it works find and gives me the about controller so the ?url isn't getting removed by the htaccess I guess...
Might that be an another error in my php code or what?
Kindly help me as I have been looking over this error about 10 hours and I didn't find why it is behaving like that, my friend has almost the same code and it works perfectly for him.
I am kind of new to php so it might be simple bug...
Thanks in advance for everyone that helps!
If you're using an .htaccess file
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^/?(.+)$ index.php?url=$1 [QSA,L]
If you're editing the main apache config file (httpd.conf or apache2.conf). I know the OP is using .htaccess but just in case other people having this issue see this discussion:
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-l
RewriteRule ^/?(.+)$ index.php?url=$1 [QSA,L]
First, presumably you want to test if the requested string does NOT match a directory, NOT match a file, and NOT match a symbolic link - so you need add a "!" before the RewriteCond flags (to negate the condition). Stacked RewriteConds are linked with an implicit AND so checking for directory, file and symbolic link doesn't make sense (a given requested string wouldn't match all of these conditions).
Second, the %{DOCUMENT_ROOT} would be necessary if you're doing this in the main apache config file (ie/httpd.conf or apache2.conf). It's not necessary if you're doing this in an .htaccess file.
Third, when RewriteRule is matching it includes the /. Presumably when you request "website.com/about" you want "about" to be passed to index.php not "/about", so the "/?" will remove the / in first character position from $1. I put the question mark, just because I think it's best practice, since technically you could get an HTTP request that does not begin with a slash (although this would be against standards and every browser includes a slash at the beginning).
Fourth, you shouldn't put a / after the index.php in RewriteRule (so it should be "index.php?url=$1", not "index.php/?url=$1". Query strings are separated from a filename via a "?" not a "/?".
Try this
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^(.*)$ http://%1/$1/ [R=301,L]
RewriteRule ^((.*)+)$ index.php?url=$1 [QSA,L]

.htaccess file - Wildcard Subdomains Redirect

I have got a lot of subdomains configured using wildcard e.g.
subdomain1.domain.com
subdomain2.domain.com
subdomain3.domain.com
(...)
subdomain89.domain.com
etc etc.
They are point to /public_html/. Inside the public_html I have created
/public_html/subdomain1
/public_html/subdomain2
/public_html/subdomain3
(..)
/public_html/subdomain89
sub-folders.
I would like to redirect all request from subdomains (any) to index.php files within the respective sub-folders e.g.:
http://subdomain1.domain.com/
http://subdomain1.domain.com/about_us.php
http://subdomain1.domain.com/contact.php
redirects to /public_html/subdomain1/index.php.
http://subdomain2.domain.com/
http://subdomain2.domain.com/about_us.php
http://subdomain2.domain.com/contact.php
redirects to /public_html/subdomain2/index.php etc etc.
This is my .htaccess:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.domain\.com$ [NC]
RewriteRule !^([a-z0-9-]+)($|/) /%2%{REQUEST_URI}/index.php [PT,L]
When I access subdomain1.domain.com i see the index.php file from /public_html/subdomain1 but when I access subdomain1.domain.com/about_us.php i got 404. Any ideas?
Thanks
I have figured it out. This is the working code:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.domain\.com$ [NC]
RewriteRule !^([a-z0-9-]+)($|/) /%2%{REQUEST_URI}/ [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
:-)
First make sure that your .htaccess file is in your document root (the same place as index.php) or it'll only affect the sub-folder it's in (and any sub-folders within that - recursively).
Next make a slight change to your rule so it looks something like:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]
At the moment you're just matching on . which is one instance of any character, you need at least .* to match any number of instances of any character.
The $_GET['path'] variable will contain the fake directory structure, so /mvc/module/test for instance, which you can then use in index.php to determine the Controller and actions you want to perform.
If you want the whole shebang installed in a sub-directory, such as /mvc/ or /framework/ the least complicated way to do it is to change the rewrite rule slightly to take that into account.
RewriteRule ^(.*)$ /mvc/index.php?path=$1 [NC,L,QSA]
And ensure that your index.php is in that folder whilst the .htaccess file is in the document root.
Alternative to $_GET['path'] (updated Feb '18 and Jan '19)
It's not actually necessary (nor even common now) to set the path as a $_GET variable, many frameworks will rely on $_SERVER['REQUEST_URI'] to retrieve the same information - normally to determine which Controller to use - but the principle is exactly the same.
This does simplify the RewriteRule slightly as you don't need to create the path parameter (which means the OP's original RewriteRule will now work):
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [L,QSA]
However, the rule about installing in a sub-directory still applies, e.g.
RewriteRule ^.*$ /mvc/index.php [L,QSA]

htaccess rewriterule for directory structure

I have the following .htaccess rewrite problem. We have requests entering with multiple subdirectories and an .html file
for example dir1/file.html
or dir1/dir2/file.html
or dir1/dir2/dir3/file.html
or dir1/dir2/dir3/dir4/file.html
what we eventually need is a rewrite rule to
index.html?dir1=$1&dir2=$2&dir3=$3&dir4=$4&file=$5
(where dir2 to dir5 would be empty if path is too short)
Is there any way to do that directly in the .htaccess file, or is it necessary to handle it in php?
I will see if I can test this out, but this should work for the problem as your question states it:
RewriteRule ^/([a-z0-9]+)/?([^/]*)$ /index.php?dir1=$1&$2 [QSA]
RewriteRule ^/([a-z0-9]+)/([a-z0-9]+)/([a-z0-9]+)/([a-z0-9]+)/?$ /index.php?dir1=$1&dir2=$2&dir3=$3&dir4=$4 [L]
RewriteRule ^/([a-z0-9]+)/([a-z0-9]+)/([a-z0-9]+)/?$ /index.php?dir1=$1&dir2=$2&dir3=$3 [L]
RewriteRule ^/([a-z0-9]+)/([a-z0-9]+)/?$ /index.php?dir1=$1&dir2=$2 [L]
RewriteRule ^/([a-z0-9]+)/?$ /index.php?dir1=$1 [L]
I emphasize should because only you can really say what your site structure is & how this cascading ruleset would affect your application.
The regex used is fairly simple:
([a-z0-9]+)
That captures any directory name with letters & characters. If you want to capture—let’s say—underscores and dashes on top of that, it would change to something like:
([a-z0-9_-]+)
The first rewrite rule I have set—^/([a-z0-9]+)/?([^/]*)$—is to capture anything that comes after dir1 just in case there’s data to capture that is not a strict directory structure. You can comment that out if you wish. Just added it since that’s how I like to handle situations that need URL parsing like this.
Also, have you considered adding this to the rewrite rule? Perhaps at the top before the rules cascade in?
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
I would suggest you this
http://domain/dir1-dir2-dir3-dir4-dir5-file.html
rules
RewriteEngine On
RewriteBase /
RewriteRule (.+)-(.+) $1/$2 [N]
you can even make it dynamic by adding these
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1
this is much cleaner.
UPDATE:
well I didn't mean you use the second part but anyways I explain what I meant, it's not wrong that people use QUERY STRING for passing path in URL but it's important how you do that like in this URL
http://domain/index.php?route=dir1/dir2/dir3/dir4/dir5/file.html
as you can see you will grab the path easily with just one GET variable and even handling of this in RewriteRule is much easier like
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?route=$1&%{QUERY_STRING} [L]
which will let you to have a URL like this
http://domain/dir1/dir2/dir3/.../file.html
and with any reason you may change those slash to hyphen or other acceptable chars which become like this
http://domain/dir1-dir2-dir3-dir4-dir5-dir6-dir7-file.html
and as I said it's more easier to pass the current QUERY_STRING which will look like this
http://domain/dir1-dir2-file.html?q=extra_query_value
and result in PHP if you dump $_GET will be:
q => 'extra_query_value'
route => 'dir1/dir2/file.html'
and finally in PHP you may easily explode them to have all folders' name by individual variable.

Strip info from the URL - PHP / htaccess

I am hosting a chatroom, and here is a potential link:
website.com/room.php?roomName=blabla
I would like my users to join this above chatroom by simply going to website.com/blabla
How would you do that?
Generally speaking, just take the whole URL path and rewrite it into the query string. The value will be available to your PHP scripts in $_GET['roomName'].
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /room.php?roomName=$1
The RewriteCond lines are checking to make sure the URL does not point at an actual file/directory (otherwise, you would not be able to access such files/directories).
If this isn't what you want, please explain your goals further.
In your Root folder,create .htaccess file that contains this :
RewriteEngine on
RewriteRule ^/room.php?roomName=(.*)$ /$1 [R=301,L]
Only links that begin with Website/room.php?roomName=xxx will be redirected to Website/xxxx,so files and folders are preserved.

Create dynamic subdirectories using htaccess and php

Every single time a user registers on my site I would like them to have their own subdirectory with their registered "username". Every user subdirectory will have the same "index.php" file which will do something.
For example: "/users/username1/" and "/users/username2/"
If some one wants to access the subdirectory they would simple go to:
"www.example.com/users/username1/" or "www.example.com/users/username2/"
The easy and messy solution would be to simply create a subdirectory for every user and place the same "index.php" file in every directory. But to me this is only going to crowd my server space and make my directories large.
I wanted to know if all this can be done using .htaccess? Can I create one "index.php" and one ".htaccess" file and place them both in my "/users/" directory? What would be the actual code that I would have to place in my .htaccess file??
If you have a better way of doing this please let me know. I am using Apache and PHP as my working environment.
Thank you
Well, for example, you could do it all with one htaccess like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>
What it does:
switches on rewrite engine
checks if a requested file exists
checks if a requested directory exists
if NOT, it redirects request to your main index.php
Basically that means if you enter url such as yourdomain.com/users/ivan/, you request will be redirected to:
index.php?url=/users/ivan
then you $_GET['url'] in your index.php and split it into pieces.
That's just an example, there other mod_rewrite methods to do this.
Make it virtual. There are no subdirectories, you can use mod_rewrite to simulate that.
With mod_rewrite you can make /users/username1 lead to /users.php?user=username1 for instance. Everything is transparent for the client, he wont notice what is really happening.
By using something like this:
RewriteEngine On
RewriteRule ^([\-_0-9A-Za-z]+)$ index.php?a=$1 [L]
You can customize RewriteRule as much as you want.
You can essentially type in any directory you want, and it will be redirected to your index.php page.
If you want to make sure the existing directories are not redirected, do this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([\-_0-9A-Za-z]+)$ index.php?a=$1 [L]
If you want to limit the scope, so only a subdirectory of user/ is redirected (similar to Stack Overflow), simply add in 'user' to the start of the rule:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^user/([\-_0-9A-Za-z]+)$ index.php?a=$1 [L]
And finally, if you want to have an individual file handle all user requests seperate from your actual index.php page:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^user/([\-_0-9A-Za-z]+)$ users.php?a=$1 [L]
This is a very similar setup I use to distribute CSS files.
Note: The Directory will be contained is $_GET['a']

Categories