Case where reCaptcha v3 won't block bots - bots

I was having huge card testing bots issues on a website using Stripe.
I had to close the payment part for a while to find the solution.
I had reCaptcha setup by a freelancer. All seems good, the reliability score is set up to 0.9, yet I still got bots making accounts on my service.
In which case bots would be able to pass through reCaptcha v3 and how am I suppose to stop them if this captcha is not working ? It is a very small business I don't have the funds to buy an enterprise solution.
Thank you for enlightments.
EDIT :
Here's the part of the code that handles captcha verification :
//captcha verification
if(!request.v) return error(401, "Error");
console.log("Captcha tracking, ", "start")
var captchaResp = await fetch(
"https://www.google.com/recaptcha/api/siteverify?secret=SECRETKEY&response=" + request.v + "&remoteip=" + event.requestContext.identity.sourceIp);
const captchaRespJson = await captchaResp.json();
console.log("Captcha tracking, ", captchaRespJson)
if (!(captchaRespJson.success==true && captchaRespJson.score >= 0.9)) {
console.log("Captcha tracking, ", "error")
firebase.auth().deleteUser(decodedToken.uid);
return error(401, "Error");
}
console.log("Captcha tracking, ", "all done")
//end captcha verification
The developper also added a honeypot. But it seems that I still get bots registering and getting access to Stripe checkout, with disposable emails domain names. Now it's been online since this afternoon, so maybe I need to wait for reCaptcha to get more data about my website ? I didn't put the reCaptcha snippet on every page but only on the two more visited pages.

Related

How to handle 3D card authentication through Stripe in node

I'm new to integrate stripe payment. I confused how to integrate 3D secure authentication. In my application on Backend platform using node with Hapi framework. Here is the some of code of paymnet intent which is given below.
let params = {
amount: 100,
currency: "CAD",
payment_method_types: ['card'],
payment_method: "card_1HqytjG6OdQYWdifbWxCrVGB", //cardId
customer: "users5fc1c5ff44d8605030499c00", //userId
}
let intent = await stripe.paymentIntents.create(params {
idempotencyKey: uuidv4());
let paymetConfirm = await stripe.paymentIntents.confirm(intent.id, intend.payment_method);
It's working fine with some of the test cards which not require 3D secure authentication.
4242424242424242
2223003122003222
Not working with these cards require 3D authentication)
4000002760003184
4000002500003155
So, when I check the response of the API (with 3D authentication card) return one of the sub-object is
next_action: {
type: 'use_stripe_sdk',
use_stripe_sdk: {
type: 'three_d_secure_redirect',
stripe_js: 'https://hooks.stripe.com/redirect/authenticate/src_1Hs1zhG6OdQYWdifEWTcyUvC?client_secret=src_client_secret_okgYE1A4eOovEFL9g0sgN29U',
source: 'src_1Hs1zhG6OdQYWdifEWTcyUvC'
}
},
When I take this URL and paste on the browser it redirects the page of 3d Secure, There are two option
complete authentication
fail authentication
Note-
Stripe SDK is set up only on the backend platform(Node)
My question is that
Is there any way not to confirm from the client-side, automatically confirm from the backend platform.
For the scenario, we have to set up a stripe SDK on the client-side(android,IOS).?
when I click on the URL which are inside next_action object which are given above,There are two option inside it,that is complete and failure authentication(3D page view) how to integrate clicking on itmy API hit respectively. how to achieve it?
Please help me.Thanks
Your payments are failing with 3DS enabled cards because you aren't authenticating them on the client. Your current flow of confirming server side won't work with 3DS enabled cards, as you aren't giving the user an opportunity to do the 3DS flow.
It's not really recommended to confirm the payment server-side, as it adds unnecessary round trips to the server without really adding anything. However if you do still want to confirm server side, Stripe has a guide on how to do that here: https://stripe.com/docs/payments/accept-a-payment-synchronously

How to get instagram follower count from instagram public account after 2020 instagram api change?

