The chronicles of the work and personal life of a boring software developer with an awesome dog.
Wednesday, December 4, 2013
Prosper Marketplace is one of the two big peer-to-peer lending platforms (the other being Lending Club), where individuals can loan or borrow money from each other. Like any online investment system, it provides a way for users to move money in and out via ACH transfers to regular bank accounts. And to do that, one needs to link one's Prosper account and bank account.
Since we're talking about a financial institution making important account changes, surely they have a secure way to do this, right? Wrong.
Back in March 2012 when I started making loans on Prosper, the process was pretty standard: enter the bank account number into Prosper.com (over HTTPS), wait a few days for some verification deposits of less than $1 each, and then log back into Prosper.com and type in the amounts to verify that you really own the bank account. This seems to work for most financial institutions, but apparently not Prosper, because, in a unique move that harms both security and usability, they've changed it. Now, when trying to add or remove a bank account, Prosper shows the following message:
For security reasons, to add or change your bank account, you must print a fax cover sheet and attach a copy of a cancelled check from the bank account you wish to add.
Click here to print a specially coded fax cover sheet which will speed processing. Specific instructions are printed on the cover sheet.
The instructions say to fax or email a copy of the account holder's driver's license and either a voided check or recent bank statement. And they won't accept this form snail-mailed or hand-delivered (I called to check). This is horrible!
Fax and email are both completely insecure methods of communication. Anyone between me and Prosper can read, copy, and store my driver's license, bank account number, address, and whatever other personal information I might be sending (like any recent transactions shown on the bank statement). Email is probably worse because typically emails are routed through a couple of servers, creating multiple copies along the way.
It's especially scary that Prosper's message begins with "for security reasons" — is their intent to eliminate security? Because that's the only effect on security that I can see. If there is any security benefit to this approach at all, I'd love to hear. Anyway, how can Prosper even verify whether a copy of a driver's license, check, or bank statement is legitimate? Copies of all of these items are trivially forgeable.
Worse, Prosper is requiring its lenders to send private documents over an insecure channel. One example attack, just for illustration, might be the following:
- Intercept a legitimate fax/email containing relevant documents. (Example methods: hack an insecure mail server along the route, hack a router, DNS attacks, routing attacks, bribe a Gmail/Hotmail/Yahoo employee, wiretap ...)
- Slightly modify the voided check or bank statement to show the same name, but an account number owned by the attacker.
- Send Prosper a new email containing the real driver's license with the modified check or bank statement.
- The victim probably doesn't notice since the "Bank Accounts" section of the Prosper site only shows the name of the bank and the last few digits of the account number; only the account number will have changed.
- Wait for the real user to withdraw some cash out of Prosper.
I am extremely disappointed that Prosper has taken such a giant leap backwards in terms of security and am strongly considering withdrawing my funds from the platform and leaving — if this is how their public-facing side operates, then what security nightmares are hidden from view?
Monday, May 20, 2013
It's tempting to assume that PHP's $_SERVER array mostly contains fields out of the reach of an attacker, since these are "server" variables. However, that's not always the case; in particular, the seemingly innocuous
PHP_SELF field can be a vector for cross-site scripting.
For example, consider the following
<form method="POST" action="<?php echo $_SERVER['PHP_SELF'] ?>"> <!-- ...form elements... --> </form>
If I visit
$_SERVER['PHP_SELF'] will be
/foo.php and everything will work correctly.
But what if I visit
http://www.example.com/foo.php/"><script>alert('hello');</script> instead? Then the rendered HTML will be:
<form method="POST" action="/foo.php/"><script>alert('hello');</script>"> <!-- ...form elements... --> </form>
This allows injection of arbitrary script running under the host site's context, also known as XSS. Two ways to fix this are:
$_SERVER['PHP_SELF']. The former is the name of the actual script file and can't normally be manipulated by an attacker.
- Use htmlspecialchars(), which by default will escape double-quotes and prevent a user-supplied string from breaking out of an HTML attribute context.
By the way, this was pretty surprising behavior to me for two reasons:
- The documentation of PHP_SELF is misleading: The first sentence says:
It seems odd that PHP would refer to something like
The filename of the currently executing script, relative to the document root.
/foo.php/"><script>alert('hello');</script>as a "filename."
- It's pretty bizarre default behavior that PHP will execute
/foo.phpfor a request of
Tuesday, April 2, 2013
By default, gvim on my Windows machines just displays question marks, boxes, or garbled characters when I try to open files with Chinese text. The fix was rather simple:
- From the gettext project on SourceForge, get libiconv-1.9.1.bin.woe32.zip, which contains bin/iconv.dll. Put that file into gvim's installation directory (for me, it's C:\Program Files (x86)\Vim\vim73).
- Put this into vimrc:
set encoding=utf8 set guifontwide=NSimSun
Note: I'm using gvim 7.3.46 from the official site.
Credit goes to user Tobbe for this answer on superuser.com, which pointed out the key ingredient (iconv.dll).
Friday, March 29, 2013
Stanford (and probably many other schools) provide official transcripts in the form of a signed PDF. This transcript can only be opened using Adobe Acrobat; other readers simply choke on the document and can't open it. This is caused by the use of a proprietary "secured" document signing feature, apparently exclusive to Adobe Reader, which verifies the authenticity of the transcript. (For comparison, Duke University provides regular PDFs that can be opened by any reader, but can be verified by uploading the file to a trusted authority who confirms the document's legitimacy.)
Stanford's PDFs are particularly annoying because you can't take a screenshot with Print Screen (though the Snipping Tool works), Acrobat won't remove the signature, and attempting to use Acrobat Reader print the PDF to CutePDF simply results in a mostly-blank page with the following text:
ERROR: undefined OFFENDING COMMAND: get STACK: /quit -dictionary- -mark
Here's how to un-certify the PDF:
Open the secured PDF in Acrobat Reader and "Print to File" (File/Print, click Advanced, and check the box).
Note: this step may violate certain laws. Proceed at your own risk. A comment in the file declares that "Removing the following eleven lines is illegal, subject to the Digital Copyright Act of 1998."
Open the resulting .ps file in a text editor. Find and delete the following block:
mark currentfile eexec ... stuff here ... cleartomark
Then, use ps2pdf or similar to convert the PostScript file to PDF.
This entire step can be accomplished with the following:
$ sed '/mark currentfile eexec/,/cleartomark/d' secured.ps \ | ps2pdf - unsecured.pdf
For Stanford transcripts, the pages need to be rotated clockwise, so use pdftk:
$ pdftk input.pdf cat 1-endE output output.pdf
Friday, March 22, 2013
LSIUtil is a handy tool for configuring some LSI RAID controllers, including the SAS 6/iR I have in my Dell box:
LSI Logic / Symbios Logic SAS1068E PCI-Express Fusion-MPT SAS (rev 08)
I'll leave the usage guides to others, but I'll mention one issue I had. I recently ran into Redhat Bug 512613 - Smartmontools cause hard drives behind a SAS controller to get dropped (or perhaps a similar bug), where I used smartctl to query /dev/sgX which promptly knocked one of my drives offline. The controller (via mpt-status) reported the disk to be MISSING and OUT_OF_SYNC, and Linux could not see it at all. I tried all kinds of things, but in the end, even LSIUtil and reboots did not fix it and I had to go to the datacenter, physically disconnect the "missing" drive, and then reconnect it. At that point, the RAID array began resyncing.
In the process, I found that an authoritative copy of LSIUtil is incredibly hard to find online. Here are the two newest copies I could find on LSI's servers:
- FC_LinuxMPT_RH4_SLES9_3.13.04.zip contains mptlinux-3.13.04.00-src.tar.gz, which contains lsiutil.tar.gz (local mirror), which has the source code to LSIUtil 1.57.
- LSIUtil_1.62.zip (local mirror) contains binaries only; I couldn't find the source.
Hope this helps someone.