71

I have a freelance client that wants me to integrate a payment gateway into their Woocommerce site but I am being increasingly concerned about their choice of provider and the project as a whole.

The Issues

Against my advice the client has selected the gateway provider. The provider is a far eastern one that I have never heard of before called Payforasia. The first warning flag is the fact the english and chinese (I think it is Chinese) version of their website doesn't appear to load images correctly.

I was provided documentation for the gateway API as a PDF and a simple PHP demo. They also gave me a login to the merchant front-end so I could monitor my test transactions. All fairly normal.

I ran the demo on my localhost and managed to connect to the payment gateway but got a failure error response. The error was not listed in the documentation, in fact the possible errors list goes from 0001 to 0067. I was getting error 0068. The second warning flag. When I contacted the provider, through my client, to ask for up-to-date docs and for advice on the error. I was told that the docs are the latest and that the office was closed for over week due to a national holiday (!?!?!). They finally got back to me today and said the error was "probably" due to them not whitelisting the server IP and that they had resolved that now. I still get the same error.

While I wait for them to come back to me on that I started digging into the demo code and rereading their documentation to see if I had missed something obvious. I noticed this line in their docs:

csid String 100 Yes Capture the value through http://cm.js.dl.saferconnectdirect.com/csid.js

Since the original testing, and while waiting for them to come off their week long national holiday, I had applied an SSL to my client's site and obviously the browser wouldn't load the insecure connection to the javascript. The URL to this is in the demo but right at the bottom after a huge number of returns between it and demo form markup. Another flag waves at me.

Turns out after trying the protocol agnostic url and HTTPS that the csid.js is not available over a secure connection. So I copy the JS to the server and amended the link in the markup. This is where the flag waving really starts going mental.

The script populates the CSID field with my user-agent string, my screen resolution, origin server and hashed data. It also, more worryingly, adds an iframe that appears to be a tracking image or something similar. The iframe fires off six strange connections using a wss:// protocol to localhost.

An image of the connection Errors from FireBug

I will admit at this point I panicked and came here to ask for advice. The JS is minified and appears to have a PHP eval() in it and what looks like encoded characters. I don't know how to decode this and I'm unsure if it is safe to continue digging further into the code.

My Questions

I need some advice.

  1. Am I being overly paranoid or do I have a genuine concern?
  2. Is it normal for a gateway provider to obfuscate their code like this?
  3. Should I advise my client to immediately change supplier?
  4. Should I walk away and chalk it up to experience?

Any advice, suggestions or comments on this will be hugely appreciated. Sorry if my question is rambling and a bit long, I wanted to get as much background in as possible.

Update

After all the excellent advice, I just wanted to give you all a quick update.

I brought up a lot of my concerns with my client, who did not react in the way I expect. I was accused of deliberately dragging my feet, inventing problems, being incompetent and received less professional questions as to my parentage. Relations between me and my client have definitely frosted.

They insisted that I implement the gateway without SSL on the site AT ALL. When I refused and invited them to find another developer they backed down almost straight away and became a little more cordial, although I have not yet received an apology.

Since then they have revealed that the gateway provider had whitelisted the wrong IP which was why I was still receiving the mysterious 0068 error. The gateway provider tried to pin that one on me until I provided Skype logs to the contrary. My client won't let me speak to the gateway provider directly, so the the IP address was garbled at some point between them.

With regards to the insecure JavaScript, my client has suddenly provided me, late yesterday, with this URL https://online-safest.com/pub/csid.js. They haven't provided any further documentation or where they have got this script from. I have not tested this script yet.

I'm not sure I want to continue with it so I've been dragging my feet. I need to have a think about it today. I will accept an answer tomorrow, unfortunately I can't accept multiple answers even though I have used the content of several.

Update 2

Just a final update. I completed this project for my client but I fear my relationship with them is now irrecoverably damaged. They insisted that I put the gateway live without any testing beyond the fact a single test transaction went through. I've told them that any post-live issues they have they will need to find another developer as they have gone live without testing and forfeited my normal support period.

