iamraphson / vue-paystack

Paystack Vue Plugin for Vue 2.X
https://www.npmjs.com/package/vue-paystack
MIT License
119 stars 45 forks source link

May be security issue? #7

Closed shirshak55 closed 5 years ago

shirshak55 commented 5 years ago

Our components are available on client side

 <paystack
        :amount="amount"
        :email="email"
        :paystackkey="paystackkey"
        :reference="reference"
        :callback="callback"
        :close="close"
        :embed="false"
    ></paystack>

say the item is of 100 Naira and using devtools or anything i changed it to 10 Naira.

Now there are two scenario 1. Using 10 Naira i purchased the item loss to website is 90Naira and hacker are enjoying . If large commercial site it is even worst

2. Server may validate that item was 100 Naira but user paid 90 Naira. Now hacker will say they were charged but didn't receive and would settle with site owner. Site owner have to give them 10 naira and would have to deal with settlement fees etc.

Both side hacker won admin loss :(

iamraphson commented 5 years ago

@shirshak55 Thanks for this. How do you suggest we go about this?

shirshak55 commented 5 years ago

@iamraphson its not your fault :D

Its paystack fault :( . I emailed them but they don't give a damn. So i started using their transaction feature .

Have you checked stripe. They give option to charge via backend but paystack ...

shirshak55 commented 5 years ago

You can keep message like its paystack end problem not this package so new user can know consequence .

iamraphson commented 5 years ago

@shirshak55 Paystack gives options for backend charges. you can see a lot of backend libraries here - https://developers.paystack.co/docs/libraries-and-plugins. Nevertheless, it's advisable to validate the transaction again at the back using reference cc @PaystackHQ

shirshak55 commented 5 years ago

@iamraphson

backend charge is not good bro . User should know who is charging them like paystack or website. It clearly some complaints. From the information i know user credit card information should never touch your server so you even remove name field from credit card form.

See, you and I am customer to some site. If there is credit card form will you fill if you know it is related to that site. We only fill if we sure know that credit card form is from paystack because we trust paystack but not that site.

Thats why stripe also made credit card form, pop up form.

So for now transaction is good but this damn paystack transaction requires me to redirect to paystack site come back to my own site and using that token send to server and validate everything .

And their webhook is not even so testable. They don't provide like sending test webhook from their site. :( Really dissatisfied with their api development :(

steveamaza commented 5 years ago

Hello @shirshak55,

If you are worried about vulnerabilities, you can

  1. Create your own form where Paystack provides a token for charging https://developers.paystack.co/v2.0/docs/paystack-custom

  2. Create the transaction via the backend by calling the initialize endpoint (https://developers.paystack.co/v2.0/reference#initialize-a-transaction). A reference is returned to you which you can then use to start the transaction using popup by passing the reference to https://developers.paystack.co/v2.0/docs/paystack-popup

shirshak55 commented 5 years ago
  1. This point is invalid because it will charge customer immediately . So they change price from 50 to 10 and pay it. and they can try lot of things. We are at disadvantage.

  2. It is what i use currently. But it is like hell. First gather customer details, product details generate transaction link then redirect customer and after they fill we check token again.

  3. is not that bad but I cannot test webhook because paystack don't provide me way to test so that i cannot test app properly.

On Sat, Oct 20, 2018 at 9:56 PM Stephen Amaza notifications@github.com wrote:

Hello @shirshak55 https://github.com/shirshak55,

If you are worried about vulnerabilities, you can

1.

Create your own form where Paystack provides a token for charging https://developers.paystack.co/v2.0/docs/paystack-custom 2.

You can create the transaction via the backend by calling the initialize endpoint ( https://developers.paystack.co/v2.0/reference#initialize-a-transaction). A reference is returned to you which you can then use to start the transaction using popup by passing the reference to https://developers.paystack.co/v2.0/docs/paystack-popup

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/iamraphson/vue-paystack/issues/7#issuecomment-431595074, or mute the thread https://github.com/notifications/unsubscribe-auth/AHuOYbdytnX_oKaJov9tGKR080WV0nAYks5um0s9gaJpZM4XcY0u .

steveamaza commented 5 years ago

Hello,

  1. Customer cannot change this. Please check the documentation first.

  2. Paystack provides a way to test webhooks. Go to your Paystack Dashboard

    Settings > API Keys & Webhooks and you'll see a space for test webhook URL

On Sat, 20 Oct 2018, 17:42 Shirshak Bajgain, notifications@github.com wrote:

  1. This point is invalid because it will charge customer immediately . So they change price from 50 to 10 and pay it. and they can try lot of things. We are at disadvantage.

  2. It is what i use currently. But it is like hell. First gather customer details, product details generate transaction link then redirect customer and after they fill we check token again.

  3. is not that bad but I cannot test webhook because paystack don't provide me way to test so that i cannot test app properly.

On Sat, Oct 20, 2018 at 9:56 PM Stephen Amaza notifications@github.com wrote:

Hello @shirshak55 https://github.com/shirshak55,

If you are worried about vulnerabilities, you can

1.

Create your own form where Paystack provides a token for charging https://developers.paystack.co/v2.0/docs/paystack-custom 2.

You can create the transaction via the backend by calling the initialize endpoint ( https://developers.paystack.co/v2.0/reference#initialize-a-transaction). A reference is returned to you which you can then use to start the transaction using popup by passing the reference to https://developers.paystack.co/v2.0/docs/paystack-popup

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub < https://github.com/iamraphson/vue-paystack/issues/7#issuecomment-431595074 , or mute the thread < https://github.com/notifications/unsubscribe-auth/AHuOYbdytnX_oKaJov9tGKR080WV0nAYks5um0s9gaJpZM4XcY0u

.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/iamraphson/vue-paystack/issues/7#issuecomment-431597587, or mute the thread https://github.com/notifications/unsubscribe-auth/APG0O_L72wViGC9KB3xGOOF3zPMhiZ4yks5um1KSgaJpZM4XcY0u .

shirshak55 commented 5 years ago

@steveamaza cannot people change frontend code?

shirshak55 commented 5 years ago

@steveamaza yes i know that test webhook but how can i fire it? There should be some provision to fire it. I know if we purchase item we can fire it but it really not the way to fire the webhook. Can you check stripe they have a dedicated part for just firing test webhook.

shirshak55 commented 5 years ago

@steveamaza You are mistaking me by 1 no I mean this one

https://developers.paystack.co/v2.0/docs/paystack-custom

By 2 number i mean this https://developers.paystack.co/v2.0/reference#initialize-a-transaction

1 number can be changed by customer

shirshak55 commented 5 years ago

@iamraphson don't you think customer can change No 1?

steveamaza commented 5 years ago

@steveamaza yes i know that test webhook but how can i fire it? There should be some provision to fire it. I know if we purchase item we can fire it but it really not the way to fire the webhook. Can you check stripe they have a dedicated part for just firing test webhook.

Thank you for the feedback @shirshak55. We will make this update in the nearest future.

shirshak55 commented 5 years ago

is there any way to do no 1 without risk?

On Sun, Oct 21, 2018, 4:22 PM Stephen Amaza notifications@github.com wrote:

@steveamaza https://github.com/steveamaza yes i know that test webhook but how can i fire it? There should be some provision to fire it. I know if we purchase item we can fire it but it really not the way to fire the webhook. Can you check stripe they have a dedicated part for just firing test webhook.

Thank you for the feedback @shirshak55 https://github.com/shirshak55. We will make this update in the nearest future.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/iamraphson/vue-paystack/issues/7#issuecomment-431657689, or mute the thread https://github.com/notifications/unsubscribe-auth/AHuOYXfG_9DRi3ZQTr9k0k_rTeA-h6uGks5unE5UgaJpZM4XcY0u .

steveamaza commented 5 years ago

Hello @shirshak55, your best bet is the second option. However, you can do the first one as advised with minimal to no risk

shirshak55 commented 5 years ago

@steveamaza how to do no 1 without no risk. I am using no 2 which i am unsatisfied because customer has to do more 👍

AustineA commented 5 years ago

There is no security whatsoever, you need to verify payment in your backend before you give value.

shirshak55 commented 5 years ago

@AustineA Ok but even if u verify ur user gonna get charged and they will complain. If u take user money without delivering him items/service u are regarded as fraud :)

U cannot take user's money no matter what they do and if u take u must give the value . Paystack is clearly doing nothing and I also don't care anymore :)

shirshak55 commented 5 years ago

@iamraphson if u think this is not a security issue feel free to close.

steveamaza commented 5 years ago

Hello @shirshak55 , we have gone over this. There are multiple options for you to achieve what you need.

You said "Have you checked stripe. They give option to charge via backend but paystack ..." and Segun mentioned that you can charge from backend and you said that isn't good.

I have also provided two options where you can charge securely. Can you kindly explain how you want to go about this?

Also like @AustineA mentioned, you need to verify the transaction. You can issue a refund via our API if the amount does not match up

shirshak55 commented 5 years ago

@steveamaza we are taking about this plugin and regarding that you only gave workaround not a solution.

"You said "Have you checked stripe. They give option to charge via backend but paystack ..." and Segun mentioned that you can charge from backend and you said that isn't good."

I was taking this in popup form not that one that we need to open a paystack page and redirect back to our page. That popup paystack is good buy you guys are dening the fact that this is bug in ur implementation. Even people can change from devtools and buy it com'n its not 90's and even kids can do this.

And regarding refund... Do u give refund without causing us loss?

By the way I have don't use paystack any more so I wont complain from now but user need to be aware of this . Due to this implementation I find most of the site that use paystack popup are vulnerable to this. I tried with one site and it worked so I don't feel any safe it with anymore.

Thanks.

steveamaza commented 5 years ago

Yes, for popup, it is possible to have the interface and still have security. This is what I explained in the second option for https://github.com/iamraphson/vue-paystack/issues/7#issuecomment-431595074. Though you are initializing the transaction from the backend, the customer will still be able to pay via topup. You are only intializing from the backend to get a reference which contains the amount to be paid and this cannot be changed by the customer since the details are already on our server from when you intialized

shirshak55 commented 5 years ago

see this is what u are saying?

var submitFunction = async function(event) {
  var transactionData = {
    email: "",
    amount: 100,
    key: ""
  };

  var transactionResponse = await Paystack.transaction.request(transactionData);

  var transaction = new Paystack.Transaction(transactionResponse);

  var card = new Paystack.Card({
    number: "4084084084084081",
    cvv: "408",
    month: "12",
    year: "20"
  });

  console.log(card, "card");

  // Payment method instances usually provide validation functions
  if (card.isValid()) {
    // Set the payment method on the transaction
    transaction.setPaymentMethod(Transaction.PaymentMethods.CARD, card);
  }

  // Charge the payment method
  const chargeResponse = await transaction.card.charge();

  // Handle the charge responses
  if (chargeResponse.status === "success") {
    alert("Payment completed!");
  }

  // Another charge response example
  if (chargeResponse.status === "auth") {
    const token = 123456;
    const authenticationResponse = await transaction.card.authenticate(token);
    if (authenticationResponse.status === "success") {
      alert("Payment completed!");
    }
  }

  event.preventDefault();
};

var form = document.getElementById("paystack-card-form");

form.addEventListener("submit", submitFunction, true);

This is frontend code right? meaning i can change this easily

  var transactionData = {
    email: "",
    amount: 100,
    key: ""
  };

And make it

  var transactionData = {
    email: "",
    amount: 1,
    key: ""
  };
shirshak55 commented 5 years ago
Create your own form where Paystack provides a token for charging developers.paystack.co/v2.0/docs/paystack-custom

Create the transaction via the backend by calling the initialize endpoint (developers.paystack.co/v2.0/reference#initialize-a-transaction). A reference is returned to you which you can then use to start the transaction using popup by passing the reference to developers.paystack.co/v2.0/docs/paystack-popup

To make long story short and what we discussed from email u already said 2nd one is good and I agree too and it is not that convenient however we can use iframe etc. And please don't deceive user by saying no 1 is properly safe and secure .Paystack charges before and think server should verify the charge and what if server couldn't verify the charge WHat do we do that unverified amount ?

steveamaza commented 5 years ago

No @shirshak55 , that is not what I am saying. You can either use https://developers.paystack.co/v2.0/docs/paystack-custom (which is the first option I gave).

However, since you want to use the popup, you can initialize the transaction on the server, get a reference and use it to create a transaction using https://developers.paystack.co/v1.0/reference#paystack-inline-x.

Both are perfectly safe and secure

If you need more explanation on this, please send an email so we can get on a call where I can explain in more detail or answer any questions you might have. Thank you for choosing Paystack!

shirshak55 commented 5 years ago

@steveamaza wait can u give me any websites that uses ur first option. I would like to test couple of sites .

shirshak55 commented 5 years ago

@steveamaza what is code for for using reference send me instead of showing that docs as it is not clear.

Is this correct code?

<script>
  function payWithPaystack(){
    var handler = PaystackPop.setup({
      ref: ReferenceFromServer,
      callback: function(response){
          alert('success. transaction ref is ' + response.reference);
      },
      onClose: function(){
          alert('window closed');
      }
    });
    handler.openIframe();
  }
</script>

ReferenceFromServer variable will contain id that we get from server.

If this works than yes it is secure. But this vue-paystack package is not safe unless we ignore :)

nmeri17 commented 3 years ago

A very simple solution to this would be providing a method (paystack.open() should expose the payWithPaystack method) to programmatically trigger the paystack popup. In an ideal scenario, devs should verify transaction details before giving the front end the go-ahead to raise the popup. Your library should serve a functional purpose, not presentation (and by extension, controlling when modal appears).

Aside security concerns, I might have additional validation checks to perform before permitting user to pay.

I could imitate this behavior with $(".payButton").click() after verifying details, but it doesn't make any sense because script kiddie could as well run that from the console (WHICH IS CURRENTLY AN UNACKNOWLEDGED SECURITY SCARE). I would take off all selectors on that element, for a start. Next, I would refactor the method to be invoked by client instead of being triggered by an event i.e. by watching an raise_modal property the client updates once verification requirements are satisfied.

Alternatively, you could use custom events.

Please notify me when/if these fixes are being implemented so I can both update the package and my implementation. Cheers

nmeri17 commented 3 years ago

Yes, for popup, it is possible to have the interface and still have security. This is what I explained in the second option for #7 (comment). Though you are initializing the transaction from the backend, the customer will still be able to pay via topup. You are only intializing from the backend to get a reference which contains the amount to be paid and this cannot be changed by the customer since the details are already on our server from when you intialized

Really? If I still have to interface Paystack servers at my back end, what is the essence of a client side checkout? I might as well generate the reference and redirect to its checkout page in one fell swoop. Or, am I missing something?