-1

I am about to implement payments on a website.

I have seen solutions like using this Javascript code

function onBuyClicked() {
  if (!window.PaymentRequest) {
    // PaymentRequest API is not available. Forwarding to
    // legacy form based experience.
    location.href = '/checkout';
    return;
  }

  // Supported payment methods
  var supportedInstruments = [{
      supportedMethods: ['basic-card'],
      data: {
        supportedNetworks: [
          'visa', 'mastercard', 'amex', 'discover',
          'diners', 'jcb', 'unionpay'
        ]
      }
  }];

  // Checkout details
  var details = {
    displayItems: [{
      label: 'Original donation amount',
      amount: { currency: 'USD', value: '65.00' }
    }, {
      label: 'Friends and family discount',
      amount: { currency: 'USD', value: '-10.00' }
    }],
    total: {
      label: 'Total due',
      amount: { currency: 'USD', value : '55.00' }
    }
  };

  // 1. Create a `PaymentRequest` instance
  var request = new PaymentRequest(supportedInstruments, details);

  // 2. Show the native UI with `.show()`
  request.show()
  // 3. Process the payment
  .then(result => {
    // POST the payment information to the server
    return fetch('/pay', {
      method: 'POST',
      credentials: 'include',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(result.toJSON())
    }).then(response => {
      // 4. Display payment results
      if (response.status === 200) {
        // Payment successful
        return result.complete('success');
      } else {
        // Payment failure
        return result.complete('fail');
      }
    }).catch(() => {
      return result.complete('fail');
    });
  });
}

document.querySelector('#start').addEventListener('click', onBuyClicked);

but this code being in Javascript is completely visible to anyone looking at the page source.

And more, suppose I want to store a successful purchase to my server. The post will be visible.

Isn't this a security risk?

Is there any way to protect this?

Duck
  • 34,902
  • 47
  • 248
  • 470
  • The `JavaScript` code being "visible" is not making things insecure. I suggest you familiarize yourself and read up on security of the `Payment Request API` itself - https://developers.google.com/web/ilt/pwa/introduction-to-the-payment-request-api to better answer your question how secure this approach is. It is still up to the backend server to determine whether the request is legit or not - you should **never** be relying on just the frontend code when it comes to security. – goto Apr 28 '20 at 18:44

2 Answers2

1

Isn't this a security risk?

Only if the server-side code believes the costs submitted from the client without checking them.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • what I mean is this: a successful purchase happens, I am posting that to my database. Everything is plain visible. – Duck Apr 28 '20 at 18:40
  • @SpaceDog — Well don't. Check that the prices are right with server-side code. – Quentin Apr 28 '20 at 18:42
  • how do I do that if everything happens in javascript? See that `if (response.status === 200)`... – Duck Apr 28 '20 at 18:43
  • @SpaceDog not everything happens in `JavaScript` - I suggest you read up on integrating a payment system into a website, or better yet, use a service that will take care of security and other important things for you if you don't know what you're doing. If your server-side code is not secure and doesn't properly check validity of incoming requests, then it doesn't matter whether you see things on the front-end or not. – goto Apr 28 '20 at 18:47
1

As long as the JS code doesn't expose any credentials you should provide to your payment gateway, you are secure.

The example provided is built around the Payment Request eco system which is a native browser approach in collecting client's payment credentials.

If an attacker is to learn your payment method from the code, all the hacks he can do is limited to paying - which is good.

Charlie
  • 22,886
  • 11
  • 59
  • 90
  • ok, but if I post a successful purchase to the server in order to, for example, save that purchase on a database, a fake purchase can be staged by that... or at least the hacker can try to. Anyway, I see more clearly now. Now I have to imagine a way to store that information, I mean the result of such purchase, in a secure way on my server. Thanks. – Duck Apr 28 '20 at 19:19
  • When the server gets a payment request, the card information is sent to the payment processor. Once processed, the payment processor will hold the funds from the issuers(card) bank. At this point, the payment processor would send you a "success" reply - after which you can save the payment to the tables. Now, if an attacker wants to save arbitary records in your system, he needs a valid card with funds. – Charlie Apr 29 '20 at 02:49