Archive for the ‘Code’ Category
Friday, December 16th, 2016
Wednesday, February 10th, 2016
Thursday, November 12th, 2015
So I started getting emails yesterday complaining that Jettison was suddenly telling users their trial period was over – even though they’d already purchased a license. When I got the first few, I thought they’d just deleted their preference files and needed to re-activate their licenses, but then the trickle became a deluge – what the heck?
So I dropped everything and looked into it – I needed an answer ASAP or I was gonna spend the next couple of days doing nothing but answering email. It turns out everyone who was affected had bought Jettison through the Mac App Store and then upgraded to the direct-from-the-website version (because it’s better, of course – instructions here if you’re interested). When you do this, Jettison copies your Mac App Store receipt to a safe place so that it can verify that you’ve actually bought a license, even if you delete the App Store copy of Jettison.
Lucky for me, I’d bought a copy of Jettison myself when testing this mechanism, so I had my own receipt still sitting in ~/Library/Application Support/ so I could look at it. Printing the certificates in the receipt showed this little tidbit:
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=US, O=Apple Inc., OU=Apple Worldwide Developer Relations [...]
Not Before: Nov 11 21:58:01 2010 GMT
Not After : Nov 11 21:58:01 2015 GMT
Subject: CN=Mac App Store Receipt Signing, OU=Apple Worldwide Deve [...]
See that “Not After:” entry in the Validity section? “Nov 11 21:58:01 2015 GMT” – yeah, that’d be yesterday. When the emails started. Apple signed the receipt with a certificate that expired yesterday, so if you have one of these receipts, Jettison no longer thinks you’re legit. Sorry about that – I hadn’t considered that eventuality. And reading the news this morning, it appears that Apple hadn’t either.
So what to do? I’ve wrapped up Jettison 1.5 and posted it. You’re going to have to do a little dance again to get Jettison to update your receipt, but this version will do the right thing once you follow these instructions:
- Put every copy of Jettison on your Mac in the Trash and empty the Trash.
- Open the App Store application and click on the Purchases tab.
- Re-download the copy of Jettison you purchased. It will include a new, non-expired receipt.
- Download the latest version of Jettison (http://www.stclairsoft.com/download/Jettison-1.5.1d2.zip)
- Double-click the .dmg file to open it, then double-click on Jettison before copying it to your Applications folder.
- After Jettison tells you that it has found your App Store license, you can copy it to your Applications folder.
Sorry for the hassle. But hey, at least it forced me to get the version 1.5 update out the door, so there’s some benefit there, eh? And thanks Apple – I didn’t need to sleep last night anyway.
P.S. I’m seeing a bunch of people buying non-App Store licenses directly from the St. Clair Software store today instead of jumping through these hoops to deal with the App Store. I have to say I’m all for that 🙂
A bit more info that’s interesting and could use some corroboration: I think this problem only affects apps that were downloaded before September 24 (either via purchase or update). When I download a new copy of Jettison from the App Store, the receipt is signed with a cert valid within these dates:
Not Before: Sep 24 19:09:31 2015 GMT
Not After : Oct 23 19:09:31 2017 GMT
So in my sample size of 1, copies of Jettison purchased or updated today will work until Oct 23, 2017, and could have worked with this receipt only as far back as September 24. If Apple has been using the same certificate to sign all App Store receipts (which seems reasonable), then anything that has been downloaded from the App Store after September 24 won’t expire until 2017. And apps downloaded prior to that have some other expiration in their receipts. If I had more time, I’d dig through all of my App Store apps to find out when each cert expires, but alas, I’ve got work to do and have killed enough time on this already…
Monday, June 18th, 2012
Kudos to Kubra and BC Hydro – they fixed this problem within 8 hours of receiving my report and are reviewing some of their practices as well. If you’re a BC Hydro customer and have made online payments in the past, you still need to make sure to clean any of the old URLs out of your browser history.
Notice anything disconcerting about this URL?
https://secure3.i-doxs.net/BCHydro/OneTime_PayProcess.asp?PaymentDate=6%2F6%2F2012&AccountNumber=1234567&InvoiceNumber=&PayAmount=38.05& Description=&CustomerEmail=jon%40email.net&CustomerName=Jon+Gotow&PaymentType=CC& State=&ConvenienceFee=2&CCCardName=VISA&CCHolderName=Jon+Gotow& CCNumber=4123456789012345&CCCVV2=123&CCMonth=1&CCYear=15&AVSname=& AVSphone=&AVSaddress1=&AVSaddress2=&AVScity=& AVSstate=&AVSzip=
I found it in my browser history after making an online payment for a BC Hydro electricity bill. And yes, you’re not mistaken. That URL has my account number, name, email address, credit card number, credit card expiration date and CVV number all embedded in it. (Yes, I did change them before blogging about this 🙂
Honestly, this has got to be one of the biggest, dumbest security mistakes I’ve seen in ages. I mean, really? Just toss all my credit card information into my browser history in clear text? Then let Google, Apple, or Mozilla sync it to all my devices and to the Cloud – so anyone can access it anywhere – brilliant!
What’s more, clicking on that URL submits another payment directly to their system. Go ahead – click on it! You know you want to! If the numbers were still correct, you’d rack up hundreds of dollars in charges to my credit card with just a few clicks of your mouse. How do I know? Because I mistakenly did that.
The Bottom Line
Kubra, the company behind this ridiculous little payment gateway, was absolutely no help when I called. They can’t refund the payments, including their own $2 “convenience fee” – they told me to dispute the charges with my credit card company instead. And when I asked them to address the underlying security flaw, they said they couldn’t do anything without a request from BC Hydro. So I’ve contacted BC Hydro through their web site. If you’re a BC Hydro customer, I encourage you to complain to them too – and NOT pay your power bill online until they get this resolved.
And if you’ve paid a bill via Kubra in the past, go check your browser history and see if your credit card or bank information is conveniently stored there for you (and everyone else). If it is, it might be a good idea to delete it 😉
That’s Cool! How Do I Get an URL Like That?
If you’ve got a BC Hydro account, you can see this for yourself. Go to http://www.bchydro.com/ and log into your account. Click on “Ways to Pay,” then “Online banking or credit card payment,” then “Kubra” as shown below.
You’ll get a data entry screen like this. Just fill in your credit card data, click “Submit”, and then confirm your payment on the next page. Then copy the URL in your browser’s address bar or from your browser history. There you go!
* Unfortunately, you do have to enter valid credit card and account information into this window to get back a valid URL. Otherwise you just get an URL filled with error message information – not nearly as fun.
I just got a call from BC Hydro – kudos to them for moving so quickly! It’s been a mere few hours since they read the email I sent them over the weekend and they’re already moving on it.
Impressive! Kubra just called and they’ve plugged the hole on their end (it looks like the switched from HTTP GET requests to HTTP POST) so the data no longer ends up in the URL. They’re also refunding the erroneous charges caused by me going to those URLs in the first place.
So the problem is fixed! The only issue that remains: If you’re a BCHydro customer and have paid your bill online in the past, search your browser history for “BCHydro” and delete any history items that match. (That’s something that you have to fix – BCHydro and Kubra can’t erase data that’s already on your computer).
Tuesday, March 20th, 2012
Friday, November 6th, 2009
So, Apple added this cool little capability to the Launch Services API in Leopard: LSSharedFileListAddObserver will call your observer function whenever there are changes in a number of different file lists maintained by Launch Services. One of those lists is the “Recent Documents” list in the Apple Menu. “Great!” I thought, “I’ll roll this into Default Folder X to ensure that it doesn’t miss any recently used folders.” It’s a simple API – what could go wrong? As a long time developer, I should have known better – if you EVER say this (even if you never even say it out loud), you need to poke yourself with something sharp and realize that the consequences will probably hurt quite a bit more than that. “What could go wrong?” indeed.
So yes, here I am apologizing for not having poked myself after I used LSSharedFileListAddObserver without asking more questions – or at least without testing more. Here’s how Default Folder X ended up using 60% of some users’ CPUs while doing nothing useful:
- DFX added itself as an observer for kLSSharedFileListRecentDocumentItems.
- The observer function got called by Launch Services because the user double-clicked a document in the Finder.
- DFX looked at the list, took the most recent entry in it (the first one), asked Launch Services for the URL of the document, and added the folder enclosing that document to its Recent Folders list.
Pretty simple, right? Yeah, I thought so too. This was tested thoroughly on Snow Leopard and performed fine, and all my Leopard testers reported that it worked well for them too.
So what’s the problem then? Well, there’s this little “issue”… If a user has a Windows server mounted on the Desktop, things get a little more interesting. Normally, when Launch Services calls your observer function, it hands you the file list and you ask for a copy of the list. The list itself is just a series of ID’s and references – to see what’s in an entry, you have to call LSSharedFileListItemResolve(). And that’s where the interesting part happened. On Leopard, if the shared file list item lies on a Windows server, the act of calling LSSharedFileListItemResolve actually results in the item being changed, so your observer function gets called again the next time you hit your event loop. The result of this is that you get called over and over again if you naively use LSSharedFileListItemResolve to get more info about the items that Launch Services is handing you.
So – the warning: If you use LSSharedFileListAddObserver to watch the list of recent documents, keep a copy of the ID’s from the previous call and ONLY call LSSharedFileListItemResolve if there’s a new ID in the array. Otherwise do nothing, or work off cached information – otherwise you’ll end up in an infinite loop, sucking down lots of CPU time. And if you’re doing anything that interacts with the filesystem, make SURE you test with SMB shared volumes too.
Wednesday, September 16th, 2009
Contextual menu plugins are dead in Snow Leopard, replaced by the revamped Services system. A user recently contacted me because he wanted to replicate the “Move Items” contextual menu item he used to use in Leopard. He had used Automator to create a service, but was having a few problems, namely that Default Folder X wasn’t available when he chose the destination folder.
This got me to open up Automator in Snow Leopard and take a crack at it myself. In the process, I was reminded how cool Automator is 🙂 At any rate, here’s the automator script I put together:
So you’re obviously asking: Why go to the trouble of creating variables instead of just using the “Move Finder Items” action by itself? I’m glad you asked! The reason is that I want to bring up a file dialog to specify the folder where I want the items to go. There’s not a clean way to have the “Move Finder Items” do that every time. You can change its options to “Show this action when the workflow runs” but you still have to click on it every time you use it to ask it to show a file dialog. If you use Default Folder X to enhance your Open dialogs, it’s faster to just have the dialog pop up and then go where you want to with DFX.
So in the image above, the workflow puts the current Finder selection into the “selection” variable. Then it uses AppleScript to bring up a file dialog to ask for a folder, which it stores in the “path” variable. And finally, it uses the Move Finder Items action to do the work. Not too much more complicated, and it speeds up your workflow considerably if you’ve already got DFX installed so the Open dialogs are smart.
For you automator programmers, note that some of the actions shown in the workflow do not take inputs. I did this by control-clicking on the action (“Get Value of Variable”, for example) and choosing “Ignore Input” from the contextual menu. If you don’t do this, Automator will actually add the input from the previous step to the next one, which is definitely not what you want in this case.
Oh, and if you just want the automator workflow file so you can add it to your own system, you can download it here:
If you need more help with Automator and Services, Apple has some good information and tutorials here:
(Once you’ve gotten through the first few steps of the tutorial, you should be able to just replicate the picture above to make the Move Items service yourself).