You could argue that it is unethical for me to release code into the wild that could be buggy and dangerous for end-users, however I saw no other way to easily exit the contract. I have given them full access to the private GIT repo containing the source which contains all the documented interaction between me and the client. Any future developer should be able to view it and make a decision from there.

I further discovered that they have actually sub-contracted the job to me. All in all it is a project I am glad to be rid of.

bad_coder
  • 129
  • 4
user5451386
  • 803
  • 6
  • 7
  • 20
    You may have cause for your concern. While Payforasia's web site [claims PCI compliance](http://www.payforasia.com/en/premium%20services.html), there are no documents such as a copy of their Report of Compliance (RoC) or links to the PCI site or the card issuer's sites where validated services and applications are listed. I also went to some of those sites and could find no mention of Payforasia. I suggest you contact Payforasia and request a copy of their documentation of PCI compliance. If they don't provide it, make this clear to you client. – JaimeCastells Oct 16 '15 at 13:40
  • 1
    @JaimeCastells I just emailed them requesting the RoC or other compliance documents, what would a legitimate one look like or contain? – user5451386 Oct 16 '15 at 14:38
  • If they have a ROC, they shouldn't give it to you, but they should give you their AOC, their Attestation of Compliance. If they have an AOC, then they're a level 1 Service Provider, and should be listed in the Visa directory - you can match the name on the AOC up with the database. If they're level 2, they'd have self-assessment forms, which you can download copies of from pcisecuritystandards.org to compare to, but the actual content of their answers are in no way validated or trusted (which is why level 2 Service Providers are very, very rare). – gowenfawr Oct 16 '15 at 16:26
  • 5
    Holidays are different in China; it is not uncommon for offices to shut down. There was a recent one of these shutdowns 1-2 weeks ago. So I would not assume that the office being closed means terrible things about the company. I'm not saying that it's a good thing, just that it should be interpreted in the right cultural setting. – Neil Smithline Oct 16 '15 at 18:34
  • 1
    (This is not related to your question, but anyway,) To avoid raising your own warning flags, you [should replace SSL with TLS](http://security.stackexchange.com/q/70719/49075). ​ –  Oct 16 '15 at 20:32
  • 2
    The company is in China, but I (as a Chinese) never hear about it. I cannot find discussions about the site on Chinese search engines, either. For online payment we Chinese use Alipay, Tenpay, Baifubao etc. – jingyu9575 Oct 17 '15 at 12:31
  • @RickyDemer I used SSL as a catch all term as in my experience most clients aren't aware of a difference. You do make a good point though and I'll go check I have applied the certificate correctly – user5451386 Oct 18 '15 at 13:33
  • @jingyu9575 Thanks for the feedback on that. I had tried googling them, but hadn't really found anything about them. Good to know that its the same in China. – user5451386 Oct 18 '15 at 13:37
  • Just to confirm a previous comment, the national holiday in China is definitely legitimate. There was one at the [start of October](https://en.wikipedia.org/wiki/Golden_Week_%28China%29) and, having travelled to China last year during those dates, I can confirm that people do stop working en masse during this period. – Jon Bentley Oct 19 '15 at 11:47
  • Hence the multi-million-year traffic jam heading into Beijing at its conclusion. – Lightness Races in Orbit Oct 19 '15 at 12:44

5 Answers5

66
  1. Am I being overly paranoid or do I have a genuine concern?

You have a genuine concern. Something is not right here.

  1. Is it normal for a gateway provider to obfuscate their code like this?

Obfuscation is not, all by itself, abnormal. However, at the point they're trying to open localhost connections to RDP, VNC, and other ports, that's not obfuscation, that's completely inappropriate and malicious.

  1. Should I advise my client to immediately change supplier?

I would advise your client that the code provided for integration appears to be malicious and that you cannot assume the supplier is either a) legitimate or b) capable of securing their business (and by extension, your client's). In addition, the supplier does not appear to integrate properly into a secure purchasing environment (the http: only js link), which calls into question their appropriateness even if legitimate.

As per @JaimeCastells's comment to the question, there is no "payforasia" service provider listed at http://www.visa.com/splisting/searchGrsp.do. That could mean they're doing business under that name but are certified under a different name, or it could mean they're a "Level 2 Service Provider". Neither of those options is reassuring, quite frankly.

  1. Should I walk away and chalk it up to experience?

If the client wants to continue with this supplier, I would definitely consider walking away. You can't make the client do the right thing, but you can choose not to be the one doing the wrong thing for them.

Javascript analysis

The intent of the obfuscated Javascript seems important. I've tried to untangle what's happening in the Javascript, and I'll link to readable partially de-obfuscated copies in this section.

Overall, my impression is that the level of obfuscation used in these scripts exceeds what is commercially reasonable and becomes suspicious as a result. The limited amount of inferences I can draw about what it does are not inline with normal payments processing. Lacking better information, I presume this is malicious javascript.

Here are files I'm looking at should you wish to explore the same question. These files have been run through the Online Javascript Beautifier and I've also used the Online Javascript Editor to pick apart bits of what the scripts do. You can see that even with the basic de-obfuscation applied, there's still a lot of obfuscation in place - check.js is full of arrays of integers which get processed by the code, and which are presumably more text or code to be executed.

There are at least four scripts involved:

It's clear, for example, that the five ports the OP saw getting connection attempts are hardwired into check.js:

td_0a = ['REF:63333', 'VNC:5900', 'VNC:5901', 'VNC:5902', 'VNC:5903', 'RDP:3389'];

I will continue to poke at them, and may pastebin some copies, but I think it's reasonable to be distrustful of this code at this point.

gowenfawr
  • 71,975
  • 17
  • 161
  • 198
  • 19
    +1 for that last sentence alone. Sometimes you just can't overcome willful stupidity, but that doesn't mean you have any obligation to further enable it! – Mason Wheeler Oct 16 '15 at 17:35
  • @duskwuff's [answer](http://security.stackexchange.com/a/102924/10885) comes to a very different conclusion - especially about the nature of the attempted port connections. – Neil Smithline Oct 16 '15 at 18:31
  • 4
    @NeilSmithline, 3389 and 590X are not ports you would check for an "Open Web Proxy", but they are ports you'd check if you wanted to know if you had a chance of remote access to a system. Also, credit card payment client code is all about the mils - surprisingly small additions of latency are enough to make cardholders go somewhere else. Setting up a "client posture check" of any usefulness would be awfully prohibitive in terms of elapsed time. So, _personally_, I am dubious... good to kick the tires on any ideas people, have, though, so good to think about. – gowenfawr Oct 16 '15 at 18:42
  • 1
    @gowenfawr Perhaps not in the classical sense of an "open web proxy", but having those ports open does indicate that you're probably not looking at a normal desktop system. –  Oct 17 '15 at 06:20
  • de-obfuscation? ​ Do you mean obfuscation, or maybe anti-deobfuscation? ​ ​ ​ ​ –  Oct 20 '15 at 20:24
  • @RickyDemer, correct, should have been "level of de-obfuscation required" or "level of obfuscation in play". Good catch, I'll fix it. – gowenfawr Oct 20 '15 at 20:29
20

A bit more info on that obfuscated javascript: They're using packer, a quite famous javascript compression method. Here's the unpacked js (you can also unpack it yourself here: http://dean.edwards.name/unpacker/ ):

var a = "";
try {
    var z = document.createElement('canvas');
    var A = z.getContext('2d');
    var B = 'http://security.tencent.com/';
    A.textBaseline = "top";
    A.font = "14px 'Arial'";
    A.textBaseline = "tencent";
    A.fillStyle = "#f60";
    A.fillRect(125, 1, 62, 20);
    A.fillStyle = "#069";
    A.fillText(B, 2, 15);
    A.fillStyle = "rgba(102, 204, 0, 0.7)";
    A.fillText(B, 4, 17);
    var C = z.toDataURL();
    C = C.replace("data:image/png;base64,", "");
    var D = atob(C).slice(-16, -12);
    a = b(D)
} catch (err) {};

function b(z) {
    var A, B, C = '',
        D;
    z += '';
    for (A = 0, B = z.length; A < B; A++) {
        D = z.charCodeAt(A).toString(16);
        C += D.length < 2 ? '0' + n : D
    };
    return C
};

function c(z, A) {
    var B = 180;
    var C = new Date();
    C.setTime(C.getTime() + B * 24 * 60 * 60 * 1000);
    document.cookie = z + "=" + escape(A) + ";expires=" + C.toGMTString()
};

function d(z) {
    var A, B = new RegExp("(^| )" + z + "=([^;]*)(;|$)");
    if (A = document.cookie.match(B)) return unescape(A[2]);
    else return null
};

function e() {
    var z = "";
    for (var A = 1; A <= 32; A++) {
        var B = Math.floor(Math.random() * 16.0).toString(16);
        z += B
    };
    z += new Date().getTime();
    return z.toUpperCase()
};
var f = "";
f = d("ccpspay");
if (f == null || f == '') {
    f = c("ccpspay", e());
    f = d("ccpspay")
} else {
    f += "OLD"
};
var g = "vduzzz8d";
var h = e();
var i = "";
i = navigator.systemLanguage || window.navigator.systemLanguage || navigator.language;
var j = "";
j = navigator.browserLanguage || window.navigator.browserLanguage || navigator.language;
var k = "";
k = navigator.appCodeName || window.navigator.appCodeName;
var l = "";
l = navigator.appMinorVersion || window.navigator.appMinorVersion;
var m = "";
m = navigator.appName || window.navigator.appName;
var n = "";
n = navigator.appVersion || window.navigator.appVersion;
var o = "";
o = navigator.cookieEnabled || window.navigator.cookieEnabled;
var p = "";
p = f;
var q = "";
q = a;
var r = "";
r = navigator.platform || window.navigator.platform;
var s = "";
s = navigator.userAgent || window.navigator.userAgent;
var t = "";
t = navigator.userLanguage || window.navigator.userLanguage;
var u = "";
u = String(window.screen.fontSmoothingEnabled);
var v = "";
v = String(window.screen.width + "x" + window.screen.height);
var w = "";
w = String(window.screen.colorDepth);
var x = new Array;
x[0] = i;
x[1] = j;
x[2] = k;
x[3] = l;
x[4] = m;
x[5] = n;
x[6] = o;
x[7] = p;
x[8] = q;
x[9] = r;
x[10] = s;
x[11] = t;
x[12] = u;
x[13] = v;
x[14] = w;
x[15] = new Date().getTimezoneOffset() / 60 * -1;
x[16] = window.location.host;
x[17] = h;
var y = x.join("&@");
document.getElementById("csid").value = y.toUpperCase();
document.write("<script type='text/javascript' src='https://h.online-metrix.net/fp/tags.js?org_id=" + g + "&session_id=" + h + "&pageid=1'></script>");
document.write("<noscript><iframe style='width: 100px; height: 100px; border: 0; position: absolute; top: -5000px;' src='https://h.online-metrix.net/tags?org_id=" + g + "&session_id=" + h + "&pageid=1'></iframe></noscript>");

While they may be a legit payment gateway (I don't know but they look pretty shady to me), they are filled with tracking tools. You may at least want to warn the client about that.

Tobias Kienzler
  • 7,578
  • 10
  • 43
  • 66
BgrWorker
  • 1,941
  • 1
  • 10
  • 17
  • 1
    Strange, I added a [syntax hint](http://meta.stackexchange.com/questions/184108/what-is-syntax-highlighting-and-how-does-it-work/184109#184109) but the code still isn't highlighted, is this deactivated on security.SE? – Tobias Kienzler Oct 17 '15 at 21:08
  • @Tobias Almost certainly, because there's no point in loading a library for every page when it's only required on one or two. MathJax doesn't work on [english.SE] for the same reason. A question for Meta, perhaps, since which libraries to load could be specified based on page content. – Andrew Leach Oct 20 '15 at 06:54
19

The behavior of the Javascript code you're analyzing is unusual, but plausible as part of an anti-fraud system.

This script is being used to evaluate the fraud risk of a client machine. As part of this evaluation, it is checking whether the machine may be configured as an open web proxy -- this is why the script is trying to open WebSockets to localhost on various ports. I have not seen this particular technique before, but I think it's rather clever actually. :) It avoids performing an invasive external port scan by having a client machine scan itself!

I didn't fully analyze the script myself, but based on some keywords in the script you linked, it appears that the script is also collecting various pieces of identifying information from the browser, such as the browser version, the system language, and various configuration options. Again, this is reasonable for an anti-fraud evaluation, and this vendor is not unusual in using these sorts of methods.

  • 17
    Perhaps what the provider is doing is reasonable in terms of checking the local machine's vulnerabilities. However, the simple fact that they are sending sensitive information over HTTP and don't support HTTPS is the only red flag I would need. I don't care how many security measures are taken to check out *my machine* when anyone could intercept my account information over the wire with minimal effort. – Chris Cirefice Oct 16 '15 at 18:34
  • 3
    Oh, the HTTP detail is definitely wrong. That part's not in question. :) –  Oct 16 '15 at 18:47
  • '*Turns out after trying the protocol agnostic url and HTTPS that the csid.js is not available over a secure connection.*" - I may have misread, but is that not saying that identity fraud protection information collected by this third party couldn't be sent over HTTPS? And shouldn't it be? – Chris Cirefice Oct 16 '15 at 18:49
  • Not vouching for whether it's what's happening in this situation, but isn't "having a client machine scan itself [/] to evaluate [its] fraud risk" a clanging contradiction in terms? e.g. couldn't the machine simply edit the JS or its response, thus making the recipient think everything's fine? – underscore_d Oct 18 '15 at 13:37
  • @underscore_d Correct. However, obfuscating the Javascript code is an attempt to make that difficult (and I think we've inadvertently foiled it by tearing the code apart here). –  Oct 18 '15 at 16:46
  • The code is scanning ports on the **machine that runs the browser**, not the one that would act as a **proxy** (if there is one). That makes this technique utterly useless as detection method for open proxies. – mastov Nov 30 '16 at 12:44
10

I will answer only question one from another angle:

Am I being overly paranoid or do I have a genuine concern?

You have genuine concern due to their website alone.

http://www.payforasia.com/

The reason images are not loading is because of AdBlock (see image below).

The source of their images are on a separate server:

(probably don't want to look at it, to be safe)
http://www.payforasia.com.img.800cdn.com/images/logo.jpg  

800cdn.com is on the list of malware domains:

https://easylist-downloads.adblockplus.org/malwaredomains_full.txt

The company is Chinese, and the Chinese sections mention it is in Shenzhen.

enter image description here

Nelson
  • 339
  • 2
  • 10
  • I stupidly hadn't looked at the console for Adblock alerts, thanks for that. – user5451386 Oct 18 '15 at 13:27
  • 1
    Does being in Shenzhen have any bearing on concerns about security? – underscore_d Oct 18 '15 at 13:39
  • 1
    @underscore_d I think Nelson was just confirming the location of the company rather than suggesting the fact they are Chinese should have any bearing on trustworthiness – user5451386 Oct 18 '15 at 14:02
  • 1
    Google's Safe Browsing diagnostics for 800cdn are grimly entertaining: they start off by saying "This site is not currently listed as suspicious." - before reeling off a list of statistics about malware being served from the domain, which steeply accelerate as you scroll down. Having said that, I assume that as a Content Delivery Network(?), they've at the mercy of whatever their customers upload, rather than intrinsically suspect. Still, by association, I wouldn't rush to associate my/customers' finances with them – underscore_d Oct 18 '15 at 14:19
  • Hmm, I'm not sure what to make of the Google Safe Browsing diagnostics. Their diagnostic of their own domain doesn't look that great either :) – Nelson Oct 18 '15 at 23:58
3

Maybe your client is not up to date. You can go to SSL Labs and check their server. If they only allow the newest protocols, your client code might fail. (On my server, for example, all java clients fail because I don't use and care about those!)

Otherwise, I agree, very dubious practices. Can you contact someone in China to check whether they are a normal provider and also that you have the right access data? Could it be someone pretending to be that company?

Also, not to make you more paranoid, but any answer you get here that the service is legitimate or where to check whether it is might come from exactly those people you ask about. ;-)

TRiG
  • 609
  • 5
  • 14
user89447
  • 31
  • 2