I'm building an application that eventually needs to process cc #s. I'd like to handle it completely in my app, and then hand off the information securely to my payment gateway. Ideally the user would have no interaction with the payment gateway directly.
Any thoughts? Is there an easier way?
Most payment gateways offer a few mechanisms for submitting CC payments:
1) A simple HTTPS POST where your application collects the customer's payment details (card number, expiry date, amount, optional CVV) and then submits this to the gateway. The payment parameters are sent through in the POST variables, and the gateway returns a HTTP response.
2) Via an API (often XML over HTTPS). In this case your application collects the customer's payment details, constructs an XML document encapsulating the payment details, and then posts this information to the gateway. The gateway response will be an XML document which your application then has to parse and interpret.
3) Some form of redirect to web pages hosted by the payment gateway. The payment gateway collects the customer's CC number and other details, processes the payment, and then redirects the customer back to a web page hosted by you.
Option 3 is usually the easiest solution but would require the customer to interact with pages hosted by the gateway (although this can usually be made to be almost transparent).
1 and 2 above would satisfy your requirements with 1 being the simplest of the two to implement.
Because your preference is to have your application collect the payment details, you may need to consider whether you need to acquire PCI DSS compliance, but there are many factors that affect this. There is a lot of information about PCI DSS here and on Wikipedia.
That's something usual to do. Please follow the instructions your payment gateway gives you on how to send info to them, and write the code. If you have some issue, feel free to ask a more specific question.
You will probably find that it's easier to just let the payment gateway handle it. It's best to leave PCI compliance to the experts.
Related
After reading around it appears that trying to protect a publically accessible API (API used by an app/site that does not need a user to log in) appears to be fruitless, e.g. store key in app, user can reverse engineer app.
My question relates to how one can protect as much as possible and slow down abuse of a public accessible API...
Rate-limiting? Check request origin (although can be spoofed).... anything else?
Also if the site is SSR, could it just be protected by the server's IP?
YOUR QUESTIONS?
After reading around it appears that trying to protect a publically accessible API (API used by an app/site that does not need a user to log in) appears to be fruitless, e.g. store key in app, user can reverse engineer app.
Security is all about defense in depth, thus is all about adding as many layers as you can afford and required by law in order to mitigate the risk, therefore any defense you add it's one more layer that will prevent that simple/dumb automated scripts from accessing it, while at same time will increase the level of skills and effort necessary for an hacker poking around to overcome all defenses.
Rate-limiting?
This is kind of mandatory for any API to employ, otherwise an automated script can easily extract an huge amount of data in seconds. The more strict this rate limit is applied, the greater may be the chances for other layers of defense to detect that unauthorized access to the API may be happening and try to mitigate/block it. To bear in mind that the rate limits can be bypassed by adapting the attack to make requests that do not trigger it, and in some cases easily automated for that Software that give back in the response header the throttling values being applied.
Check request origin (although can be spoofed)....
Yest it is easily bypassed, but why not? It will be one more layer of defense that filters out some dumb automated scripts/bots.
Also if the site is SSR, could it just be protected by the server's IP?
No matter if a SSR site or any other type of app, when used from a mobile phone the IP address can change during the load of a page or mobile app screen, because when the phone switches between masters the IP will change. Also to bear in mind that in an office or public wifi all the users on it will have the same IP.
The use of it as a blocking measure on its own needs to be carefully evaluated, and normally requires fingerprinting the request in order to reduce the risk of blocking other valid users sharing the same network.
I would use it very carefully to avoid/block/throttle requests only when I could establish that hey are known bad IPs, that you can collect from your own requests history and/or from public datasets.
WHO IS IN THE REQUEST VS WHAT IS MAKING THE REQUEST
A common misconception around developers of any seniority is about not being aware that the who is in the request is not the same as what is making the request, therefore we will first clear it out...
The Difference Between WHO and WHAT is Accessing the API Server
While your API is not using user authentication is important to be aware of this distinction in order to better perform informed decisions around the security measures to be adapted in the API server.
I wrote a series of articles about API and Mobile security, and in the article Why Does Your Mobile App Need An Api Key? you can read in more detail the difference between who and what is accessing your API server, but I will quote here the main takes from it:
The what is the thing making the request to the API server. Is it really a genuine instance of your mobile app, or is it a bot, an automated script or an attacker manually poking around your API server with a tool like Postman?
The who is the user of the mobile app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.
The best way to remember the difference is to think about the who as the user your API server will be able to Authenticate and Authorize access to the data, and think about the what as the software making that request in behalf of the user.
DEFENDING THE API SERVER
My question relates to how one can protect as much as possible and slow down abuse of a public accessible API...
For Mobile APIs
For an API serving only mobile apps you can use the Mobile App Attestation concept as I describe in my answer to the question How to secure an API REST for mobile app?.
For Web APPs
For an API that only serves a Web app I would recommend you to read my answer to the question secure api data from calls out of the app?.
DO YOU WANT TO GO THE EXTRA MILE?
anything else?
It seems you already have done some research but you may not know yet the OWASP guides and top risks.
For Web Apps
The Web Security Testing Guide:
The OWASP Web Security Testing Guide includes a "best practice" penetration testing framework which users can implement in their own organizations and a "low level" penetration testing guide that describes techniques for testing most common web application and web service security issues.
For Mobile Apps
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.
OWASP - Mobile Security Testing Guide:
The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.
For APIS
OWASP API Security Top 10
The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.
Just for a quick answer
I can suggest at least one via solution which is to use an API Gateway (like Kong, Express Gateway or AWS API Gateway, etc.).
The API Gateway allows you to create API consumers (e.g: buyer mobile app, seller mobile app, buyer TV app). For each API consumer, an auth key (or even OAuth 2.0 credentials) will be generated and asigned respectively.
You then can use the auth key or OAuth 2.0 credentials (ID and secret) to access the APIs securely (even for the public ones, as API Gateways will only allow access from valid API consumers).
How about request from web?
You can configure API Gateway to detect requests from web and instead of using auth key or Oauth mechanism, it can use domain white-listing CORS protection mechanism.
How about user access token (generated from successful login)? Any conflict here?
IMHO (emphasized), after getting user access token (e.g: a JWT), for every authenticated-user-only requests you will send both API Gateway auth key token user auth access token. Referencing to Exadra's answer above, we can consider API Gateway key is to verify the "what" (mobile app) while user access token is to verify the "who" (login user).
I want to integrate Stripe, PayPal or Braintree into django project, and I want to use 'django-rest-framework`, now I'm confused about one thing and that is - Should I "touch" my database?
What I mean, I want only to charge once to my customers, it's a fee and nothing more, so should I touch 'db' or not? I'm afraid it will distort PCI Compile way of handling things. I don't know where to start beside documentation for those mentioned payments systems.
Can someone help me understand what are best practices for one time payment.
(Disclaimer: I'm a Stripe employee, so I'll only talk about Stripe here.)
Stripe makes it easy to be PCI compliant. With a proper integration, you will never have access to your customers' payment information.
A typical payment flow with Stripe can be divided in two steps:
Collect the customer's payment information, using the prebuilt Checkout form, or a form of your own using Stripe.js.
In both cases, the card information is sent directly from the customer's browser to Stripe's servers, which return a card token. You then send this token to your backend.
On your backend, you use the token to create a charge.
The token represents a card, but hides the PCI sensitive information (i.e. the whole card number and the CVC) from you.
You can find a simple tutorial for creating charges here.
If you don't plan on charging the same customer multiple times (or if you don't mind asking them to provide their card information every time), then you don't necessarily need to store anything in your own database. When you create the charge, you will be immediately informed of the result (success or failure) and can take the necessary actions.
I guess you solved the problem.
On top of that, I wanna add some information about PayPal payments when working a REST API(DRF) and a frontend server.
In this case, you can use both servers to work to secure your transactions, how?
The frontend server will take care of displaying the PayPal checkout buttons, and creating an Order in the Paypal Servers when the order has gone through. And the backend server will check the validity of the order created in the PayPal servers (using an order ID passed from the frontend after the payment has gone through), and update the database based on the PayPal response to that.
Now you could simply update your database when the payment is successful, but that would cause a security issue: people can send requests to update the database without even going through the payment.
Here is an illustration of this:
Full tutorial: https://www.kowe.io/projects/accept-paypal-payments-in-your-vuejs-and-drf-app/
I have already asked a question about IP Authentication here: TastyPie Authentication from the same server
However, I need something more! An IP address could be very easily spoofed.
Scenario: My API (TastyPie) and Client App (in javascript) are on the same server/site/domain. My users don't login. I want to consume my API in my javascript client side.
Question: How can I make sure (authentication) that my AJAX requests are originating from the same server?
I'm using Tatypie. I need to authentication that the requests from the client are being made on the same server/domain etc. I cannot use 'logged in sessions' as my users don't login.
I have looked at private keys and generating a signature but they can viewed in the javascript making that method insecure. If I do it in a way to request a signature form the server (hiding the private key in some python code) anyone can make the same http request to get_signature that my javascript makes, thus defeating the point.
I also tried to have the Django view put the signature in the view eliminating the need to make the get_signature call. This is safe, but means that I have to now refresh the page every time to get a new signature. From a users point of view only the first call to the API would work, after which they need to refresh, again pointless.
I cannot believe I'm the only person with this requirement. This is a common scenario I'm sure. Please help :) An example using custom authentication in Tastypie would be welcome too.
Thanks
Added:
Depending on your infrastructure #dragonx's answer might interest you most.
my 2c
You want to make sure that only if a client visits your website can use the api? Hmm does the bot, robot, crawler fall in the same category with the client then? Or am I wrong? This can be easily exploited in case you really want to secure it really.
I cannot believe I'm the only person with this requirement.
Maybe not, but as you can see you are prone to several attacks to your API and that can be a reason for someone not sharing your design and making security stricter with auth.
EDIT
Since we are talking about AJAX requests what does the IP part has to do with this? The IP will always be the Client's IP! So probably, you want a public API...
I would Go with the tokens/session/cookie part.
I 'd go with a generated token that lasts a little while and a flow described below.
I'd go with a limiter per some time, like Github does. Eg 60 requests per hour per ip or more for registered users
To overcome the problem with the refreshing token I would just do this:
Client visits the site
-> server generates API TOKEN INIT
-> Client gets API TOKEN INIT which is valid only for starting 1 request.
Client makes AJAX Request to API
-> Client uses API TOKEN INIT
-> Server checks against API TOKEN INIT and limits
-> Server accepts request
-> Server passes back API TOKEN
-> Client consumes response data and stores API TOKEN for further usage (Will be stored in browser memory via JS)
Client Starts Comm with the API for a limited amount of time or requests. Notice that you know also the init token date so you can use it to check against the 1st visit on the page.
The 1st token is generated via the server when the client visits.
Then the client uses that token in order to obtain a real one, that lasts for some time or something else as of limitation.
This makes someone actually visit the webpage and then he can access the API for a limit amount of time, requests perhaps etc.
This way you don't need refreshing.
Of course the above scenario could be simplified with only one token and a time limit as mentioned above.
Of course the above scenario is prone to advanced crawlers, etc since you have no authentication.
Of course a clever attacker can grab tokens from server and repeat the steps but, then you already had that that problem from start.
Some extra points
As the comments provided please close writes to the API. You don't want to be a victim of DOS attacks with writes if you have doubts about your implementation(if not use auth) or for extra security
The token scenario as described above can also become more complicated eg by constantly exchanging tokens
Just for reference GAE Cloud storage uses signed_urls for kind of the same purpose.
Hope it helps.
PS. regarding IP spoofing and Defense against spoofing attacks wikipedia says so packet's won't be returned to the attacker:
Some upper layer protocols provide their own defense against IP
spoofing attacks. For example, Transmission Control Protocol (TCP)
uses sequence numbers negotiated with the remote machine to ensure
that arriving packets are part of an established connection. Since the
attacker normally can't see any reply packets, the sequence number
must be guessed in order to hijack the connection. The poor
implementation in many older operating systems and network devices,
however, means that TCP sequence numbers can be predicted.
If it's purely the same server, you can verify requests against 127.0.0.1 or localhost.
Otherwise the solution is probably at the network level, to have a separate private subnet that you can check against. It should be difficult for an attacker to spoof your subnet without being on your subnet.
I guess you're a bit confused (or I am, please correct me). That your JS code is published on the same server as your API does not mean AJAX requests will come from your server. The clients download the JS from your server and execute it, which results in requests to your API sent from the clients, not from the same server.
Now if the above scenario correctly describes your case, what you are probably trying to do is to protect your API from bot scraping. The easiest protection is CAPTCHA, and you can find some more ideas on the Wiki page.
If you are concerned that other sites may make AJAX calls to your API to copy your site functionality, you shouldn't be--AJAX requests can only be sent to the same server as the page the JS is running on, unless it is JSONP.
Short answer: It is not possible to prevent a dedicated attacker.
You have no method of identifying a client other than with the information that they give you. For instance, username/password authentication works under the assumption that only a valid client would be able to provide valid credentials. When someone logs in, all you know is that some person provided those credentials -- you assume that this means that this means that they are a legitimate user.
Let's take a look at your scenario here, as I understand it. The only method you have of authenticating a client is IP Address, a very weak form of authentication. As you stated, this can be easily spoofed, and in with some effort your server's response can be received back to the attacker's original IP address. If this happens, you can't do anything about it. The fact is, if you assume someone from a valid IP address is a valid user, then spoofers and legitimate users are indistinguishable. This is just like if someone steals your password and tries to log in to StackOverflow. To StackOverflow, the attacker and you are indistinguishable, since all they have to go on is the username and password.
You can do fancy things with the client as mentioned in other answers, such as tokens, time limits, etc., but an dedicated attacker would be able to mimic the actions of a legitimate client, and you wouldn't be able to tell them apart because they would both appear to be from valid IP addresses. For instance, in your last example, if I was an attacker looking to make API calls, I would spoof a legitimate IP address, get the signature, and use it to make an API call, just as a legitimate client would.
If your application is critical enough to deem this level of thought into security, you should at least think of implementing something like API tokens, public key encryption, or other authentication methods that are more secure than IP addresses to tell your clients apart from any attackers. Authentication by IP address (or other easily forged tokens like hostname or headers) simply won't cut it.
may be you could achieve this by using Same-origin policy
refer http://en.wikipedia.org/wiki/Same_origin_policy
As suggested by Venkatesh Bachu, Same Origin Policy and http://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing (CORS) could be used as a solution.
In your API, you can check Origin header and respond accordingly.
Need to check if Origin header can be modified by using extensions like tamper data.
A determined hacker can still snoop by pointing browser to a local proxy server.
If this app server is running on an ordinary web server that has configurable listening IP address, set it to 127.0.0.1. With the TCPServer module, it's like
SocketServer.TCPServer(("127.0.0.1", 12345), TheHandlerClass)
Use netstat command to verify the listening address is correct as "127.0.0.1"
tcp4 0 0 127.0.0.1.12345 *.* LISTEN
This will effectively making any connection originated outside the same host impossible on the TCP level.
There are two general solution types: in-band solutions using normal web server/client mechanisms, that are easy to implement but have limitations; and out-of-band solutions that rely on you to configure something externally, that take a little more work but don't have the same limitations as in-band.
If you prefer an in-band solution, then the typical approach used to prevent cross-site request forgery (XSRF) would work well. Server issues a token with a limited life span; client uses the token in requests; privacy of token is (sort of) assured by using an HTTPS connection. This approach is used widely, and works well unless you are worried about man-in-the-middle attacks that could intercept the token, or buggy browsers that could leak data to other client-side code that's being naughty.
You can eliminate those limitations, if you're motivated, by introducing client certificates. These are kind of the flip side to the SSL certificates we all use on web servers -- they operate the same way, but are used to identify the client rather than the server. Because the certificate itself never goes over the wire (you install it locally in the browser or other client), you don't have the same threats from man-in-the-middle and browser leakage. This solution isn't used much in the wild because it's confusing to set up (very confusing for the typical user), but if you have a limited number of clients and they are under your control, then it could be feasible to deploy and manage this limited number of client certificates. The certificate operations are handled by the browser, not in client code (i.e. not in JavaScript) so your concern about key data being visible in JavaScript would not apply in this scenario.
Lastly, if you want to skip over the client configuration nonsense, use the ultimate out-of-band solution -- iptables or a similar tool to create an application-level firewall that only allows sessions that originate from network interfaces (like local loopback) that you know for certain can't be accessed off the box.
After reading the introductory articles on REST (Fielding's thesis and other) my perception of statelessness is that there should be no session objects on the server side. Yet, i see Flask (and maybe other REST frameworks in different technologies that i do not know about) gives us a session object to store information on the server in this example:
#app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
session['username'] = request.form['username']
return redirect(url_for('index'))
...
Surely, i am misunderstanding REST's statelessness. So, what is it really?
The purposes of introducing the statelessness constraint in REST include improvements to visibility, reliability, and scalability. This means that proxies and other intermediaries are better able to participate in communication patterns that involve self-descriptive stateless messages, server death and failover does not result in session state synchronisation problems, and it is easy to add new servers to handle client load again without needing to synchronise session state.
REST achieves statelessness through a number of mechanisms:
By designing methods and communication patterns that they do not require state to be retained server-side after the request.
By designing services that expose capabilities to directly sample and transition server-side state without left-over application state
By "deferring" or passing back state to the client as a message at the end of each request whenever session state or application state is required
The downside of statelessness is exposed in that last point: Applications that demand some kind of session state persist beyond the duration of a single request need to have that state sent back to the client as part of the response message. Next time the client wants to issue a request, the state is again transferred to the service and then back to the client.
you can get more info from herehttp://soundadvice.id.au/blog/2009/06/
No, you understand well. There shouldn't be any "session" in a RESTful service. Always check that you can send any URI by mail, keep it in bookmarks, and reference it in links. This is indeed why REST is so important to the Web: no RESTful resources = no more links. Authentication should only be done when accessing the resource representation.
What you can have instead of sessions is a user object (for example a shopping cart) that can be modified by REST methods. This is different from a session, since, for example, there could be services where you could authorize other people to see your shopping cart.
In REST architecture, Session state is kept entirely on the client. This means data cannot be left on the server in a shared context and we still have to send the repetitive data (per-interaction overhead) in a series of requests.
As we keep the application state on the client-side, this reduces the server's control over consistent application behavior, since the application becomes dependent on the correct implementation of semantics across multiple client versions.
However this constraint induces the properties of visibility, reliability, and scalability.
Visibility is improved because a monitoring system does not have to
look beyond a single request datum in order to determine the full
nature of the request.
Reliability is improved because it eases the task of recovering from
partial failures.
Scalability is improved because not having to store state between
requests allows the server component to quickly free resources, and
further simplifies implementation because the server doesn't have to
manage resource usage across requests.
see http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
Firstly pardon me if i've yet again failed to title my question correctly.
I am required to build an app to manage magazine subscriptions. The client wants to enter subscriber data and then receive alerts at pre-set intervals such as when the subscription of a subscriber is about to expire and also the option to view all subscriber records at any time. Also needed is the facility to send an SMS/e-mail to particular subscribers reminding them for subscription renewal.
I am very familiar with python but this will be my first real project. I have decided to build it as a web app using django, allowing the admin user the ability to view/add/modify all records and others to subscribe. What options do I have for integrating an online payment service? Also how do I manage the SMS alert functionality? Any other pointers/suggestions would be welcome.
Thank You
Payment gateway integration:
Here is a detailed article about how to integrate the Authorize.net payment system into a Django project. Authorize.net is used by a few popular Django projects, including the Satchmo e-commerce store project.
django-paypal is a pluggable Django app which lets you connect to PayPal merchant services.
SMS alerts:
django-sms is a Django app which is "...designed to make sending SMS text messages as simple as sending an email." so might be a good start.
General Django
You didn't mention your knowledge level of Django itself; if you need to brush up on your Django skills I would highly recommend the book Django 1.0 Website Development.
I think it's also worth pointing out that the resources I've mentioned here were all found in the first few results of a Google search for each topic. These are the search terms I used:
django payment gateway integration
django paypal integration (because I knew of PayPal beforehand)
django sms alerts
I'd like to comment on the SMS alert part.
First, I have to admit that I'm not familiar with Django, but I assume it to be just like most other web frameworks: request based. This might be your first problem, as the alert service needs to run independently of requests. You could of course hack together something to externally trigger a request once a day... :-)
Now for the SMS part: much depends on how you plan to implement this. If you are going with an SMS provider, there are many to choose from that let you send SMS with a simple HTTP request. I wouldn't recommend the other approach, namely using a real cellphone or SMS modem and take care of the delivery yourself: it is way too cumbersome and you have to take into account a lot more issues: e.g. retry message transmission for handsets that are turned off or aren't able to receive SMS because their memory is full. Your friendly SMS provider will probably take care of this.