Security issues with FinTech APIs and integrations

This post is a continuation of my last blog post on crypto startups’ front-end security. After my post on common security issues with crypto website and APIs, I had the opportunity to work with more crypto and fintech startups.

Most fintech and crypto startups rely on third-party integrations. Looks like most of these integrations happen without verifying security practices of each other.

I’ll try to make a small list of issues I found multiple times during my recent security audits.

Negative amounts and zero checkout validation: Though it might seem like common sense to validate a transaction against negative amounts and zero, you would be amazed how many developers are missing on this.

Here’s an example of a negative balance checkout:

I was able to change crypto borrowing percentage rate to negative in another audit.

In one case, the ‘amount’ parameter was transferred in the GET request from the client’s website to the payment gateway without validation. The URL looked like this:


Insecure storage of customer’s KYC data:

KYC stands for Know Your Customer and most fintech and crypto startups have to collect government issued IDs from customers for regulatory purposes.

In one audit, I came across the insecure storage of KYC data in the S3 bucket. The URL looked like this:

In the above URL, 602 looks like a user ID so I tried different numbers in auto-increment and was able to access KYC documents for different users.

All you need was one AWS S3 link for format and you could have the personal data of almost all users on the platform.

Changing restricted user settings:

Most platforms don’t allow users to change certain settings after KYC. For example, you can’t change your name, address after your KYC is done.

In the image below, most of these JSON fields in the response header were not part of the request header.
But you could add these fields in request body and modify those (‘KYCSkip’ changed from 0 to 1).

After submitting the request, profile (response field) gets updated.

An attacker can bypass restricted settings this way!

Insecure third-party integrations:

In one of my audits, a client had an integration with a card issuance service. The communication between client and service provider used to happen through a URL like this:


this URL itself looks insecure and on top of that these parameters(auth_token/card_id) are fixed parameters.

These links were used to change the PIN of the card with no ratelimit on this endpoint. Attackers can bruteforce the PIN number in this case (on mutiple cards if encryption/encoding is not strong).

Along with these issues, XSS, access control, IDOR are still very common in fintech APIs.

These days just securing yourself is not enough, you should also verify the security of every partner you are integrating with and make sure they follow best security practices.

That’s all for now, hope this short post was useful for you from the security perspective.

If you run a crypto or FinTech startup and looking for security audits – we should talk 🙂

Have questions, suggestion regarding this post – feel free to reach out on my Twitter.

P.S. Can’t name websites as per our working agreements!

Common security issues with crypto websites and APIs

There are many crypto startups coming up with the increasing popularity of cryptocurrencies.

As a FinTech enthusiast, I explore as many crypto websites, wallets, DeFi systems as possible and as a bug bounty hunter – I get to test some of them. 

This week I tested a couple of crypto applications and there seems to be a pattern in security vulnerabilities among these applications. 

Most of these security issues were related to injection, bypassing disabled forms, and access control. 

Let’s see each one of them with example:

  1. Injection via X-forwarded-for header:
    As a general practice most crypto websites save log-in IPs and have some functionality around IP whitelisting.
    an example of login notification – also present in the dashboard

    Without a proper validation on the server side, this field can be injected using XFF header.
    These Injection can range from a harmless XSS to server side code injection, here’s an example:

    an example of XFF injection

    Most of these application uses REST architecture, hence these API injections can lead to severe damage depending on where you are using these JSON fields.

  2. Bypassing disabled input fields:
    Some of the input fields are disabled in the dashboard (of crypto/FinTech websites).
    In most cases, these fields are name, username and email – disabling them make sense because these fields shouldn’t be updated regularly for KYC and compliance issues.

    Just disabling them from HTML forms on the client side is a bad idea, it can be easily bypassed through a browser proxy like Burp and Zap.

    Sometimes even fields which aren’t supposed to be updated like currency, language and timezone can get injected.

    here’s an example:

    Again, because of REST architecture if you are using these user data elsewhere – it can create injection issues ranging from XSS to server side code execution
  3. Access control: This one is complex and deep topic but I’ll share two examples: weak auth token and improper session managements.

    There are many ways to authenticate a user in REST from HTTP basic auth, JWT to a complex implementation of cryptography. No matter what variation of auth token you are using, make sure you are not just encoding BASE64 of user data like user ID and some timestamp.

    In case of JWT, use a longer secret with HMAC enabled, RS256(asymmetric algorithm) is recommended over HS256(symmetric) is the alg header.

    Also, there are some known issues with JWT, you can read more about it at and

    Coming to session management – the most common issue here is session fixation.
    It is recommended to end the session when a user log-out. All the cookies and session ids shouldn’t work in a new session but that’s not the case most of the time.

    In some cases, even where new session IDs are generated old session IDs are not disabled.
    This was the case with Remitano, where I submitted the issue in their bug bounty program on Hackerone:
    Here is the video POC for the same:

    Again make sure, session IDs are not predictable.

