Block all search queries except on .htaccess - html

i am currently working on a wordpress website in which I've a special case. I want one specific search query to be allowed while rejecting all others.
For example:
www.example.com - PASS
www.example.com/page - PASS
www.example.com
www.example.com/?myQuery - PASS
www.example.com/?anyotherQuery - 404
Right now, I have tried it using the following re-write rule but it is also blocking access to other pages.
RewriteBase "/"
RewriteCond %{QUERY_STRING} ! myQuery
RewriteRule ^.* - [F]`
I'm new in rewrite and htaccess thing so need help in achieving this.

Try the following, at the top of your .htaccess file, before the WordPress front-controller.
RewriteCond %{QUERY_STRING} .
RewriteCond %{QUERY_STRING} !=myQuery
RewriteRule ^ - [F]
The above states... for any URL that contains a query string (first condition) and the query string is not exactly myQuery (second condition) then respond with a 403 Forbidden (Apache response, not WordPress).
The = prefix on the CondPattern makes it a lexicographical string comparison (not a regex) and the ! prefix negates the result.
RewriteBase "/"
RewriteCond %{QUERY_STRING} ! myQuery
RewriteRule ^.* - [F]`
The RewriteBase directive is irrelevant here. The space between ! and myQuery is erroneous. But this would potentially block anything where the query string does not contain myQuery, including when there is no query string at all.

Related

NGINX dynamic location to create dynamic og:image

