Why a letter "e" after %{VARIABLE}e - .htaccess

I have found a little htaccess to allow CORS:
SetEnvIf Origin ^(https://subdomain.domain.com)$ CORS_ALLOW_ORIGIN=$1
Header append Access-Control-Allow-Origin %{CORS_ALLOW_ORIGIN}e env=CORS_ALLOW_ORIGIN
Header merge Vary "Origin"
But i don't understand why in the second lines there is the letter "e" after %{CORS_ALLOW_ORIGIN}
I have found this htaccess example on a lot of sites, but nobody speak about that. Is it a "concatenation" ?
Thank for help

As well as examples, it's useful to read the official documentation. In this case, http://httpd.apache.org/docs/2.4/mod/mod_headers.html#header explains everything about the Header directive, including that the value can include various special values beginning %, such as
%{VARNAME}e The contents of the environment variable VARNAME.
So the short answer is that "e" is short for "environment variable". For what that means exactly, follow the link and keep reading.

Related

How do I create a rule to block all user agents with ModSecurity V3?

I want to add a custom ModSecurity (V3) rule that can block all user agents, and allow me to whitelist certain User Agents from a file.
If this is possible, if someone could share the rule with me, that would be great. I cannot seem to figure out the rule to do this.
Thanks!
This is a bit dangerous what you want to do, but I try to give you some help.
I think CRS rule 913100 would be a good point to start for you.
It's a bit complex if you new in ModSecurity any SecLang, so in short, this would be a possible solution. Create a rule for your WAF, like this:
SecRule REQUEST_HEADERS:User-Agent "!#pmFromFile allowed-user-agents.data" \
"id:9013100,\
phase:1,\
deny,\
t:none,\
msg:'Found User-Agent associated with security scanner',\
logdata:'Matched Data: illegal UA found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}'"
Please note, that you can choose any id for your rule what you want, but there is a reservation list for id's:
https://coreruleset.org/docs/rules/ruleid/#id-reservations
It's highly recommended you choose a right one to avoid the collision with other rules. 9013100 would be a good choice, and it represents where this rule is derived from.
Then you have to make a file with a list of your allowed user agents. Note, that you have to place that list in same directory as the rule conf file exists. The name of file must be (as you can see above) allowed-user-agents.data. You can put an agent per line. Also you can use comments with # at the beginning of the rule - just see the CRS's data file.
How this rule works?
SecRule is a token which tells the engine that this is a rule. REQUEST_HEADERS is a collection (a special variable), what the engine expands from the HTTP request. The : after the name indicates that you want to investigate only the mentioned header, namely User-Agent.
The next block is the operator. As documentation says #pmFromFile "Performs a case-insensitive match of the provided phrases against the desired input value.". This is what you need exactly. There is a ! sign before the operator. This inverts the operator's behavior, so it will be TRUE if the User-Agent isn't there in the file.
The next section is the action's list. id is mandatory, this identifies the rule. phase:1 is optional but very recommended to place one. For more information, see the reference. deny is a disruptive action, it terminates the request immediately. msg will append a message to the log in every cases. logdata will show a detailed info about the rule result.
Why is this a little dangerous
As you can see in the documentation of #pmFromFile operator, it uses patterns. This means you do not have to place the exact User-Agent names, it's enough to put a pattern, like "curl", or "mozilla" - but be careful, a wrong pattern can lead to false positive results, which means - in this case - an attacker can bypass your rule: it's enough to place the pattern to trick it.
Consider you put the pattern my-user-agent into the data file. Now if someone just uses this pattern as User-Agent, the rule won't match.
It is generally true that handling whitelists in this way (in some special contexts, like this) is dangerous, because it's easy to bypass them.

Code igniter - mod rewrite issue

I have following kind of URL,
http://example.com/controller/method/VBGFrt543ERik4523/text1-text2
I want this to be shown in browser as,
http://example.com/text1-text2
I searched a lot but couldnt find any specific solution on this requirement.
Can anyone help me out please?
Use URL routes with a bit of regex. This will reroute any url with letter and numbers followed by a hyphen and then letters and numbers to controller1/method/abc123/$1:
$route['([a-zA-Z0-9]+)-([a-zA-Z0-9]+)'] = "controller1/method/abc123/$1";
(nb. you only can have one controller in your URL - it goes controller/method/variable1/variable2...)
You set routes in application/config/routes.php
http://ellislab.com/codeigniter/user-guide/general/routing.html
Good luck!

Mod Rewrite Rule for Dynamic URL - Is this possible?

I've given myself a headache trying to figure out if this can be done. I have a forum that was recently migrated, leaving thousands of broken dynamic links.
A typical URL looks like this:
http://domain.com/Forum_Name/b10001/25/
('b10001' refers to the forum ID number and the last number refers to the page number.)
The new URL is formatted like this:
http://domain.com/forums/Forum_Name.10001/
(No page number. Also, notice the 'b' is no longer in front of the ID number.)
Is there a rewrite rule that can achieve this?
I'm not a rewriter, but following what I've read here, something like this should work:
RewriteRule ^([A-Za-z0-9-]+)/b([0-9])+(/[0-9]+)?/?.*$ forums/$1.$2/ [NC,L]
^([A-Za-z0-9-]+) says "begins with an alphanumeric string", then there's the /b constant, followed by [0-9]+ (one or more digits), and then an optional / with one or more digit (the page number, (/[0-9]+)?), and lastly, it ends with an optional slash (/?$).
If the URL matches that pattern, then it's rewritten to forums/$1\.$2/. \. escapes the dot (it's a wildcard), $1 is the first match of the pattern (that first alphanumeric string which is the forum name), and $2 is the second match, namely, the number after the b.
Finally, NC means pattern is case-insensitive, and L is "last" - so you don't process any other rule. I think that is most up to you, just read the linked article and pick the flags you need :)
Edit: corrected pattern checking with http://htaccess.madewithlove.be/
I think what you're looking for is
RewriteRule ^([a-zA-Z0-9_]+)/b([0-9]+)/.*$ forums/$1/$2/
Make sure the contents of the [] parts match the format you're using for forum names and ids.
For parameters, you probably want R=301 to force a permanent redirect.

