Apache2 - Rewrite Response header Key - apache

How can I rewrite response headers within the apache2 conf? Is this even possible?
We are using apache2 for legacy services which connects to a service behind an envoy proxy.
Envoy always set the response and request header to lower-case. Their solution with
preserve case format doesn't work, because they don't respect the source header.
I expect a responseheader like
"DockingStation_One: 44"
envoy does
"dockingstation_one: 44"
with their preserve case format i get
"Dockingstation_one: 44"
My idea was to rewrite the header either with mod_rewrite or mod_headers in apache2 before it send the response to the client. Sadly nothing works as expected.
My latest setting:
<Location /my/service/v2>
RewriteEngine on
# 1. Save the current value in env var (Case of header name does not matter)
SetEnvIf dockingstation_one(.*) HEADER_VALUE=$1
# 2. Delete the current header (Case of header name does not matter)
Header unset "dockingstation_one" env=HEADER_VALUE
# 3. Recreate header with the required case (Case of header name is preserved)
# env=HEADER_VALUE ensures the header is only set if it was set to begin with
Header set "DockingStation_One" %{DOCKINGSTATION_ONE}e env=HEADER_VALUE
ProxyPass "http://service.go:8090/v2"
ProxyPassReverse "http://service.go:8090/v2"
</Location>

Nevermind. My whole syntax was wrong. My fix looks like this:
Header always set "DockingStation_One" "expr=%{resp:dockingstation_one}"

Related

How can i add current URL to .htaccess CSP header dynamically?

I'm currently working on Shopify app, one of their main requirement is to add an iframe-protection. here is more info
Currently, to resolve this I need the CSP to set should be in this format :
Content-Security-Policy: frame-ancestors https://shopify-dev.myshopify.com https://admin.shopify.com;
The https://shopify-dev.myshopify.com in above code should be the merchant/ requester domain.
What I tried?
I created .htaccess file with following, it's not adding the dynamic url.
<IfModule mod_rewrite.c>
RewriteEngine On
Header set Content-Security-Policy "frame-ancestors '%{HTTP_HOST}' 'https://admin.shopify.com';"
</IfModule>
This is what I'm getting in console:
Apache
On Apache, you would need to do it like this instead:
### Apache ###
Header set Content-Security-Policy "frame-ancestors https://%{HTTP_HOST}e https://admin.shopify.com;"
Note the e after %{HTTP_HOST}e (specific syntax for mod_headers). I've also removed the single quotes (not present in the Spotify example) and included the https:// protocol.
The <IfModule> and RewriteEngine On directives are irrelevant here.
Reference:
https://httpd.apache.org/docs/current/mod/mod_headers.html#header
UPDATE:
LiteSpeed
However, if you are using LiteSpeed (as opposed to Apache) you will instead need to first explicitly assign the Host header to an environment variable and use this in the Header directive instead. (Apache is able to access server variables directly using this syntax, but not LiteSpeed.)
For example:
### LiteSpeed ###
# Assign the "Host" header to an env var "HOSTNAME"
SetEnvIf Host "(.*)" HOSTNAME=$1
# Use "HOSTNAME" (env var) instead in the Header directive
Header set X-Content-Security-Policy "frame-ancestors https://%{HOSTNAME}e https://admin.shopify.com;"
Attempting to use the syntax %{HTTP_HOST} (as you originally had) on Apache would have resulted in a 500 Internal Server Error (with the error "Unrecognized header format %" being reported in the error logs). However, on LiteSpeed this just outputs the literal string {HTTP_HOST} and no error.

How to unset a cookie using .htaccess

I'm using Apache; I put the following code in .htaccess to unset the Cookie header but it doesn't work:
<FilesMatch "\.(js|css|jpg|png|jpeg|gif|xml|json|txt|pdf|mov|avi|otf|woff|ico|swf)$">
RequestHeader unset Cookie
Header unset Cookie
Header unset Set-Cookie
</FilesMatch>
What is your solution?
Preventing the server from issuing a Set-Cookie response header for specific file types won't stop other file types setting a cookie for the domain. So the browser will still send the cookie and the benefits are lost.
Telling the server to remove a Cookie request header before passing it on to the next layer of request processing won't stop the browser from sending it in the first place. So the benefits are lost.
The article you reference in a comment says to serve your static files from a different domain.
Do that. Never write code that sets a cookie for that domain. That's all you need to do.
1 - Create a subdomain, such as static.yourwebsite.com, which is where you will deliver all your static files from
2 - Point your new subdomain to the /wp-content directory of your WordPress installation. For cPanel users, you will need to update the document root field from public_html/static to public_html/wp-content like the screenshot below.
3 - Edit your wp-config.php file to reflect the following
define("WP_CONTENT_URL", "http://static.yourwebsite.com");
define("COOKIE_DOMAIN", "www.yourwebsite.com");
4 - Run the following command in your SQL database, this will ensure all post URLs are directed to the new subdomain:
UPDATE wp_posts SET post_content = REPLACE(post_content,'www.yourwebsite.com/wp-content/','static.yourwebsite.com/')

X-Frame-Options on Apache