I developed a site that shows some products from a store. The site URL looks like that:
http://testsite.com
The site has the functionality of sharing the product (it's already working) generating a link that can be shared at facebook or WhatsApp or anywhere. The link of the shared product is:
http://testsite.com/product/1234
Where 1234 is the product ID. All the products have images with the ID name. Ex: 1234.jpg. The link for the image of the product ID 1234 is:
http://testsite.com/static/imgs/1234.jpg
This site is hosted using a simple NGINX server, that just provides the files.
At the head of my index.html file I have a default og:image for sharing:
<meta property="og:image" content="http://testsite.com/static/imgs/main.jpg">
I wanna the NGINX server to replace this default og:image by the shared ID image. I already know how to do that at NGINX. At the NGINX configuration file (/etc/nginx/conf.d/default.conf) I used the sub_filter option. My NGINX configuration file is:
server {
listen 80;
server_name *.testsite.com;
root /var/www/testsite.com/dist;
location / {
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
location ~ /product/(.*) {
index index.html index.htm;
try_files $uri $uri/ /index.html;
sub_filter 'http://testsite.com/static/imgs/main.jpg'
'http://testsite.com/static/imgs/$1.jpg';
sub_filter_once on;
}
}
This configuration is working for the location /, but for the location ~ /product/(.*) it is not working.
When I test the sub_fiter option at the location / using any other image it replaces correctly.
QUESTIONS:
1) How can I get the product ID (1234) from the URL (http://testsite.com/product/1234)? $1 is not working.
2) I think that when entering at the location ~ /product/(.*), it also redirects for the location /. How can I fix this configuration file to works as expected?
I think your alias statement is the problem.
Reading in nginx docs:
location /i/ {
alias /data/w3/images/;
}
on request of “/i/top.gif”, the file /data/w3/images/top.gif will be sent.
It means that in your case on each ~/product/(.*) request /var/www/testsite.com/dist/index.html will be sent without taking product ID into account. You might want to configure alias on / to avoid that. This is also likely to be the reason you get "redirected" to /.
As for $1, it should work as you have it now. When you fix the alias, I think it will work then. If not, you can try the named match: (?<product>[0-9]+) instead of (.*), then you can use the $product variable to reference the id.
There's another small glitch in your code — you're adding extra quote marks on replace. The second argument to sub_filter is in quotes twice.
Working Example
UPDATE: Ok, I got it working on localhost with the following nginx config (testing on "Hello World"):
location ~ /product/(\d+)$ {
set $product $1;
try_files $uri $uri/ /index.html;
}
location / {
if ( $product = '' ) {
set $search 'Non-Existent-String';
}
if ( $product != '' ) {
set $search 'World'; # the string you want to replace
}
index index.html index.htm;
sub_filter '$search' 'Product #$product';
}
The key here is that when you use try_files, it does get to location /. So we need to sub_filter in /. We also don't want to sub_filter regular /index.html requests. Something like if ($product) sub_filter would be nice, but is impossible with nginx. So I just leave sub_filter but only set real search string for product requests.

proftpd mod_exec in conjuncion with <IfUser>

Is there a way to enable the module 'mod_exec' only with a certain proftdp user?
I've compiled proftp with --with-modules=mod_exec:mod_ifsession and then configured in this way...
<IfModule mod_exec.c>
<IfUser stefano>
ExecEngine on
ExecLog /opt/proftpd-master/logs/proftpd.semics.mod_exec.log
ExecOptions logStderr logStdout
ExecBeforeCommand STOR,RETR /path/to/handler.sh EVENT=BeforeCommand FILE='%f'
ExecOnCommand STOR,RETR /path/to/handler.sh EVENT=OnCommand FILE='%f'
</IfUser>
</IfModule>
or this:
<IfUser stefano>
<IfModule mod_exec.c>
ExecEngine on
ExecLog /opt/proftpd-master/logs/proftpd.semics.mod_exec.log
ExecOptions logStderr logStdout
ExecBeforeCommand STOR,RETR /path/to/handler.sh EVENT=BeforeCommand FILE='%f'
ExecOnCommand STOR,RETR /path/to/handler.sh EVENT=OnCommand FILE='%f'
</IfModule>
</IfUser>
without success. Seems that mod_exec works only if configured outside the conditional statement.
My goal is to enable mod_exec only for user 'stefano' and/or to have several mod_exec configuration accordingly with each user configured.
Any suggestion?
mod_exec.c must be enabled by default and then inside it is possible to configure different actions for different users:
<IfModule mod_exec.c>
ExecEngine on
ExecLog /opt/proftpd-master/logs/proftpd_mod_exec.log
ExecOptions logStderr logStdout
<IfUser stefano>
ExecBeforeCommand STOR,RETR /path/to/script.sh EVENT=BeforeCommand FILE='%f'
ExecOnCommand STOR,RETR /path/to/script.sh EVENT=OnCommand FILE='%f'
</IfUser>
</IfModule>
Thanks to TJ Saunders. I hope this helps.

nginx directories without slash

I have this configuration of nginx + phpfpm + phpmyadmin:
root /var/www/utils;
location ~ ^/phpmyadmin/.*\.(jpg|jpeg|gif|png|css|js|ico)$ {
root /var/www/utils;
}
location = /phpmyadmin {
index index.php;
}
location ~ ^/phpmyadmin.*(\.php|)$ {
index index.php;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
All is good, but if I remove "location = /phpmyadmin", I get 403 error on _http://server/phpmyadmin.
How can I access to the ALL subdirectories such as _http://server/phpmyadmin/setup ?
I get "Access to the script '/var/www/utils/phpmyadmin/setup' has been denied - on every directory without slash at the end, if I haven't written a special config for an each one.
As stated in nginx documentation:
$fastcgi_script_name variable takes value of incoming request URI, and in case URI is finished by a slash, then $fastcgi_script_name is appended with what is defined with fastcgi_index directive.
So if your request is "/phpmyadmin/setup/" and fastcgi_index is set to "index.php", then $fastcgi_script_name variable will be "/phpmyadmin/setup/index.php". Therefore $document_root plus $fastcgi_script_name will be "/var/www/utils/phpmyadmin/setup/index.php", which should work fine.
But if you make request like "/phpmyadmin/setup" (without slash at the end), then $fastcgi_script_name will not be appended by fastcgi_index, i.e. it would be just "/phpmyadmin/setup". And $document_root plus $fastcgi_script_name will be "/var/www/utils/phpmyadmin/setup", which won't work since there is not such file.
You should either use URIs with slashes, or define a rewrite rule (in a "server" block of configuration), which will be adding slash to the URIs that do not end with some extension (so that URIs like "/phpmyadmin/myscript.php" won't transformed into "/phpmyadmin/myscript.php/".
It should be like:
rewrite ^([^\.]*[^\/])$ $1/ break;
Did not test that myself, though.

in nginx config, what is the meaning of caret ^ by itself?

A bit down on this nginx config reference page you'll see:
rewrite ^ http://example.com$request_uri? permanent;
What is the meaning of ^ above?
For rewrite, the first argument is the match pattern and only applies to the path portion of the url, not the domain. In regular expressions, ^ matches the beginning of the input. For example, ^/photos/.*$ would match paths beginning in '/photos/'. By itself, ^ is a shortcut for all paths (since they all have a beginning).

Using a hash sign (#) in a .htaccess search

So the jist of this is,
I have a file:
search.php
When I goto:
search.php?search=%23HashTag
The search returns: #HashTag
But when I use my .htaccess method:
/search/%23HashTag
Nothing is returned. And i've tested by putting the number sign later in the search and it returns upto that point.
This is what I have:
RewriteRule ^search/([^\.]+)$ search.php?search=$1 [NE,L]
What am I doing wrong..?
Change your flags to [NE,B,L].
http://httpd.apache.org/docs/current/rewrite/flags.html#flag_b
mod_rewrite unescapes the url before applying transformations. I'm not sure why it loses anything after the hash (maybe it re-interprets it as a url, and discards the fragment?). In any case, [B] re-escapes the url before running it through the rewrite rule.
Does replacing it with \%23 work ok?
(Clarity: Opposed to writing the # in the .htaccess file)