This an interesting 'fix'. It appears that the redirector domain check logic is in the '200 OK' response from capitalone's server in the form of HTML/Javascript. The client logic checks the redirect location against a list of valid sites or a regex match on "capitalone.com" domain. There are several ways to circumvent this javascript logic: 1 - The check for "capitalone.com" is a simple regex check within the URL string, so if the attacker can create a valid domain named "capitalone.com.attacker.com", then it will pass the validation checks and redirect to the attacker's server. http://www.capitalone.com/redirect.html?linkid=SECURITY+VALIDATION&dest= http://capitalone.com.attacker.com The regex for /capitalone.com/ matches within the URL and allows the rest of the URL to pass thru. 2 - The check is not actually aware of all the ways URLs can be formatted, and user@domain can be used to fool the checks. An example would be "http://www.capitalone.com@xxxxxxxxxxxx" for the redirect URL. This will throw a warning in Firefox and doesn't work with IE, but is a way around the filter. http://www.capitalone.com/redirect.html?linkid=SECURITY+VALIDATION&dest= http://www.capitalone.com@xxxxxxxxxxxx The substring/regex matches on the initial occurrence of http://capitalone.com, but when the browser decodes the URL it submits a userID of "http://capitalone.com" to the site "attacker.com". 3 - if an attacker specifies a redirect location early in the URL without using a :// ref, the :// ref con be placed later in the string to trick the check logic. http://www.capitalone.com/redirect.html?linkid=SECURITY+VALIDATION&dest= //www.attacker.com/http://www.capitalone.com The substring/regex logic is looking for what follows after the "://" sequence, so doesn't pay attention to the first portion that actually is the URL the browser goes to. We have to add the "//" after "dest=" to force the browser to treat the location as another site. 4 - The above idea should also apply to javascript tags, but the server CGI seems to be forwarding to capitalone.com when there is a match for the string "script" anywhere in the URL. Odd way to block XSS.....I wonder why that server-side logic isn't doing the valid site checks as well? This means that "javascript:", "livescript", "ecmascript", "jscript:" and "vbscript:" are blocked, but "mocha:" gets thru if you have a browser that actually understands that ref like older Netscape (test in 4.7x and it works) http://www.capitalone.com/redirect.html?linkid=SECURITY+VALIDATION&dest= mocha:alert(document.domain)//http://www.capitalone.com I've attached the client-side Javascript validation document for reference. It's also somewhat interesting what other sites they will allow redirection to. These checks really need to analyze URLs more fully and should be done server-side instead of using client javascript to allow/block redirects. Regards, Anton Rager arager@xxxxxxxxx -----Original Message----- From: Joseph Barillari [mailto:bugtraq@xxxxxxxxxxxxx] Sent: Tuesday, April 19, 2005 5:12 PM To: dramatools Cc: bugtraq@xxxxxxxxxxxxxxxxx; webinfo@xxxxxxxxxxxxxx Subject: Re: Capital One's website inadvertently assists phishing On Tue, Apr 19, 2005 at 05:30:28PM -0500, dramatools wrote: > However, I clicked your "proof of concept" link and found that the > redirector did not send me to Wikipedia as expected, but Capital One's > home page. Perhaps one of their security people is lurking on bugtraq > and attempted to fix the problem on the spot. I'll keep monitoring this > one. Looks like full disclosure worked. Thanks! http://barillari.org/blog/computers/internet/conephishing-updated.html Timeline (should be mostly complete): |13 Apr 01:28:45 -0400|Phishing email exploiting unchecked redirect arrives| |13 Apr 01:54:51 -0400|Emailed webinfo@xxxxxxxxxxxxxx to report it| |13 Apr 01:53:00 -0400|Blog post "posted":http://barillari.org/blog/computers/internet/conephishing.html| |13 Apr 16:29:45 -0400|Inform Capital One of my intention to post to "bugtraq":http://securityfocus.org/archive/1 in 24 hours| |13 Apr 16:31:11 -0400|Capital One form letter arrives: "this [phishing] email has not compromised Capital One's systems in any way,"| |13 Apr 16:44:42 -0400|Reply to Capital One form letter: "this email _has_ taken advantage of a compromised Capital One system: Capital One's website redirects URLs without checking them....please see the note about bugtraq below"| |13 Apr 16:47:15 -0400|Another form letter: "A Capital One representative will respond to your e-mail inquiry, usually within 24 - 48 hours. Please note, due to high email volumes, this timeframe may be extended to up to 72 hours". I wonder if saying "bugtraq" provokes this response.| |19 Apr 16:32:15 -0400|Four business days later (well beyond 72h), redirect is still unchecked. "Post":http://www.securityfocus.com/archive/1/396255 bug to bugtraq and cc Capital One| |19 Apr 16:53:46 -0400|Reply to Capital One (signed by a human?) form letter: "the point is that the phishing email _has_ exploited a flaw in Capital One's systems. Your website permits unchecked redirects. This makes a phisher's job much, much easier.| |19 Apr 18:01:00 -0400|A bugtraq subscriber tells me that he's emailed abuse@xxxxxxxxxxxxxx (I should have thought of that)| |19 Apr 14:27:05 -0800|<b>Another bugtraq subscriber tells me that it's fixed.</b> Checked myself --- apparently, it is.| |19 Apr 18:55:38 -0400|Send email to webinfo@, thanking them for fixing the unchecked redirect.|
<HTML> <HEAD> <title>Redirecting....</title> <META http-equiv="cache-control" content="no-cache"> <META http-equiv="pragma" content="no-cache"> <META http-equiv="expires" content="Wed, 26 Feb 1997 08:21:57 GMT"> <SCRIPT LANGUAGE="JavaScript"> var url_str = top.location.href; var url_index = url_str.indexOf("dest="); //for identifying urls containg "getmycard" and "apply2" var entryURL = window.location.search.toLowerCase(); var trustedNames = "www.tuc.ca|www.equifax.ca|www.consumer-action.org|www.yourcreditcardcompanies.com|phx.corporate-ir.net|"; trustedNames += "www.cb.net|www.secondharvest.org|www.heartofamerica.org|www.jumpstartcoalition.org|www.whitehousedrugpolicy.gov|"; trustedNames += "www.theantidrug.org|www.coveringkids.org|www.national.unitedway.org|www.capitalonemortgage.com|www.fullspectrumlending.com|"; trustedNames += "partners.financenter.com|www.peoplefirst.com|www.reliaquote.com|www.capitaloneautofinance.com|capitalonecareersone.com|"; trustedNames += "www.hrmc-c1.com|www.linkageinc.com|www.nbmbaa.org|www.nsbe.org|www.nshmba.org|"; trustedNames += "www.reachingoutmba.org|usa.visa.com|www.mastercard.com|www.carparts.com|www.planplus-discounts.com|"; trustedNames += "www.milesone.com|www.adobe.com|www.equifax.com|www.experian.com|www.transunion.com|"; trustedNames += "www.usa.visa.com|www.consumer.gov|www.ftc.gov|www.securesuite.net|www.occc.state.tx.us|"; trustedNames += "www.money-wise.org|www.moneywise-u.com|www.youngmoney.com|www.milesone.com|www.mycapitalonerewards.com|"; trustedNames += "www.collegeonecard.com|www.capitalonesavings.com|cib.ibanking-services.com|my.capitaloneautofinance.com|capitalone.mortgageeservices.com|"; trustedNames += "www.capitalone.inslogic.com|www.capitaloneisland.com|www.getmycard.com|www.capitalonehomeequity.com|www.capitalonehealthcarefinance.com|"; trustedNames += "secure.capitalonefinance.com|www.jamsadr.com|www.adr.org|www.arbitration-forum.com|www.capitalone.ca|"; trustedNames += "www.capitalone.co.uk|www.capitalone.it|www2.iraservicecenter.com|www.com|www.progressive.com|"; trustedNames += "www.CapitalOneAutoInsurance.com|www.fdic.gov|capitalone.inslogic.com|www.citizenshealth.com|www.eadinsurance.com|"; trustedNames += "www.RentersIns.com|www.insurekidsnow.gov|capitalone.mortgageeservices.com|www.bbb.org|www.sba.gov"; if (url_index != -1) { var domain_start = url_index + 5; var url_value = url_str.substring(domain_start, url_str.length); var serverIndex = url_value.indexOf("://"); if (serverIndex == -1) location.replace("http://www.capitalone.com"); var serverName = url_value.substr(serverIndex + 3).toLowerCase(); if (serverName.indexOf("/") != -1) serverName = serverName.substr(0, serverName.indexOf("/")); if ((serverName.search(/capitalone.com/gi) != -1) || (trustedNames.toLowerCase().indexOf(serverName) != -1)) { if ((entryURL.search("getmycard") != -1) || (entryURL.search("apply2") != -1)) { var referringURL = document.referrer; if(referringURL != "") { location.replace(url_value+'&referrerURL='+referringURL); } else { // referringURL is NULL if (window.opener!=undefined) { var poprefURL = window.opener.location.href; location.replace(url_value+'&referrerURL='+poprefURL); } else { location.replace(url_value); } } } else { location.replace(url_value); } } else { location.replace("http://www.capitalone.com"); } } </SCRIPT> </HEAD><noscript><p>You do not have JavaScript enabled. Please re-enable JavaScript and try again. </p> <p><a href="/">Continue</a></p> </noscript> </HTML>