Restricting user content -- case study

Today we are looking at 纪佳缘 (, the largest match making website in China with 40 million users. Their revenue model is to allow paid users to send letters, but to read a letter you  must also pay a monthly amount. You can send or receive a few letters for free and set up a profile for free.

In the last week I have 30 new messages, here's the inbox.
And here is the first letter, you can see for free:

But when you try to click on the second one...
Blocked, you need to pay to see this. Lots of messages and you can't see them... is this a scam or are there real people on the other side of the line? Let's poke around. Actually, this is just an iframe, so lets load it separately.


Basically the whole game here is you want to compare the URLs to see what is different so you can take the one that works (#1) and get a working URL with the content you want (#2).
So let's try this:

Fail, OK, let's try removing that other part all together...
 So this fails too... but there's a clue:


which means "you forgot to specify an inbox or outbox". Ok... let's try the outbox:

 Same error. Going on a limb here... let's try the "sent" box: 

Bingo! I can see the letter, but it shows the page as if I had sent the letter to her. This letter is in English and she sent:
HI, I'm wondering whether you are a real person using this website or it's a deception to lead people believe some foreigners are using this website too. But no offence either way.

A fellow sceptic out there... and the funny thing is that I have no way to reply... so she'll never know.

Lessons learned / recommendations

* Jiayuan has real people sending messages, not auto-generated content.

* Do not format your webpage with the "sent" template or "inbox" template based on user input... the database should tell you which format to use.

* Be careful when limiting user access to the data. Here, the logic is: "if box_type == inbox then see if user has access to letter". The right approach is "if !letter.shouldBeAccessible() then throw error"

* Never give hints in your error messages. 没有选择收件箱或发件箱 makes it clear that the front-end code and backend code were written by different teams without a properly documented interface. This type of error should fail silently with "server error 224254" and log to disk because the user did not actually select the box type.

Last words

I am sending this letter and recommendations to fix the problem to jiayuan and will keep you up-to-date on the progress.