One of our Marketo landing pages, calls an external API to pass some information. For this, the external API client ID and secret are placed on the landing page.
In order to secure this setup, we are planning to use IP restrictions to only allow calls from the landing page to the external server. I just wanted to confirm if we should be concerned regarding IP Spoofing? Also, any other security risks involved with this approach?
Also, will there be extra concerns to do with shared Marketo IP?
If Sanford Whiteman hasn't made it clear, this is a bad idea entirely.
The discussion has been very abstract. Right now you're getting very specific answers to your questions, but are left with many choices to make. To get more useful ideas, it might be helpful to explain your overall goal in simple terms so that we can help propose a workable solution.
Thanks Tony.
I'll start a new question with a better question and clear suggestions.
Hi Alex,
Do you mean to use 'landing page domain' based restriction instead of the IP address of the visitor?
Thus the service would allow a web page to use the service only if the web page is on your website(s). If someone else copies the 'access credentials' and create web page on their domain, the service should reject the request. The unauthorized person would not be able to host their landing page on your domain(s).
Hope this helps...
What you're describing isn't secure at all. The referrer can be trivially forged by an absolute newbie.
So I hope that isn't what Alex means...
I agree. I was asking if that was the service provider meant instead of IP address..
Do you think there is a way to use CSRF token mechanism if the service provides along with custom javascript on Marketo landing page in such instance?
Nope, because CSRF only applies to hijacking an authenticated session from an unauthenticated page. For example, without knowing a Marketo user's username and password, being able to trigger Marketo campaigns because you got them to go to your malicious site. (Note any worried lurkers: this is not possible! I'm describing the potential case that CSRF tokens are there to block.)
In this case Alex is talking about a Marketo LP (thus unauthenticated) posting data to an external service (perhaps expecting an API key, but if the end user is not to be prompted to enter the key, it must be embedded in the page where anyone can copy it). If it were possible to require a popup w/interactive authentication to the external service (not publishing the credentials to the world) that would be a different story.
You can cobble together pseudo-authentication for a Marketo form post using the Marketo Unique Code (blog post on that in the future). However, it doesn't happen interactively, it's something for the back end and could potentially take minutes to process under load. Similarly, you could use any custom field as a password-like (or password-lite!) field, so only if a certain field supplied by the end user matched this other (non-updateable) field would you continue processing. But that processing is still server-side, like via a webhook. And in both of the cases, the person has to enter something they know in advance, it's not a regular lead gen form post.
One of our Marketo landing pages, calls an external API to pass some information. For this, the external API client ID and secret are placed on the landing page.
Um, okay, no longer an API secret though as obviously anyone can read it from the webpage (the whole idea of a secret is it is not world-readable).
It's operating more like an API key in this scenario.
In order to secure this setup, we are planning to use IP restrictions to only allow calls from the landing page to the external server.
The IP address seen by the remote API will be the public IP address of the person viewing the page. How are you predicting this IP address? Are you locking this down so it can only be used from a particular external IP or subnet?
I just wanted to confirm if we should be concerned regarding IP Spoofing?
In practice, no, you don't need to worry about spoofing a (TCP) IP source address across the net, because that'll be blocked by transit routers.
Also, will there be extra concerns to do with shared Marketo IP?
The IP address of your Marketo instance will not be the source IP address of connections made by end users, so the question doesn't really make sense.
Your right. Not an API secret anymore.
Regarding, 'The IP address of your Marketo instance will not be the source IP address of connections made by end users, so the question doesn't really make sense'
Since the landing page sits on Marketo, will the source IP of the API calls made via the landing page not be from the Marketo IP? If not, is there anyother way for the API server to authenticate?
Hi Alex,
I think you have a bit of confusion.
When the 'landing page' calls the external service API, the 'landing page' is calling from the 'user's browser' using typically Javascript code. The IP address in this case is the IP address of the 'website visitor' machine. And not the IP address of Marketo server.
If your business need does not need the external service to be called from the 'landing page' but can be called from Marketo server after the form is submitted to Marketo, You can use Marketo web hook in this case. In this case, the IP address will be that of the Marketo server. And in this case, there is no security issue as all the access credentials will be in Marketo and not visible to web visitor.
Thank you Rajesh! I think we will need to explore webhooks in this case. Unfortunately, there are multiple API calls to get the data and then update info via the external APIs.
Do you have a guide that i can use? I am using the Basic Authentication(Btoa) method for the API calls.
Unfortunately, I do not have any guide for your case as it will depend on the service provider and your business case specifics. Especially, when you have the need of 'multiple' API calls 'I guess one after other' to get all the data.
You will most likely need a custom webhook which will accept call from Marketo and manage the handshake with your external service provider to collect all the data. It can get complicated if this all is going to take some time as the web hook might have to use Marketo API calls to write the data in to Marketo if it takes long time.
Unfortunately, there are multiple API calls to get the data and then update info via the external APIs.
You will have to write an intermediate webhook gateway. In other words, a webhook-compatible endpoint that manages the outbound connections (perhaps in parallel) but which Marketo only connects to once.
Webhooks are stateless, they are not suitable for multi-stage processing.
Noted.
Is there any guide i can use for GET and POST calls using webhooks and Basic Authentication?
Basic Auth is just an
Authorization: Basic <base64encodedcredentals>
header. You add Custom Headers using Webhooks Actions » Set Custom Header.
Note: btoa() is not actually correct for encoding String-to-String, as it does not support non-Latin-1 characters.
Yup. I have set up the webhook and the custom header. But I can't figure out how to call the GET webhook from the landing page and use the response on the landing page.
Hi Alex,
You can not call a 'webhook' from landing page. Webhook is 'only' callable from Marketo server using a smart campaign that executes on Marketo server side.
This then defeats what i'm trying to achieve.
Is there anyway I can store the API key and secret in marketo and access it securely when I make the AJAX API Calls?
Is there anyway I can store the API key and secret in marketo and access it securely when I make the AJAX API Calls?
No.
There's no way to do what you're describing securely from the client side.
It's Web Security 101: a service that can be accessed from a public page without user interaction, and which permits connections from any IP, is not secure. You've pretty much defined the problem in your architecture. Erase your sketched-out architecture and start over, this is a dead end.
Yup. We will start again. Do you have a proposed method that will work with Marketo and be secure?
Do you propose the below will work?
On the marketo landing page,
1. API Call 1 - Get user info based on user email from the external system - Returns an "access token" along with the user info.
2. API call response is used to populate the marketo form.
3. Marketo form is submitted.
4. API Call 2 - Update user info on external system by matching the user email along with the above received "access token" to authenticate that the request was made by the same user.