I am trying to retrieve the follower count only just using a user's instagram handle (aka #myusername). I read in several answers that you can access the "https://www.instagram.com/{username}/?__a=1" to retrieve the block of json that has all the details. However, when I try to do that now in 2020 after the api change, the url simply redirects me to the login page.
I also looked at instagram basic display/graph api but I can't seem to find a way to get other users' follower counts.
From the official ig basic display api documentation: https://developers.facebook.com/docs/instagram-basic-display-api/reference/user
This api only allows you to get the account_type, id, ig_id (about to be deprecated), media count and username. (no sign of follower count)
From the official ig graph api documentation:
https://developers.facebook.com/docs/instagram-api
"The API cannot access Intagram consumer accounts (i.e., non-Business or non-Creator Instagram accounts). If you are building an app for consumer users, use the Instagram Basic Display API instead."
Since my program is suppose to retrieve the follower count from accounts that are not necessarily professional, I can't seem to figure out what to do...
In conclusion:
I have tried web scraping -> get redirected to login page
Basic display api -> can't get the follower count
Graph api -> can't access consumer accounts
Does anyone have a solution for this?
Thank you!
You can use Instaloader Python module.
Here is a quic example:
import instaloader
L = instaloader.Instaloader()
user = "IG_USERNAME"
password = "IG_PASSWORD"
L.login(user, password)
profile = instaloader.Profile.from_username(L.context, user)
print(profile.followees) #number of following
print(profile.followers) #number of followers
print(profile.full_name) #full name
print(profile.biography) #bio
print(profile.profile_pic_url) #profile picture url
print(profile.get_posts()) #list of posts
print(profile.get_followers()) #list of followers
print(profile.get_followees()) #list of followees
Had the same problem. I ended up inspecting instagram network and found this:
https://i.instagram.com/api/v1/users/web_profile_info/?username=<USERNAME>.
Make sure you put a user-agent header in the request with this value:
Instagram 76.0.0.15.395 Android (24/7.0; 640dpi; 1440x2560; samsung; SM-G930F; herolte; samsungexynos8890; en_US; 138226743)
you can get the follower count on data.user.edge_followed_by.count
Instagram blocked your IP ... you need to use undetected proxies to scrape that from Instagram, usually, Residential IPs passed.
send HTTP request to IG API end > if got JSON response it's good and not detected, else it's detected proxy and not good for Instagram.
code for that (in c# but could follow the same logic in python) :
var httpClientHandler = new HttpClientHandler()
{
Proxy = new WebProxy("127.0.0.1:8080", false),
UseProxy = true
};
var client = new HttpClient(handler: httpClientHandler, disposeHandler: true);
var response = await client.GetAsync("https://www.instagram.com/instagram/?__a=1");
if ( response.Content.Headers.ContentType.MediaType == "application/json")
{
// Not detected proxy and good for Instagram
}
else
{
// Detected proxy and not good for Instagram
}
If you ask why Instagram is blocking some IPs? simply Instagram has a huge database that contains past IPs who sent more than the allowed limit requests ... they are doing that to prevent scraping.

Stripe Automatic Confirmation and order fulfillment without Webhooks?

The stripe documentation says when using payment intent using automatic confirmation you should Asynchronously fulfill the customer’s order using webhooks.
If i'm offering a service e.g. ability to download a file once purchased then why do I need to monitor for the payment_intent.succeeded webhook?
If payment succeeded in the following handleCardPayment function then is there still a possibility for the charge to fail? Why shouldn't I allow the user to download the file straight away if the payment has succeeded?
var cardholderName = document.getElementById('cardholder-name');
var cardButton = document.getElementById('card-button');
var clientSecret = cardButton.dataset.secret;
cardButton.addEventListener('click', function(ev) {
stripe.handleCardPayment(
clientSecret, cardElement, {
payment_method_data: {
billing_details: {name: cardholderName.value}
}
}
).then(function(result) {
if (result.error) {
// Display error.message in your UI.
} else {
// The payment has succeeded. Display a success message.
}
});
});
Maybe I've not understood how the handleCardPayment works. Any help appreciated.
When using handleCardPayment, the issue is not so much that the payment might fail, it's that it might succeed but your code doesn't know about it.
handleCardPayment kicks off several asynchronous steps — showing the user a dialog to authenticate a payment with their bank, processing the actual charge against their card, and closing the dialog. It's only after all that completes does the Promise resolve and your function that receives result executes.
Consider the case where:
the customer clicks Pay
handleCardPayment is called
the customer sees a dialog from their bank to authenticate the
payment
they do that, and they consider that their payment is now complete,
and they close their browser immediately.
In this case, your code will never execute, but Stripe still processed the charge. So you don't know that the payment happened and you can't fulfil the order.
That's why it's important to use webhooks, so you get notified asynchronously when the payment completed, even if the user closed their browser mid-process and your code after handleCardPayment never got a chance to run. Alternatively you can use the manual confirmation flow, where the steps are split up and the actual charge isn't processed until your server makes a separate API call.

How to replace default response in account linking on Google Assistant

As part of an action configured for account linking with the following topology:
Actions-on-Google->Dialogflow->Webhook,
I'm seeing Google Assistant injecting its own message prior to going through the account linking flow, as follows:
"I need to link your <action-name> to Google. Is that ok?"
The linking flow is triggered by the following in the webhook:
public ActionResponse launchRequestHandler(ActionRequest request) throws Exception {
ResponseBuilder responseBuilder = getResponseBuilder(request);
responseBuilder.add(new SignIn());
}
I'd like to be able to replace the above stock message with a custom one, however when attaching a context to a sign in card with our own message, like so:
String speech = "Hi, I see that your account isn't connected. "
+ "I've sent a link to your Google Assistant app that will get you started and set up in just several simple steps. "
+ "Don't worry, I'll be here waiting, just call me when you're ready.";
responseBuilder.add(
new SignIn()
.setContext(speech));
I'm still seeing the default message tacked at the end:
"Hi, I see that your account isn't connected.
I've sent a link to your Google Assistant app that will get you started and set up in just several simple steps.
Don't worry, I'll be here waiting, just call me when you're ready.,
I need to link your <action-name> to Google. Is that ok? "
How can I replace the Google default message with my own?
To ensure a consistent experience for users, you cannot replace the default message. You can only set the context, which lets you provide your custom information for the user ahead of the generic question.
The context is an additional piece of information which may be more relevant to your Action. Let's say it's connecting to your example.com account. You would add the context as a string:
app.intent('Login', conv => {
conv.ask(new SignIn('To provide you with personalized info from example.com'))
})
The user would hear this message, with the generic prompt appended:
To provide you with personalized info from example.com, I need to link your Example Action to Google. Is that ok?
Then you can say yes or no, and go through the OAuth flow / Google Sign-In flow.

Getting a valid Google access token for Chrome Web Store APIs access from outside a Chrome Extension

I have an issue over Google OAuth and Chrome Web Store APis.
Some context before starting with the tech stuff.
I have a popular Chrome Extension that delivers in-app purchases: purchasing an item the extension goes "pro", so usage limits are expanded.
Last year the audience asked me to make a porting on Firefox (thanks to the newly available WebExtentions APIs), and I started delivering both versions.
The Firefox version does not support in-app purchase at this moment, but people are starting to ask for it (let's think the FF version as an alpha version, so not all features are guarantee to be supported).
Problem: That said, I don't want to implement a secondary payment service using Google Pay APIs or other similar APIs and I'd like that if a user makes an in-app purchase on Chrome, it is delivered on FF as well.
Hoped Solution: I thought it would have been easy to use the Google Chrome Web Store APIs. Making an user authorising its Google Account from the FF add-on I could understand if it was a paying user or not, thus enabling or disabling the "pro" limits.
Here are the steps I did.
Step 1 - Create a new app on the Google Cloud Console (I already have the one used on the Chrome Extension):
And enable the Chrome Web Store APIs:
Step 2 - Jump on Firefox JS console (inside the Options page of the add-on, so I have all the WebExtensions APIs enabled), and call the method to get a valid token (the code is quick and dirty, not enhanced and written just as a POC):
var scopes = ['https://www.googleapis.com/auth/plus.login',
'https://www.googleapis.com/auth/chromewebstore.readonly'];
var url = 'https://accounts.google.com/o/oauth2/v2/auth?'
+ 'client_id=xxxxxxxx.apps.googleusercontent.com'
+ '&response_type=token'
+ '&scope='
+encodeURIComponent(scopes.join(' '))
+ '&redirect_uri='
+encodeURIComponent(browser.identity.getRedirectURL());
browser.identity.launchWebAuthFlow(
{interactive: true, url: url})
.then(function(result){
console.log(result);
})
.catch(function(err){
console.log(err);
});
Using the browser.identity.launchWebAuthFlow() function I got a valid token from the returning result (in the query string on the access_token parameter).
Now I get call the Chrome WebStore APIs with no issue (I thought) with this simple code:
//access token
var token = 'previous_access_token';
//Google Chrome immutable Ext. ID from the store
var GOOGLE_CHROME_EXTENSION_ID = 'XXXXYYYYZZZ....';
//endpoint to get all purchased items (see https://developer.chrome.com/webstore/webstore_api/payments#resource)
var CWS_LICENSE_API_URL = 'https://www.googleapis.com/chromewebstore/v1.1/items/';
var req = new XMLHttpRequest();
req.open('GET', CWS_LICENSE_API_URL+ GOOGLE_CHROME_EXTENSION_ID + '/payments');
req.setRequestHeader('Authorization', 'Bearer ' + token);
req.onreadystatechange = function() {
if (req.readyState == 4) {
var license = JSON.parse(req.responseText);
console.log(license);
}
}
req.send();
Unfortunately this doesn't work at all, getting the following error:
(You don't have access to licensing data for App ID: xxxxyyyzzzzz)
I have the following evidences:
If I use a token got from the Chrome Extension using chrome.identity.getAuthToken() the call is ok
If I run the same script inside the Options page of the Chrome Extension, I get the same error
A specific Chrome WebStore API actually work (the get items API)
I guess for some reason Chrome WebStore APIs are not accessible using a token produced outside a specific context (i.e. Chrome extension subject of the call).
Does anyone have evidence of this? Google team are you there :) ?

Resources