1

I have a page that allows users to watch a YouTube video and automatically receive a reward as soon as the video ends playing. This is done with the Youtube JS API:

pseudocode:

function videoStoppedPlaying() {
    requestRewardFromServer(); // currently uses an XMLHttpRequest
}

The problem with this approach is that one could just open the browser console and manually call requestRewardFromServer().

I am already applying obfuscation on the code, but this is like putting a bandage on a hole in a boat; It does not solve the problem.

Edit: So far the only solution that comes close is using timestamps. Even though this is not the ideal solution, I will take the advice to heart and try to further obfuscate the JS code.

Any suggestions?

  • 2
    I think you could (perhaps you already have) have a method videoStartedPlaying() which also calls the server. Then, when the second method hits the server, the server compares the time between those two requests with the time of the video. If it is lower it means something went wrong. It is not exactly what you want, but it will give a small improvement. – actunderdc May 24 '18 at 10:42
  • 1
    There is no real “solution” to this, because you have to trust information coming from the client. I’d also use time stamps at least, and compare playback start and end time with the video length (assuming you want to force people to watch the whole sh*tty thing before getting the reward.) Of course that won’t stop me from calling your method that records the playback start timestamp manually same as before, then do something else for a few minutes, and then call the second one that says I’ve finished watching ... – CBroe May 24 '18 at 10:55
  • …and finally nothing can stop the user from opening your page and then looking at something else. – Bergi May 24 '18 at 11:37

3 Answers3

1

When getting the reward, store the Youtube video ID so you get at least one reward per video. Of course you have to keep track of the video ID's or else you can pass any string.

To prevent users getting the reward without watching the video you could build some timer such that it would be impossible to get the reward after the time has exceed.

com2ghz
  • 2,706
  • 3
  • 16
  • 27
1

Below are my thoughts on this-

I feel you need to dive into server side for this.

  • Set a session variable on the server, such as video_length = some_length.
  • From the time the video started, send an ajax request to the server and set some session variable, as video_started = some_time.
  • Now, when you call requestRewardFromServer(), compare the current time with video_start. It needs to greater than or equal to the video_length.

If it is satisifes the condition, reward them, or else not. You might say this doesn't guarantee that the full video is watched. Yes, but at least the person trying to spoof has to wait that long.

nice_dev
  • 17,053
  • 2
  • 21
  • 35
1

The only solution to control that the user is actually watching the video, besides checking end time - start time vs length of video is to actually check that the user is really watching it. I suppose you have a function that can tell you at what minute of the video (or percentage) the user is. So, you could periodically inform the server via javascript about that: For example, every 5 seconds or every 5% of the video, the client has to send a xmlhttp request to the server to inform it about this. The server will check for a client that it received all requests in the corresponding order (or almost, maybe he rewatched a part of it, you will have to figure out an appropiate algorithm).

It is not easy, it requires some work and it is not quite 100% 'bulletproof'. But, anything related to javascript can still be manipulated locally.

actunderdc
  • 1,448
  • 2
  • 11
  • 20
  • Since I'm on a new StackOverflow account I cannot upvote your answer anymore. This is a very creative, potentially deadline saving solution. Thanks! – Maxim van Dijk May 25 '18 at 08:10
  • I am glad it helped. I think you can, at least, mark this as the correct answer for future references to this post. – actunderdc May 25 '18 at 08:19