Is it possible with canonical URL for this pattern in htaccess: /a/*/id/uniqueid?

A big problem is that I am not a programmer….! So I need to solve this with means within my own competence… I would be very happy for help!
I have an issue with a lot of duplicated URLs in the Google index and there are strong signs that it is causing SEO problems.
I don’t have duplicate links on the site itself, but as it once was set-up, for certain pages the system allows all sorts of variations in the URL. As long as is it has a specific article-id, the same content will be presented under an infinite number of URLs.
I guess the duplicates in Google's index has been growing over long time and is due to links gone wrong from other sites that links to mine. The problem is that the system have accepted the variations.
Here are examples of variations that exists in the Google index:
site.com/a/Cow_Cat/id/5272
site.com/a/cow_cat/id/5272
site.com/a/cow…cat/id/5272
site.com/a/cowcat/id/5272
site.com/a/bird/id/5272
The first URL with mixed case is the one used site-wide and for now I have to live with it, it would take too long time to make a change to all lower case. I cannot make a manual effort via htaccess as it is a total of 300.000 articles. I believe there are 10 ‘s of thousands that have one or more duplicates.
My question is this:
Is it possible to create rules for canonical URLs in htaccess in order to make the above URLs to be handled as one as well as for the rest of the 300.000?
I e, is there a way to say that all URLs having
/a/*/id/uniqueid
should be seen as one = based only on the unique ID and not give any regard to the text expressed with the “*”?
My hope is that it would be possible to say that a certain pattern like above should only be differentiated by the last unique segment.
If it is not possible in htaccess, how would it be done with link rel="canonical" on each page, can the code include wildcards?
I should add that the majority of the duplicates are caused by incoming links being lower case where the site itself is using a mix. Would it be OK to assign a canonical URL only with lower case although the site itself is basically always using a mix of lower/upper case?
If this is possible, I would be very happy to be helped with how to do it!!!!
Jonas
Hi Michael! I am not an expert but this is how I think it could be done:
1) My problem is that the URLs have mixed cases and I cannot change that now.
2) If it is OK for the searchengines, it would be fine for me to make the canonical URL identical to the actual URLs with the difference that it was all lower case, that would solve approx 90% of the duplicates. I e this would be the used URL: site.com/a/Cow_Cat/id/5272 and this would be the canonical: site.com/a/cow_cat/id/5272. As I understand, that would be good SEO...or...?
My idea was NOT to change the address browser address bar (i e using 301 redirect) but rather just telling the search engines which URLs that are duplicates, as I understand, that can be done by defining a canonical URL either in htaccess (as a pattern - I hope) or as a tag on each page.
3) IF, it would be possible to find a wildcard solution...I am not sure if this is possible at all, but that would mean it was possible to NOT assign a specific canonical URL but rather a "group pattern", i e "Please search engine, see all URLs with this patter - having the unique identifier in the end - as if they are one and the same URL, you SE, decide which one you prefer": /a/*/id/uniqueid
Would that work? It will only work in htaccess if canonical URLs can be defined as a group where the group is defined as a pattern with a defined part as the unique id.
Is it possible when adding a tag for each page to say that "all URLs containing this unique id should be treated the same"? If that would work it would look something similar to this
link rel="canonical" /a/*/id/5272
I dont know if this syntax with wildcard exist but it would be nice : )
My advice would be to use 301 redirects, with URL rewriting. Ask your webmaster to place this in your apache config or virtual host config:
RewriteMap lc int:tolower
Then inside your .htaccess file you can use the map ${lc:$1} to convert matches to lower case. Here, the $1 part is a match (backreference from brackets in a regex in the RewriteRule) and the ${lc: } part is just how you apply the lc (lowercase) function set up earlier. Here is an example of what you might want in your .htaccess file:
RewriteCond %{REQUEST_URI} [A-Z] #this matches a url with any uppercase characters
RewriteRule (.*) /${lc:$1} [L,R=301] #this makes it lowercase
As for matching the IDs, presuming your examples mean "always end with the ID" you could use a regex like:
^(.+/)(\d+))$
The first match (brackets) gets everything up to and including the forward slash before the ID, and the second part grabs the ID. We can then use it to point to a single, specific URL (like canonical, but with a 301).
If you do just want to use canonical tags, then you'll have to say what you're using code wise, but an example I use (so as not add tags to hundreds of individual pages, for instance) in PHP would be:
if ($_SERVER["REDIRECT_URL"] != "") {
$canonicalUrl = $_SERVER["SERVER_NAME"] . $_SERVER["REDIRECT_URL"];
} else if ($_SERVER["REQUEST_URI"] != "") {
$canonicalUrl = $_SERVER["SERVER_NAME"] . preg_replace('/^([^?]+)\?.*$/', "$1", $_SERVER['REQUEST_URI']);
}
Here, the redirect URL is used if it's available, and if not the request uri is used. This code strips off the query string (this bold bit in http://www.mysite.com/a/blah/12345/?something=true). Of course you can add to this code to specify a custom path, not just taking off the query string, by playing with the regex.

