DKIM passes even though domains don't match - postfix-mta

I'm trying to figure out how DKIM verification works.
My understanding so far has been that the domain inside DKIM-Signature header must match the domain inside From header in case for DKIM check to pass.
I configured the opendkim SigningTable all e-mails from lskdfjlsd.com domain with domain key from different domain:
*#lskdfjlsd.com default._domainkey.unrelateddomain.com
My KeyTable looks like this:
default._domainkey.unrelateddomain.com unrelateddomain.com:default:/etc/opendkim/keys/unrelateddomain.com/default
I send out e-mails with this:
echo "Hello world" | mail -s "Hello" -r noreply#lskdfjlsd.com my-personal-mail#gmail.com
When I check the e-mail inside my-personal-mail#gmail.com I can see the DKIM check passed for the domain unrelateddomain.com - the content of the DKIM header and From field is:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unrelateddomain.com; s=default
From: noreply#lskdfjlsd.com
And this is where my confusion stems from. The DKIM check says PASS for domain unrelateddomain.com but the From header clearly says it's originated from different domain. Based on this the https://mxtoolbox.com/dmarc/dkim/dkim-alignment I'd expect the DKIM check will fail.
I've tried to playing with domains and DKIM check always says PASS no mather if domains match or not.

The domain mentioned in the d= tag of the signature header tells the receiving server where to look for the public key to use, in the selector record. The s= tag tells it the name of the selector. The DKIM RFC does not require the FROM domain to be the same domain as the DKIM signature domain.
In fact, a message can be signed by multiple signatures from multiple domains, and often is. For example, a service like MailGun might add a DKIM signature for their domain, while enabling you to set up an additional DKIM signture for the domain you're sending From.
This is exactly why DMARC has been introduced, to require alignment between domains used in authentication technologies (SPF and DKIM) and the domain used in the FROM header. Because that is the main address shown in the email client facing the user.

Related

dmarc getting fail in Authentication result

