Re: JWTs, PURCHASE_CANCELED - android-pay

Having trouble with the PURCHASE_CANCELED error in Wallet for Digital.
A. I can successfully round-trip JWTs between
https://sandbox.google.com/checkout/customer/gadget/inapp/demo.html
and
https://developers.google.com/commerce/wallet/digital/docs/jwtdecoder
...of course I can, they're both Google tools.
B. I can successfully pass from PyJWT to the decoder, seems no info changes.
C. I can successfully pass from the demo to PyJWT, seems no info changes.
D. The request in the .buy() failure callback is correct.
This is extremely frustrating, to have no feedback from Google Wallet when it does PURCHASE_CANCELED.
I cannot make identical JWTs between PyJWT and the demo encoder. Even with exactly similar data in exactly the same order, the result varies at the end of the long string. Does this matter?
Is there any way of independently generating the signature (encoded) to verify against?
Does the order of keys in the object to encode matter?
Edit:
In the Order History, Wallet says "Google has sent the customer an order confirmation email." No emails arrive to my test buyer.
Also in the Order History, Wallet says "The customer's credit card was authorized for $3.00, and passed all risk checks". Looks promising.
I remember reading that, in the Sandbox, no banking or tax info is necessary. However, Google Books held me up for months on "selling" a $0 (free) book in Google Play due to lack of banking/tax information; without it, the book never made it through the approval process, no other explanation given. Does the Sandbox need even fake/placeholder information to allow .buy() transactions to proceed?

Flow is now working, postbacks are appearing at the server.
Estimated delay was 5-6 hours between sandbox setup and start of postback activity.
No changes made within sandbox tax/banking info.

Related

Stripe token - why isn't data-amount included in the token

I've been playing with stripe recently and while i fully understand that the token hides the clients credit card details from the server. This tutorial suggests that the server should not rely on the data-amount since it can be changed by the client
Don’t Rely on the Form’s Price
A frequent mistake stems from using form data to contain the price of
the product being purchased, possibly via a hidden input. Because a
user can easily edit this input’s value, it’s unwise to depend on it.
Always fetch the price of the product from the server-side. Never rely
on the form to tell you. A simple database query is the preferred option.
Can someone explain to be why stripe does not include the data-amount value as a parameter in the token generation? Is there not a potential for a server side code to change the agreed price and overcharge the client.
The token is a placeholder of a pending charge, it does not know how much you are going to charge yet. Once you are ready to charge the card an api request will be sent to Stripe along with the token. The concern about the amount deals with relying on POST data from a form that can be manipulated by the customer.
Its up to you to set the charge amount. For example a hotel could authorize $100 to spend the night but then at check out discover that you used the minibar and then charge $150. Or the auto calculated shipping is off so when you actually purchase the shipping its $5 less and you decide to charge $5 less than your auth.
What you should be doing is calculating the amount to charge the customer, save it via a shopping cart like function in your DB (or serverside somehow) sending the checkout form to the customer then using the previously calculated amount run the auth then the charge.
Form data can easily be changed by the end user. Just open the page and right click (in chrome) and click inspect element. You can then arbitrarily change form data. So if you were using that, the user could set the price to $.01 for your $1,000.00 product.
The propose of tokenization in the PCI world is to keep sensitive data off your servers. Otherwise you would collect the PCI data yourself then send the amount off to the processor along with the PCI data. By not ever having the sensitive data touch your systems you save a ton of money and headache in PCI compliance. See this 115 page document: https://www.pcisecuritystandards.org/documents/PCI_DSS_v3-1.pdf
Hope that helps, Please comment and I'll try to help further if it doesn't.

Can SagePay's callback be validated to prevent hacking?