How to specify named subfolders in htaccess?

I have a folder structure like this /img/products/{product name}/ and then the sub folders hi, low, and thumb.
I want to use htacess to force-download any files in a 'hi' or 'low' subfolder (but not 'thumb').
I was hoping something like this would work:
<FilesMatch "\(.*)(\/hi|\/low)(.*)">
ForceType applicaton/octet-stream
</FilesMatch>
Now I'm not great with regex, but that seems to work in regex testers against paths like
/img/products/active/low/something.jpg
However it's not working on the site.
Any suggestions?
Thanks
Pete
This probably should have been a ServerFault question based on what I think that you're trying to do, but since you actually can't do what you're trying to do (the way I think you're trying to do it), I'll provide two alternatives; one that likely won't work, and another that involves a PHP script (which should hopefully be alright for you, since your question history shows you asking something about PHP before).
The Problem:
First, what I think you're trying to do, so you can correct me if I'm wrong:
# Apply ForceType to anything that's in a path that matches this
<FilesMatch "img/products/[^/]+/(hi|low)/[^/]+$">
ForceType applicaton/octet-stream
</FilesMatch>
However, this won't work, because FilesMatch only examines the filename, under the assumption that you could either appropriately place the .htaccess file, or combine the directive with a Directory statement in the server or virtual server configuration.
In your case though, this isn't possible (Well, I assume anyway, maybe you do have access to the necessary configurations, but since your question is tagged .htaccess I'm guessing probably not), given that copying a .htaccess file to every folder isn't realistic.
The Solutions:
As it turns out, mod_rewrite, along with performing all sorts of voodoo in the way of filename resolution, also gives you extensions of other Apache functionality that you would not necessarily have been able to use otherwise. Case in point, we can set the MIME type using the T flag, making the easiest solution this:
RewriteEngine On
# Force the MIME-type, but don't actually perform a rewrite
RewriteRule ^img/products/[^/]+/(hi|low)/[^/]+$ - [T=application/octet-stream]
This actually works pretty well, but chances are good that your Apache installation thinks that it knows better than you, and includes a mimes.types file in the main configuration that maps the jpg extension to image/jpeg. This value takes precedence over the RewriteRule, making it ineffective in that case.
The other solution is to create a small script that acts as the go-between, passing the appropriate headers and image data from the server to the client. You would then use mod_rewrite to pass the request on to that script:
RewriteEngine On
# For an added bit of sanity, make the test pattern even more restrictive
RewriteRule ^img/products/[A-Za-z._-]+/(hi|low)/[A-Za-z._-]\.[A-Za-z]+$ imageDownloader.php
As for the script itself, to keep this answer from getting ridiculously long, I suggest taking a look at this answer or one of the other questions on this topic, keeping in mind that it's imperative that you screen the filenames that can be downloaded for reasons of security. Note that you would be able to get the original request path from $_SERVER['REQUEST_URI'], and could use that to locate the proper image.

Resources