I am trying to allow some particular domain to access my site via iframe
Header set X-Frame-Options ALLOW-FROM https://www.example.com
I know this could be done by add the line above to the config of Apache server.
Two questions here.
which config file should be added to? The Apache running on both Unix and windows, if not the same file
while enable the all-from, I still want to be able to run some iframe from my own domain. Can I just add the following line after the allow-from?
Header set X-Frame-Options SAMEORIGIN
Or I should just add my own domain in the all-from, ie
Header set X-Frame-Options ALLOW-FROM https://www.example.com, http://www.my-own-domain.example
You can add to .htaccess, httpd.conf or VirtualHost section
Header set X-Frame-Options SAMEORIGIN this is the best option
Allow from URI is not supported by all browsers. Reference: X-Frame-Options on MDN
See X-Frame-Options header on error response
You can simply add following line to .htaccess
Header always unset X-Frame-Options
What did it for me was the following, I've added the following directive in both the HTTP <VirtualHost *:80> and HTTPS <VirtualHost *:443> virtual host blocks:
ServerName example.com
ServerAlias www.example.com
Header always unset X-Frame-Options
Header set X-Frame-Options "SAMEORIGIN"
The reasoning behind this? Well by default if set, the server does not reset the X-Frame-Options header so we need to first always remove the default value, in my case it was DENY, and then with the next rule we set it to the desired value, in my case SAMEORIGIN. Of course you can use the Header set X-Frame-Options ALLOW-FROM ... rule as well.
This worked for me on all browsers:
Created one page with all my javascript
Created a 2nd page on the same server and embedded the first page using the object tag.
On my third party site I used the Object tag to embed the 2nd page.
Created a .htaccess file on the original server in the public_html folder and put Header unset X-Frame-Options in it.
I found that if the application within the httpd server has a rule like "if the X-Frame-Options header exists and has a value, leave it alone; otherwise add the header X-Frame-Options: SAMEORIGIN" then an httpd.conf mod_headers rule like "Header always unset X-Frame-Options" would not suffice. The SAMEORIGIN value would always reach the client.
To remedy this, I add two, not one, mod_headers rules (in the outermost httpd.conf file):
Header set X-Frame-Options ALLOW-FROM http://example.com early
Header unset X-Frame-Options
The first rule tells any internal request handler that some other agent has taken responsibility for clickjack prevention and it can skip its attempt to save the world. It runs with "early" processing. The second rule strips off the entirely unwanted X-Frame-Options header. It runs with "late" processing.
I also add the appropriate Content-Security-Policy headers so that the world remains protected yet multi-sourced JavaScript from trusted sites still gets to run.
you have to enable mod_headers first in your server
sudo a2enmod headers
sudo service apache2 restart

Rewrite authenticated Apache2.2 user for mod_proxy_ajp

I have a Tomcat connected via mod_proxy_ajp to an Apache2.2 instance. Apache does the authentication via mod_auth_kerb, and Tomcat uses request.getRemoteUser() to get the authenticated user.
This basically works, but I want to rewrite the user. However, none of the headers I set affect what is returned by request.getRemoteUser(), I only see them as additional headers, what do I have to do?
# Rewrite Magic: change REMOTE_USER to something Alfresco expects
RewriteEngine On
RewriteMap domain_map txt:/etc/apache2/rewrite-map.txt
# Grab the REMOTE_USER apache environment variable for HTTP forwarding (requires sub-request!)
RewriteCond %{LA-U:REMOTE_USER} (.*)#(.*)
# change the format and replace the domain, e.g.:
# user#some.domain ==> other.domain_user
RewriteRule . - [E=RU:${domain_map:%2|%2}_%1]
# copy processed user to HTTP headers
RequestHeader set REMOTE_USER %{RU}e
RequestHeader set HTTP_REMOTE_USER %{RU}e
RequestHeader set AJP_REMOTE_USER %{RU}e
RequestHeader set AJP_HTTP_REMOTE_USER %{RU}e
Thanks!
I suspect that the headers are not being set as you expect them to be set, and they are getting to Tomcat empty.
I have experienced some puzzling processing order issues that caused RequestHeader to ignore the environment variables set by a RewriteRule. Take a look at https://stackoverflow.com/a/9303018/239408 in case it helps
It seems the getRemoteUser() value can not be overwritten by Apache header directives, as the AJP protocol handler gets the username from some internal Apache structure. I worked around this by sending the username via http header and modifying the Java code to use that instead of using getRemoteUser().

How to append cookie value to end of response Location header with Apache?

I have a page that issues an HTTP redirect. I need to append the current session id (jsessionid) to the end of the HTTP redirect to pass this id as a GET parameter in the redirect.
Can mod_header's Header append directive pick up a cookie value via SetEnvIf?
Should a rewrite rather be involved? But mod_rewrite just rewrites the request not the response, yes?
How would you solve this from an Apache perspective without touching back-end code?
Update: the Apache-JVM is handled by either mod_jk OR via IBM HTTP Server connection to WebSphere.
As to my knowledge, with Apache HTTPd you do it like this:
SetEnvIf Cookie "mycookie=([^;]+)" MYCOOKIE=$1
SetEnvIf Cookie "mycookie=([^;]+)" HAVE_MYCOOKIE=1
Header add Set-Cookie "mycookie=%{MYCOOKIE}e; expires=0" env=HAVE_MYCOOKIE
You can also add additional cookie attributes like path and domain if you want.