SagePay's form callback can be hacked by re-using the success URL that the user is directed to upon a successful transaction. This can create all sorts of problems with duplicate transactions, fake transactions etc.
You can check for a duplicate VPSTxId, but these can be generated anew by hacking around the crypt parameter of the callback URL.
The crypt parameter can also be manipulated to generate a different "Amount" field.
I have not tested what other field values can be changed by hacking the callback URL crypt parameter.
Is there any way (as per PayPal's IPN validation) of doing a double-check callback to SagePay to ensure that the transaction is new and unique?
Thanks for your post. In general we encourage clients to use Server integration where they can. We also constantly monitor transactions for suspicious behaviour and proactively contact our customers if we suspect any malicious activity.
We recommend customers make sure that they’re using the latest version of our integration protocol which is currently v3. Get the latest integration documents.
As Dan suggests you could use the Reporting and Admin API to validate that a transaction does indeed exist on the Sage Pay side but having an additional validation mechanism (like PayPal's IPN) is something we will actively explore.
If you'd like us to update you on this, then please get in contact with our customer services team at support#sagepay.com or 0845 111 44 55.
Sage Pay Support
You should always redirect a user from a success URL.
I personally use a fulfil page (success url), and a thank you page. On the fulfil page, you should obviously only ever process a transaction once (based on the transaction id), and you can store crypt sent with a transaction. The crypt will have to be valid and is only possible to encrypt if you have the encryption key.
So hacking would be extremely difficult unless you are being very security lax, and the hacker would have to know your encryption key to even begin trying to hack it.
Alternatively, you should use the server integration, so that the communications are server-server, not client-server. There is little difference between form and server.
10 immutable laws of security
http://technet.microsoft.com/library/cc722487.aspx

What is a simple and secure way to transmit a login key from one website to another while redirecting a user?

I want to create a portal website for log-in, news and user management. And another web site for a web app that the portal redirects to after login.
One of my goals is to be able to host the portal and web-app on different servers. The portal would transmit the user's id to the web-app, once the user had successfully logged in and been redirected to the web app. But I don't want people to be able to just bypass the login, or access other users accounts, by transmitting user ids straight to the web app.
My first thought is to transmit the user id encrypted as a post variable or query string value. Using some kind of public/private key scenario, and adding a DateTime stamp to key to make it vary everytime.
But I haven't done this kind of thing before, so I'm wondering if there aren't better ways to do this.
(I could potentially communicate via database, by having the portal store the user id with a key in a database and passing that key to the web app which uses it to get the user id from that database. But that seems crazy.)
Can anyone give a way to do this or advice? Or is this a bad idea all-together?
Thanks for your time.
Basically, you are asking for a single-sign-on solution. What you describe sounds a lot like SAML, although SAML is a bit more advanced ;-)
It depends on how secure you want this entire thing to be. Generating an encrypted token with embedded timestamp still leaves you open to spoofing - if somebody steals the token (i.e. through a network sniffing) he will be able to submit his own request with the stolen token. Depending on the time to live you will give your token this time can be limited, but a determined hacker will be able to do this. Besides you cannot make time to live to small - you will be rejecting valid requests.
Another approach is to generate "use once" tokens. This is 'bullet proof' in terms of spoofing, but it requires coordination among all the servers within the server farm servicing your app, so that if one of them processed the token the other ones would reject it.
To make it really secure for the failover scenarios, etc. it would require some additional steps, so it all boils down to how secure you need it to be and how much you want to invest in building it up
I suggest looking at SAML
PGP would work but it might get slow on a high-traffic site
One thing I've done in the past is used a shared secret method. Some token that only myself and the other website operator knows concatenated to something identifying the user (like their user name), then hash that with a checksum algorithm such as SHA256 (you can use MD5 or SHA1 which usually are more available but they are much easier to break)
The other end should do the same thing as above. Take the passed identifying information and checksum it. Compare that to the passed checksum, if they match the login is valid.
For added security you could also concat the date or some other rotating key. Helps to run SSL on both sides as well.
In general, the answer resides somewhere in SHA256 / MD5 / SHA1 plus shared secret based on human actually has to think. If there is money somewhere, we may assume there are no limits to what some persons will do - I ran with [ a person ] in High School for a few months to observe what those ilks will do in practice. After a few months, I learned not to be running with those kind. Tediously avoiding work, suddenly at 4 AM on Saturday Morning the level of effort and analytical functioning could only be described as "Expertise" ( note capitalization ) There has to be a solution else sites like Google and this one would not stand the chance of a dandelion in lightning bolt.
There is a study in the mathematical works of cryptography whereby an institution ( with reputable goals ) can issue information - digital cash - that can exist on the open wire but does not reveal any information. Who would break them? My experience with [ person ]
shows that it is a study in socialization, depends on who you want to run with. What's the defense against sniffers if the code is already available more easily just using a browser?
<form type="hidden" value="myreallysecretid">
vis a vis
<form type="hidden" value="weoi938389wiwdfu0789we394">
So which one is valuable against attack? Neither, if someone wants to snag some Snake Oil from you, maybe you get the 2:59 am phone call that begins: "I'm an investor, we sunk thousands into your website. I just got a call from our security pro ....." all you can do to prepare for that moment is use established, known tools like SHA - of which the 256 variety is the acknowledged "next thing" - and have trace controls such that the security pro can put in on insurance and bonding.
Let alone trying to find one who knows how those tools work, their first line of defense is not talking to you ... then they have their own literature - they will want you to use their tools.
Then you don't get to code anything.

How can you prevent Man in the Browser attacks?

Been reading up on MitB attacks and some things worry me about this.
From WIKI:
The use of strong authentication tools simply creates an increased level of misplaced confidence on the part of both customer and bank that the transaction is secure.
One of the most effective methods in combating a MitB attack is through an Out-of-Band (OOB) Transaction verification process. This overcomes the MitB Trojan by verifying the transaction details, as received by the host (bank), to the user (customer) over a channel other than the browser
So if I get this straight, that the only real safe method is a non browser confirmation method. (like a phone call or some other external tool)
Would an email count as a OOB Transaction? Or could the MitB send a fake email?
Is there a way to prevent MitB with only code?
EDIT: I'm asking this because our local banking system are employing a physical keygen system for which you have to push to get a number and then enter that number into a field in the transaction form.
I have no idea if that is considered safe, since it looks like a MitB attack is just making it look like everything you did is safe and correct but what actually happened is that the form data was changed on submit and is now transferring to some other bank account. So it would have access to this keygen number.
Would an email count as a OOB Transaction?
Given the prevalence of Web mail services like GMail, I would say No. Even if the target of such an attack isn't using Web mail, an attacker that has control of the target's browser could fire off a fake email, just as you suggest.
Generally speaking if your machine is infected then you are vulnerable no matter what.
A physical token or "out of band" token is designed to solve the "identity" problem and gives the bank higher confidence that the person logging in is the person they say they are. These sort of mechanism normally involve using a "one time code" technique so that even if someone is recording the conversation with the bank, the token can't be reused. However if the malware is intercepting in real-time then they can maliciously control the account after you have successfully logged in, but often banks require a new 'code' each time you try and do something like transfer money out of the account. So the malware would have to wait for you to do this legitimately and then modify the request. However most malware are not real-time and send data to a 3rd party for collection and later use. Using these "one time token" techniques would successfully defend against this post processing of the login data, because the recorded data can't be used later to login in.
To answer your question, there is no way to defend against this only in code. Anything you do could be specifically worked around in a piece of malware.
In the article which is the subject of (and referenced by) that Wikipedia article, step 1 in the "Method of Attack" is stated as:
The trojan infects the computer's software, either OS or Application.
The answer to your question is therefore "no": once the O/S is infected then the malware can (theoretically at least) be intercepting your email too.
As an aside, some client platforms (e.g. even mobile phones, not to mention dedicated point of sale terminals) are less susceptible to infection than others.
I suppose you could use critical pieces of the transaction information as part of a secondary or tertiary transaction verification step. That is, if I thought I told the bank account #12345 and it heard #54321 because the data was adulterated by that type of attack, the secondary verification would fail the encryption check. It would also be possible for the bank to echo back something that was more difficult to alter, like an image containing the relevant information.
The thing about these types of discussions is that it can always get more complicated. Email is not valid out of band step because, I have to imagine I have a rootkit ... if I stop that, I have to imagine that my OS is actually a guest OS running in an evil virtual machine ... if I stop that, I guess I have to imagine it's the matrix and I can't trust anything all to protect my visa card with $200 of available credit. :)
This is my point of view for the man in the browser. The man in the browser is as if:
The victim stands up, leaves his computer, and move his back to his computer, so he can not touch the keyboard, move the mouse or even see the screen.
A hacker sits behind victim computer.
If victim wants to work with his computer he must ask the hacker to do it for him. If he wants to see any result, he must ask the hacker to read the data on the monitor.
The hacker does his best to convince the user that he is doing what he asks for and repeats what he seas. But try to make the benefit of this situation with no mercy !
As a simple case:
Victim may ask hacker to fill a transaction form data as transfer 500USD to mom.
The hacker instead can type transfer 10000USD to Jack. ( Tamper form data before send)
The system may display, I have transferred 10000USD to Jack but the hacker says that the 500USD has transferred to Jack. ( Tamper result HTML)
The victim asks to see his account balance, to make sure that the transfer is done.
The hacker can say that the the account balance in correct ( This can be done for example, by removing the last line of balance table and changing the balance amount in HTML)
As for email:
You are waiting for an email, and ask hacker do I have a confirm email from bank.
As you can not see the monitor, he say yes you have. (Technically he can generate a fake email easily).
(even if you sit on another clean computer, a fake email can be sent to you again)
The image generation can not prevent attack.
You ask the hacker, my bank should shows me an image which must display the transfer information, could you see it, what does it says.
The hacker reply: Yes I can see it, it says "You are transferring 500USD to mom" (The image can easily created by the JavaScript or hacker can point the image url to a server, which generates a dynamic image with appropriate data to cheat user)
The very dangerous situation may happens as the man in the browser change the flow of the site. In this case even an OTP or kegen system can not prevent the attack. For example:
You ask hacker that you want to see your balance
The hacker goes to transfer account page, and fill a transfer account form to transfer 10000USD to jack ( but you don't know what is he doing at all, you are just waiting) he come to a page that asks him for a key. This is the key you which you must give him.
Now, the hacker says : Well, the bank ask me if you want to see your balance you must enter a key.
You think, well a key for balance seems strange, but any way lets give that key, I trust this guy !!
The hacker switch back to transfer form and use the key to do the transfer.
So as you can see there is no server side solution for a Man in the browser you can:
Use a out of the band solution to inform critical information to user. ( This is as if you take a mobile in your hand and although your back is still to your computer but sensitive information are sent to your TRUSTED device and you can see critical information)
Use a hardened browser to make sure that no one can change its behavior. ( Sit back to your computer :) )
Good samples of what can be done by MITB can be found at: http://www.tidos-group.com/blog/2010/12/09/man-in-the-browser-the-power-of-javascript-at-the-example-of-carberp/

