I have a simple custom MVC app using $_GET to parse a url, and i've got it working on my dev server as well as a few different webhosts using php 7.1... but I'm trying to use x10hosting's free lamp hosting and the data being passed from $_GET is coming through as 403...
I've proved that it works on other servers as well as my own dev server with this
echo '<pre>', $route->path, $_GET['url'], '</pre>';
when going to the url http://app/admin... this line in my loop gives me what should be expected...
/admin
adminadmin
but on x10's server i get this
/403.shtml
admin403.shtml
I have tried encoding to base64 with urlencode($_GET) as well as disabling mod_sec in the .htaccess with
<IfModule mod_security.c>
SecFilterEngine Off
SecFilterScanPOST Off
</IfModule>
neither solution worked... I'm almost certain it's a server config issue but access is pretty much limited to .htaccess and php.ini .... I haven't touched php or apache in a while and am a little lost... any help would be greatly appreciated
This does sound like a mod_security type issue. And, as you have found, you are unable to disable mod_security on the free hosting platform.
I have encountered mod_sec rules on a number of shared hosts that simply block the request based on certain parameter names (supposedly blocking common XSS attempts). url is a common one. site is another. Simply changing the parameter name might be all that's required.
"Free" hosting accounts are always going to have some restrictions. If this is the only thing that holds you back then you are lucky.
Related
I'm in the process of working on an error system for my site (i.e., if MySQL encounters an error, it sends them to an error page). I'm wondering, is it possible to use a "/" instead of "?err=" for a URL?
What I'd like to do is have people sent to the url "/error/404/" but display on page the content at url "/error?err=404". Is there a way to do this with HTAccess, or something of the sort?
My current way is with lots of files and iframes, and it gets really annoying when you have to update one tiny little thing.
Thanks!
What you are looking for is url rewriting. You can set it up using an .htaccess file, given that your installation of apache has mod_rewrite enabled (if not, check this question).
Here is a nice tutorial on how to do it.
Have a try with this:
RewriteEngine on
RewriteRule ^error/(\d+)$ error?err=$1 [L,QSA]
This should not end in a redirection loop, since this requires a trailing number in the URI.
Note that I removed your leading slashes from both the pattern and the result. .htaccess style files work on relative paths.
In general you should always prefer to place such rules inside your http servers host configuration instead of using .htaccess style files. Those files are notoriously error prone, hard to debug and the really slow the server down. They are only available as a last option for users who do not have access to the host configuration, for example when using a cheap hosting provider.
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 have a form with many inputs. Some named "date", "type" etc.
The form action points to http://www.xxx.com/admin/links/create, via POST.
When I try to submit it (having required fields populated correctly), I get a 403 response.
In the following cases, I get either 302 or 200 response codes (depending on log-in cookie):
plain http://www.xxx.com/admin/links/create URL in address bar (I know that's GET);
using websniffer (GET & POST)
curl/wget from local
I checked the permissions, the .htaccess (I only have FTP access to web-root) and various other places and everything looks fine.
I hope it's not naming collision of the inputs (actually, I do hope so, because that'll be easy to fix).
All the above happen in production, which is Linux (Apache/2.0.51 on Fedora). Everything works fine on local, which is Windows. Don't tell me it's permissions...
Does somebody know what could be the cause for this - in my own perception - strange behavior?
Culprit: Apache's mod_security.
I didn't have that module installed in my Windows machine (that's why it worked locally), but the server had it installed.
Here's what I did:
I checked the access logs. Found this:
[...] mod_security: Access denied with code 403. Pattern match "!(^application/x-www-form-urlencoded$|^multipart/form-data;)" at HEADER("Content-Type") [...] [uri "/admin/links/create"] [...]
As I don't know how to handle mod_security (yet!), I removed it altogether, and it worked. In your .htaccess:
<IfModule mod_security.c>
SecFilterInheritance Off
</IfModule>
Of course, you can pin-point your Apache targets only to apply that rule to certain files/folders using directives.
Some links that might help:
http://community.mybb.com/showthread.php?tid=7592
http://wordpress.org/support/topic/upgrade-to-22-dashboard-not-working
http://energy-4-3.com/uncategorized/mod_security-access-denied-with-code-403-pattern-match-http/
http://www.modsecurity.org/ (homepage)
I am having a problem like this:
403 Forbidden on PHP page called with url encoded in a $_GET parameter
I am getting "403 forbidden" error
When i pass a url as a GET variable like this
http://script/test.php?url=https://stackoverflow.com/questions/ask
But this is ok.
http://script/test.php?url=stackoverflow.com/questions/ask
And even if i urlencode the url it still gives me a 403.
Apache mod_fcgid/2.3.6 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 Server at ----- Port 80
And I don't think this server has mod_security enabled, Because when I add SecFilterEngine Off in htaccess I get "500 Internal Server Error".
Code snippet:
$URL = mysql_real_escape_string($_GET['url']);
mysql_query("INSERT INTO `url` ...");
So the question is, can I fix this without editing httpd.conf, because I don't have root privilege.
Thanks
Do you have access to the apache error log itself? If this is a cPanel system and you have shell access, try viewing the log /usr/local/apache/logs/error_log - mod_security errors will appear there. Otherwise, you can look inside your control panel to see if it picks up any error messages.
Even if mod_security is installed, you can still get a 500 error after putting SecFilterEngine in .htaccess if the keyword isn't allowed.
I recommend contacting your web host to determine whether mod_security is the cause. If it is, you can ask them to create an exception. (I work for a web hosting company, and we're almost always happy to make mod_security exceptions for reasonable applications)
If it's caused by mod_security and your web host won't create an exception, you either need to change hosting companies or find a different way to pass the url (base64 encoding might work for you)
For me the solution to this issue was by getting my host (hostgator) to create an exception for mod_security on my site. mod_security's used for blacklisting certain types of operations, and it seems $_GET requests containing urls (http://www.etc) was one, for whatever reason. As stated by lunixbochs most hosts will be happy to sort it out for you.
I have made some changes to a clients website.
The client was continually being attacked using SQL injection, and at the moment the URL contains variables that the website needs (i.e. index.php?filenmae=home.php).
So after securing the site as best I could using mysql_real_escape_strings and stripslashes, I then came to do URL rewriting in Apache.
At the moment, the server the website is currently on doesn't support mod_rewrite (i've checked using phpinfo) and it's not a server belonging to us. Is there anything I can do in my .htaccess file that would enable mod_rewrite for this website?
If mod_rewrite is installed, you can configure it in your local .htaccess file.
Create a file called .htaccess in your site's root folder.
First line should be RewriteEngine On.
Second line should be RewriteBase /.
After that, put in your rewrite rules are required.
If it isn't installed, you're out of luck - no web host will install extra software on a shared hosting box just for one client.
Mick, the best solution for you is to change your code. I'm guessing that in your code you then include the filename specified, e.g.
include $_GET['filename'];
In short, there is no way using mod_rewrite that you can make this secure.
However, you can make it more secure very easily by checking that the filename is valid, e.g.
$valid_filenames = array('home.php', 'foo.php', 'bar.php', /* etc... */);
if (!in_array($_GET['filename'], $valid_filenames)) {
echo "Invalid request.";
exit;
}
include $_GET['filename'];
Just make sure that you validate the requested filename before including it and you'll be much better off.
No, you cannot dynamically load mod_rewrite. Most hosting providers have mod_rewrite enabled on Apache servers. If they do not, you could ask them for enabling it. Otherwise, if you really need mod_rewrite, consider switching hosting providers.
As an alternative, you can rewrite URL's in PHP.
$_SERVER['QUERY_STRING'] can be used for getting the part after the question mark (http://example.com/file.php?this_part).
Split it by your preferred parameter separator (e.g. /, ;) using explode('/', $_SERVER['QUERY_STRING'])
Loop through the values, and split those using a preferred value separator (e.g. '=', ':')
Overwrite $_GET with an empty array, and put the newly generated values in it.
Note: filter_input and related functions do not operate on $_GET. Thus, this method will not work for filter_input.
For Shared Hosting Server , It Really Work.
Create a file called .htaccess in your site's root folder.
First line should be RewriteEngine On.
Second line should be RewriteBase /.
After that, put in your rewrite rules are required.