That’s all for now, hope you found this short post useful.
And if you are a crypto or FinTech startup and looking for security audit or hiring security engineers – we should talk 🙂

If you have any questions, suggestion regarding this post – feel free to reach out on my Twitter.

P.S. Can’t name websites as per their security and responsible disclosure policies but Remitano(the one with session fixation issue) has a public bug bounty on Hackerone.

Breaking Instacart

Instacart is an American company that operates as a same-day grocery delivery service. Customers select groceries through a web application from various retailers and delivered by a personal shopper. As of 2017, Instacart only has operations and services in the United States. [1]

Instacart has a bug bounty program on Hackerone, you can learn more about it at I’ve reported multiple valid security issues(ranked #3, ).

Instacart has a hiring section for shoppers, where a potential candidate can enter his details and set up a meeting.

The Auth part was of this section was had an interesting bug.

One day I received an email which said “set up your meeting”, I clicked the linked and it logged me in without asking any credentials.

After breaking down the Auth link, found out it was GET request with pin code, phone number, and a verification code which was in the format

The login process from the ‘sign-in’ page required an OTP sent to the registered mobile. Tried to log in multiple times from the login page, surprising part was getting the same OTP every time.

In order to show the impact, the attack must be applicable to all accounts.

Obviously, the first attempt will be brute forcing the login form with known mobile number and as the verification code consists 5 digits. We can start from 00000 to 99999 but that didn’t work and I got blocked by the rate limit after certain attempts.

As it was a GET request, one can brute force the URL itself. Just brute force the code part for a known number in the URL

And it worked!

Though the whole attack depends upon a known pin code and mobile number, Instacart accepted the report as medium severity and paid their highest bounty of that time.

Later, Instacart replaces the auth part with Twitter fabric.

Thanks for reading. If you have any suggestions or feedback, feel free to reach out on Twitter

Manish 🙂



Hacking Google for fun and profit

I have been doing bug bounties since September 2013(Asana was the first), participated and qualified in almost all bug bounties at least once. My bucket list had Facebook, Yahoo, Twitter, Dropbox, Github and 100+ such sites (including couple of YC Startups ) but Google VRP was tough nut to crack. I always wanted to start my bug bounty story with Google, but failed in past with few duplicates.

I was watching 2016 Google I/O, Firebase was the main focus. I had reported couple of security issues when they were quite young. Got a mini box full of stickers, bands and hot souces for my contribution.


So when I saw Firebase got a new site that too on a *,  it all came back to me.

The minimum bounty on Google main domain(* is $500, more than that you’ll get your name in prestigious Google Hall of Fame.
Continue reading

Understanding CSRF attacks


What is CSRF ?

“Cross-site request forgery, also known as one-click attack or session riding and abbreviated as CSRF (sometimes pronounced sea-surf) or XSRF, is a type of malicious exploit of a website where unauthorized commands are transmitted from a user that the website trusts.” – Wikipedia

CSRF is at 8th position in OWASP top 10 bug list. Usage of frameworks like Django, ROR reduces the risk of CSRF to a large extent but it is still there. Also, it is carried out from user’s IP address, website’s logs will have no evidence.

Examples of CSRF:

CSRF comes in all shape and sizes. Dangerous one can take over an account, minor one can destroy your session or log you out.

Every request that change state on server should have CSRF protection.

It can be an email change or addition of user details like a bank account.
Continue reading

Web application security checklist

I printed out my Asana task list of web app security testing,hopefully you’ll find it useful. OWASP 10 are the starting points of web testing, followed by other not so common issues.

Comments inside my task list are more helpful(provide various attack scenario and test cases) but Asana don’t export  comments while printing, maybe I’ll write a proper short guide explaining all the points in future. Stay tuned on my twitter for further updates.

Here is the PDF of Security task list



Manish (@umenmactech)


List of Y Combinator companies I have worked with(hacked)


I have worked with lots of companies as security consultant through bug bounties either I asked them if they need my service or they approached. I’m a big fan of Paul’s essay, Hacker News, Startup School and YC as a whole, so thought to document my contribution to YC(nothing technical, just a list).

I have worked with these companies in their early stage to resolve security issues with their websites:

  1. Xobni (S06) :   Acquired by Yahoo later. Found account take over CSRF in setting page. Got Yahoo swags.
  2. Dropbox (S07):  Multiple bugs in the mailbox and other acquisitions. Got listed on Special Thanks page, swags and 100GB.
  3. Disqus (S07):  Got stickers and swags.(Can’t find the mail, don’t remember the issues)
  4. Heroku(W08):  Screen Shot 2015-10-28 at 11.49.39 am
  5. WePay (S09):  Participated in their bug bounty program on Hackerone.
  6. Olark (S09):    Screen Shot 2015-10-28 at 11.58.44 am
  7. Mixpanel(S09): Screen Shot 2015-10-28 at 12.02.29 pm
  8. Stripe(S10):Screen Shot 2015-10-28 at 12.06.52 pm
  9. PagerDuty(S10): Multiple issues,Multiple swags Screen Shot 2015-10-28 at 12.11.04 pm
  10. Hipmunk(S10): Just realized, I was discussing stuff with Steve Huffman 🙂 Screen Shot 2015-10-28 at 12.15.14 pm
  11. Screen Shot 2015-10-28 at 12.20.16 pm
  12. Mailgun(W11): Screen Shot 2015-10-28 at 12.24.17 pm
  13. DR Chrono(W11): Worked with CEO directly and got handsomely rewarded for my work.
  14. Parse(S11):  Yes, Parse CEO said thisScreen Shot 2015-10-28 at 12.33.19 pm
  15. Firebase(S11): Screen Shot 2015-10-28 at 12.36.45 pm
  16. Instacart(S12):   Through private bug bounty
  17.  Acquired by Github, reported multiple issues. Special Thanks page on Github.
  18. Coinbase(S12): Through public bug bounty on Hackerone.
  19. Clever(S12): Screen Shot 2015-10-28 at 12.45.16 pm
  20. Zenefits(W13): Through private Bug bounty.
  21. Heap Analytics(W13): Screen Shot 2015-10-28 at 12.49.59 pm
  22. TrueVault(W14): Screen Shot 2015-10-28 at 12.54.42 pm
  23. Algolia(W14): still have lots of Algolia stickers 🙂
  24. Gitlab(W15): Listed on Acknowledgement page.
  25. Hacker News: Yup, Y Combinator itself. You can find me on their thanks page.

Look like that’s it for now.

so 25, not bad! BTW I am no ninja hacker, most of the stuff are the same task just another website. I have been a jerk professionally (in responding emails), sometimes I didn’t know the tech celebrity I’m talking with, for e.g Steve Huffman, IIya sukar.

I can help with basic web application testing but crowdsourcing your security is the best way to stay updated.

Any questions, suggestions or want to hire me? I’m at

Logging off


Edit: This list has grown up to 120+, I’m not maintaining this list anymore!

Beginner’s Guide to API(REST) security

API security


API(Application Program Interface) is a framework that makes it easy to build HTTP services that reach a broad range of clients, including browsers and mobile devices. Most of the websites provide API so that developers can make application on top of it. For e.g. Facebook graph API, Twitter API, Dropbox API ,Github API etc .

I’ll discuss few basic points about REST architecture that you need to keep in mind regarding API security.

Authentication: There are various ways to authenticate a user for using your API , most commonly used authentication protocols are HTTP Basic Auth and OAuth.

HTTP Basic Auth : Credentials are merely encoded with Base64, no encryption , no hashing. Every request contain encoded value inside header, so using HTTP Basic Auth without HTTPs is suicide.

OAuth : In this case access token is generated by the resource owner for certain sets of scope . With OAuth, leakage of access token can be dangerous as it contains certain permissions to perform action on behalf of user. Even Facebook was once vulnerable to this,you can read more about this facebook bug in this post.
Authorization is as important as authentication.You must check what are the permissions associated with the access token,Facebook was vulnerable to this as well where hacker can delete any facebook album. Facebook paid him $12,500 for reporting this, read more about this on his  blog.

User Input: There’s a single rule for maintaining security of applications, never trust user input.This apply to API security as well, most of the time web application filter input but they forget to apply filter on input coming from API. Here’s a example of this, Slack was vulnerable to this.
Continue reading

How to order Free Food in Bangalore

After my Internship , I had  plan to stay in Bangalore for a week. For people who know me I hardly go out alone , problem was going out for lunch  so I thought i’ll order food online .

Dazo is a Bangalore based food ordering app. I had a promo code  DAZO100 for 100rs off on your first order.


One thing I noticed , no traditional account management (registration or OTP verification). I was curious about “how they manage user information”.

In the meantime got a mail from DAZO with order details, but I never entered the mail. Ohh, the app is using my android(google) account.

Adrenaline rush started in my security nerve.

You can create multiple user in Android Lollipop ,


so created a new user (better not mess up with my google settings).This “New user” provide  virtual box like environment, registered with different email,downloaded DAZO , used DAZO100 again and Bang ! .

Had the Chicken for 20 Rs.


DAZO new user acquisition price was rs100 but in my case it was 400+. All you have to do is change the google account from phone setting before placing an order and use DAZO100. Being a tester I have 5,6 gmail and it doesn’t cost anything for creating new.

I came to know that they do verify every order  manually and they know about this 😛 but they don’t have any choice , either fix the bug or deliver the food. I am a  new user with new email , nothing illegal .

They use all sorts of permissions  Device ID,Identity ,WI-FI information and what not.

I had Free food (or paid in 2 figures) for 3 days . I guess now they have fixed it or blocked my phone for code , you can give it a try after all your one email worth INR100.

till then Happy Hacking 🙂


Every CSRF token need not be verified in order to prevent CSRF

Cross-Site Request Forgery (CSRF) is a type of attack that occurs when a malicious Web site, email, blog, instant message, or program causes a user’s Web browser to perform an unwanted action on a trusted site for which the user is currently authenticated. – Wikipedia


I had an interesting encounter with CSRF last week , one of them is yet to be fixed. Here is an interesting low impact issue

These days almost every form on a website use CSRF protection by default. Every time website load  , CSRF token should be different/unique/unpredictable . But this is not the case with 80% of websites out there. I’ll be explaining this two examples one is Dropbox and other is move-app(Facebook)

Let’s start.

Most of the dynamic website contain Sign in functionality as well as forgot password to recover the account.

“Most of the forgot password forms are vulnerable by design , a good practice is to ask a security question before sending reset link” – Aditya

My area of interest was CSRF token for the visitors , public forms like reset password ,sign in ,feedback and all. These tokens are session based (when the site load session started till you close  the browser).

The issue was token remains same for a particular session . For e.g when you submit reset password request first time , token is x, now every time you request areset password  token will be same x.

I thought to abuse this , I made a PHP crawler that will crawl the hidden CSRF value and thought to add token field with my CSRF form . here is the PHP code to extract all the input values from Coinbase.

$doc = new DOMDocument();
$tags = $doc->getElementsByTagName(‘input’);

foreach ($tags as $tag) {
$x= $tag->getAttribute(‘value’).’|’.$tag->nodeValue.”\n”;
echo $x;

I tried to submit my form by scrapped CSRF token ,  badass idea. Didn’t worked , because my page was not creating any session.

Now , the goal was clear I have to use my session to abuse the CSRF. So, what I did is copied my cookie and token and used cookie with document.cookie and token value, this time Bingo !. Continue reading