Security review: client credit card# stored on server but with one time pad encryption stored in client cookie

I'm writing a system where, as usual, the client is asking for a convenience "remember your credit card details" option.
I've told them that this is in all likelihood a no-go. However, I did have a good idea (tm) just now, and seeing that Good Ideas in Encryption(tm) are actually Bad Ideas (tm), I thought I'd put it up for review here and see what holes can be punched through it.
Essentially, I'm thinking of xor'ing the credit card information plus some message signature using a one time pad that's generated per client. This pad is stored as a cookie variable on the client's browser.
Next time that user tries to place a purchase, the pad is sent to the server, and if the server can properly decode its encrypted data, it shows the credit card information as already being filled. (The cc info isn't actually transmitted back). The server will never store the pad in anything more than memory or page file. In fact, I intend to have the pad be sent twice: once upon arrival on the CC page (where the server checks if it should ask for CC information), and once on CC submission to get the actual information.
The user will also be instructed that their information is "partially stored" in their cookie cache, meaning that they will expect that if their cookies are flushed, their CC information is lost.
Let me know where you think this scheme is horribly failing.
Sounds sketchy, and I'm pretty sure you're misusing the term "one time pad."
Instead of going this route, look into using a service like Authorize.net's Customer Information Management. Basically, you give them the card info, and they give you back an ID that you can use to charge the card. The ID is linked to the website's merchant account, and can't be used to charge the card with any other merchant.
It's much, much safer, and should get you the same results.
Note: I'm not endorsing Auth.net or its CIM. It's just the example I'm most familiar with.
Storing the pad client-side leaves it vulnerable to XSS, I would think.
Technologically: flawed.
Legally: probably flawed. talk to a lawyer.
A one time pad only works if the pad is securely kept secret. Storing it in a cookie definitely doesn't count as secure or secret (it's sent to and from the server, it's dropped onto the user's machine, which might be a public terminal or shared machine). This is a really bad idea. It's a clever idea but ultimately very flawed. I suggest you read the PCI compliance documentation and do what other people do which is (generally speaking):
Don't do it.
Use a payment processor that will securely store the CC and handle billing (i.e. PayPal).
Setup a separate and strongly secured payment gateway, this machine only processes credit card transactions, and it in turn accesses a secured machine that stores the credit card data.
Remember that storing credit card numbers will basically violate PCI and will probably violate any merchant agreements and might even be illegal in your jurisdiction (privacy laws, etc.), consult a lawyer please.
Don't do it. Seriously. Find a payment processor who will handle this for you.
If the credit card is being stored client side then you're storing it with the key which means it's vulnerable.
If you are storing the credit card server side then you don't need a key of an encryption key stored on the client.
It sounds like a very dangerous situation if what you are describing is a case where the user is not only not being given the option whether or not they want to store their details but is also going to have them re-populated without having to authenticate in any way. I'd be pretty happy if I came along to an internet cafe and got the credit card details fields pre-populated for me!

Resources