I am having Postfix server configured for domain. From last few days my mails are marking as spam in gmail. I have already configured DKIM,SPF and DMARC for this domain. I have checked mail source and getting
"Authentication-Results: mydomain; dmarc=fail header.from=mydomain"
I have checked all the support docs but didn`t find anything.
Could you provide full sample headers or run a classification test with a third party?
Often, the TXT records aren't correctly created with the proper name style or have a syntax error causing the mail server parser to fail. Since DMARC fails the issue can be in either SPF or DKIM. In relaxed mode, the [SPF]-authenticated domain and RFC5322.From domain must have the same Organizational Domain. In strict mode, only an exact DNS domain match is considered to produce Identifier Alignment.
Generally speaking, its really hard to help without proper details. Kindly always provide DNS and configuration samples.

OpenDMARC multiple domains

I want to set OpenDMARC to support multiple domains and only show the header for the domain sending the email.
Adding more than one AuthservID doesn't do it. the header shows as
Authentication-Results: domain1.com; dmarc=none header.from=domain2.com
You are misunderstanding the syntax of the Authentication-Results: header.
The first field, in your case domain1.com, is essentially a site ID for the service that performed authentication verification. Different sites do this slightly differently, but it is not intended to correlate to the recipient domain. It is intended to identify who performed authentication validation. Yahoo, for example, puts specific hostnames in that field, such as mta1315.mail.gq1.yahoo.com. Google and Hotmail both just use more generic mx.google.com and hotmail.com identifiers respectively.
Refer to section 2.4 of RFC 7001 "Message Header Field for Indicating Message Authentication Status" (https://www.rfc-editor.org/rfc/rfc7001#page-13) for full details.
Only the SPF and DKIM identifiers - domain2.com in your example above - or each instance of agari.com in my example below:
Authentication-Results: mx.google.com; spf=pass (google.com: domain of chris#agari.com designates 2607:f8b0:400e:c03::22b as permitted sender) smtp.mail=chris#agari.com; dkim=pass header.i=#agari.com; dmarc=pass (p=REJECT dis=NONE) header.from=agari.com
relate to the recipient domain. Note that because our email is hosted with google apps, the identifier is mx.google.com, telling me who validated email authentication.
I would recommend configuring AuthservID to a value that represents either the machine that performed authentication, or perhaps an organizational name or identifier if appropriate for your site.

How to protect a web server FROM a reverse proxy server

I have a website "www.website.com".
Recently I found out that somebody has set up a reverse proxy with an almost identical url "www.website1.com" in front of my website.
I'm concerned of those users who came to my website through that reverse proxy. Their username and passwords might be logged when they login.
Is there a way for me to have my web server refuse reverse proxy?
For example, I've set up a reverse proxy using squid with the url "www.fakestackoverflow.com" in front of "www.stackoverflow.com". So whenever I type "www.fakestackoverflow.com" in my web browser address bar, I'll be redirected to "www.stackoverflow.com" by the reverse proxy. Then I notice the url in my address bar changed to "www.stackoverflow.com" indicating that I'm no longer going through the reverse proxy.
"www.stackoverflow.com" must've detected that I came to the website from another url and then redirected me to the website through the actual url.
How do I do something like that in ASP.NET web application?
Also asked on server fault.
First, use JavaScript to sniff document.location.href and match it against your domain:
var MyHostName = "www.mydomain.com";
if (0 == document.location.href.indexOf("https://"))
{
MyHostName = "https://" + MyHostName + "/";
if (0 != document.location.href.indexOf(MyHostName)) {
var new_location = document.location.href.replace(/https:\/\/[^\/]+\//, MyHostName);
if(new_location != document.location.href)
document.location.replace(new_location);
}
}
else
{
MyHostName = "http://" + MyHostName + "/";
if (0 != document.location.href.indexOf(MyHostName)) {
var new_location = document.location.href.replace(/http:\/\/[^\/]+\//, MyHostName);
if(new_location != document.location.href)
document.location.replace(new_location);
}
}
Second: write a init script to all your ASP pages to check if the remote user IP address matches the address of the reverse proxy. If it matches, redirect to a tinyurl link which redirects back to your real domain. Use tinyurl or other redirection service to counter reverse proxy's url rewriting.
Third: write a scheduled task to do a DNS lookup on the fake domain, and update a configuration file which your init script in step 2 uses. Note: Do not do a DNS lookup in your ASP because DNS lookups can stall for 5 seconds. This opens a door for DOS against your site. Also, don't block solely based on IP address because it's easy to relocate.
Edit: If you're considered of the proxy operator stealing user passwords and usernames, you should log all users who are served to the proxy's IP address, and disable their accounts. Then send email to them explaining that they have been victims of a phishing attack via a misspelled domain name, and request them to change their passwords.
After days of searching and experimenting, I think I've found an explanation to my question. In my question, I used stackoverflow.com as an example but now I'm going to use whatismyipaddress.com as my example since both exhibit the same behaviour in the sense of url rewriting plus whatismyipaddress.com is able to tell my ip address.
First, in order to reproduce the behaviour, I visited whatismyipaddress.com and got my ip address, say 111.111.111.111. Then I visited www.whatismyipaddress.com (note the additional www. as its prefix) and the url in my browser's address bar changed back to whatismyipaddress.com discarding the prefix. After reading comments from Josh Stodola, it strucked me to prove this point.
Next, I set up a reverse proxy with the url www.myreverseproxy.com and ip address 222.222.222.222 and I have it performed the two scenarios below:
I have the reverse proxy points to whatismyipaddress.com (without the prefix **www.). Then typed www.myreverseproxy.com in my browser's address bar. The reverse proxy then relayed me to whatismyipaddress.com and the url in my address bar didn't change (still showing www.myreverseproxy.com). I further confirmed this by checking the ip address on the webpage which showed 222.222.222.222 (which is the ip address of the reverse proxy). This means that I'm still viewing the webpage through the reverse proxy and not directly connected to whatismyipaddress.com.
Then I have the reverse proxy points to www.whatismyipaddress.com (with the prefix wwww. this time). I visited www.myreverseproxy.com and this time the url in my address bar changed from www.myreverseproxy.com to whatismyipaddress.com. The webpage showed my ip address as 111.111.111.111 (which is the real ip address of my pc). This means that I'm no longer viewing the webpage through the reverse proxy and redirected straight to whatismyipaddress.com.
I think this is some kind of url rewriting trick which Josh Stodola has pointed out. I think I'm gonna read more on this. As to how to protect a server from reverse proxy, the best bet is to use SSL. Encrypted information passing through a proxy will be of no use since it can't be read in plain sight thus preventing eavesdropping and man-in-the-middle attack which what reverse proxy exactly is.
Safeguarding with javascript though can be seen trivial since javascript can be stripped off easily by a reverse proxy and also prevent other online services like google translate from accessing your website.
If you were to do Authentication over SSL using https://, you can bypass the proxy in most cases.
You can also look for the X-Forwarded-For header in the incoming request and match it against the suspicious proxy.
As I see it, your fundamental issue here is that whatever application layer defence measures you put in place to mitigate this attack can be worked around by the attacker, assuming this really is a malicious attack made by a competent adversary.
In my view, you should definitely be using HTTPS, which in principle would allow the user to confirm for sure whether they're talking to the right server, but this relies on the user knowing to check for this. Some browsers these days display extra information in the URL bar about which legal entity owns the SSL certificate, which would help, as it's unlikely an attacker would be able to persuade a legitimate certificate authority to issue a certificate in your name.
Some of the other comments here said that HTTPS can be intercepted by intermediate proxy servers, which is not actually true. With HTTPS, the client issues a CONNECT request to the proxy server, which tunnels all future traffic direct to the origin server, without being able to read any of it. If we assume that this proxy server is entirely bespoke and malicious, then it can terminate the SSL session and intercept the traffic, but it can only do that with its own SSL certificate, not with yours. This certificate will either be self signed (in which case clients will get lots of warning messages) or a genuine certificate issued by a certificate authority, in which case it'll have the wrong legal entity name, and you should be able to go back to the certificate authority, have the cert revoked and potentially ask the police to take action against the owner of the certificate, if you have reasonable suspicion that they are phishing.
The other thing I can think of which would mitigate this threat to some extent would be to implement one-time password functionality, either using a hardware/software token or using (my personal favorite) an SMS sent to the user's phone when they log in. This wouldn't prevent the attacker getting access to the session once, but should prevent them being able to log in in future. You could further protect the users by requiring another one time password before allowing them to see/edit particularly sensitive details.
There's very little you can do to prevent this without causing legitimate proxies (translation, google cache, etc..) from failing. If you don't care if people use such services, then simply set your web app to always redirect if the base url is not correct.
There are some steps you can take if you are aware of the proxies, and can find out their IP addresses, but that can change and you would have to stay on top of it. #jmz's answer is quite good in that regard.
I have come with an idea, and I think a solution.
First of all you do not need all page to be overwrite because this way you block other proxies, and other services (like google automatic translate).
So let say that you won to be absolute sure about the login page.
So what you do, when a user gets on login.aspx page you make a redirect with the full path of your site again to login.aspx.
if(Not all ready redirect on header / or on parametres from url)
Responce.Redirect("https://www.mysite.com/login.aspx");
This way I do not think that transparent proxy can change the get header and change it.
Also you can log any proxy, and or big requests from some ips and check it. When you found a Fishing site like the one you say you can also report it.
http://www.antiphishing.org/report_phishing.html
https://submit.symantec.com/antifraud/phish.cgi
http://www.google.com/safebrowsing/report_phish/
Maybe create a black-list of URLs and compare requests with Response.Referer if the website is on that list then kill the request or do a redirection of your own.
The black-list is obviously something you would have to manually update.
Ok i have went throu a similar situation but i managed to overcome it by using another forwarded domain that points to my original perminantly , then checking with code if the client is the reverse server or not if it it i would redirect them to my second domain which will go to the original
Check out more info from here: http://alphablog.xyz/your-website-is-being-mirrored-by-someone-else-without-your-knowledge/
The simplest way would probably be to put some Javascript code on your page that examines window.location to see if the top level domain (TLD) matches what you expect, and if not, replaces it with your correct domain (causing the browser to reload to the proper site instead).

Cookie on an intranet domain

I have a dev server in our office that is behind the firewall. The hostname is franklin. We name all our servers after scientists or inventors.
When I set an HTTP cookie:
Set-Cookie: user=kenny; expires=1245424860.11; Path=/; domain=franklin
The cookie doesn't set. I have tried the following with no luck.
.franklin
.franklin.local
franklin.local
.franklin.localdomain
franklin.localdomain
Do I have to set the hostname to something different or can I set this cookie through some magic I don't know already?
RFC 2109 says:
To prevent possible security or privacy violations, a user agent
rejects a cookie (shall not store its information) if any of the
following is true:
The value for the Domain attribute contains no embedded dots or
does not start with a dot.
The value for the request-host does not domain-match the Domain
attribute.
And also:
Domain Defaults to the request-host.
If your host is franklin:
Cookies with domain=.franklin will be rejected, because it has no embedded dot.
Cookies with domain=.franklin.local will be rejected, because it does not match the actual host name of your server.
The solution is to rename your hostname to franklin.local or franklin.<tld> and set the domain attribute of the cookie accordingly (domain=.franklin.<tld>). Alternatively (as you found out), do not specify the domain, and let the user agent fallback to the request host.
Are you setting the cookie from the right domain? You should access the website over http://franklin/ otherwise it wouldn't work (see: same origin policy).

Integrated Windows Authentication

We're experiencing some really strange problems with Integrated Windows Authentication with IIS and I'm not sure if I can see a pattern or not.
We have a DNS-Cname record called Fred. We have an IIS website with Fred set as the host header. When I connect to this site I get prompted with a credential challenge. I would expect my credentials to have been passed through. If I enter my credentials I am granted access.
I then create a local host entry called Betty and point the host file to the same IP address as Fred and change the host header to Betty. There is no associated CName record anywhere. When I access Betty I am authenticated automatically and everything is fine.
If I attempt to bypass the CName record and create an entry in the local host file called Fred and change back the host header to Fred. I still receive an authentication challenge.
As I see it have two questions. How is this CName record affecting the resolution here or is it a red herring. Secondly what is happening with this challenge? We have similar symptoms elsewhere and our concern is that our authentication token is getting blatted somewhere. Could someone walkthrough the order in with Authentication occurs i.e. what packets are sent to what machines. Is there a way I can trace this? (I'm thinking WireShark or something similar). How can I prove my authentication token is getting passed and is valid?
The reason for the authentication box is simple: Internet Explorer sends your credentials only if it thinks the host is in the "Local Intranet" zone (default configuration assumed). If a host outside what IE deems to be "local" asks for NTLM credentials, an authentication box will appear, and you have to authenticate manually.
If you want your credentials to be sent automatically, make sure IE thinks it in "Local Intranet". Check the zone info far right on the status bar to see the currently active zone.
IE takes into account multiple things in order to decide whether a host is to be considered as "Local Intranet":
is it an IP address in the local sub-net -> YES
is it a simple host name (i.e. "no dots") -> YES
in the IE options: is it in the "Sites..." list for "Local Intranet" -> YES
in the IE options: is it in the proxy exclusion list -> YES
is it an UNC path -> YES
otherwise: NO
Sometimes, an old password exists in the personal passwords list for that host name (accessible through Control Panel -> User Accounts). If it is wrong, similar issues can occur.
My suspicion is that your host "fred" does not fulfill conditions #2 through #4, but your test case "Betty" somehow does.
What way the name was resolved (CName record, A record, hosts file, other) makes no difference, because the method of name resolution is opaque to the calling application. IE just asks for name "XYZ" and gets an IP address back.
Recent configuration changes can require you to clear the local DNS cache, though. An occasional ipconfig /flushdns would help here, alternatively you can stop the DNS Client service for a while.
The described internal logic is applied to the host name and security settings change based on the outcome.
CName would be a red herring. Has no effect on Windows Auth or not.
The easiest way to trace it is with fiddler. You should see your request followed by a 401 response (it contains the authentication the server supports), then your request again is sent with the authentication details (or you are prompted and then it's sent)

Resources