<<< Date Index >>>     <<< Thread Index >>>

RE: Capital One's website inadvertently assists phishing

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.


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.


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.


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

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)


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.


Anton Rager

-----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
> one.

Looks like full disclosure worked. Thanks!


Timeline (should be mostly complete):

|13 Apr 01:28:45 -0400|Phishing email exploiting unchecked redirect
|13 Apr 01:54:51 -0400|Emailed webinfo@xxxxxxxxxxxxxx to report it|
|13 Apr 01:53:00 -0400|Blog post
|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
|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.|

<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"> 
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 = 
trustedNames += 
trustedNames += 
trustedNames += 
trustedNames += 
trustedNames += 
trustedNames += 
trustedNames += 
trustedNames += 
trustedNames += 
trustedNames += 
trustedNames += 
trustedNames += 
trustedNames += 
trustedNames += 
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)
        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 != "") {
                        } else { 
                                // referringURL is NULL
                                if (window.opener!=undefined) { 
                                        var poprefURL = 
                                } else { 
                } else { 
        } else {
</HEAD><noscript><p>You do not have JavaScript enabled. Please re-enable 
JavaScript and try again. </p> 
<p><a href="/">Continue</a></p>