2

I'm creating a JS counter for an exams website, I found that they can add extra time very easily in console by running sec += 10000, how can I stop this.

I'm using laravel in the backend

runCounter();
function runCounter() {
  let min = 45;
  let sec = min * 60;
  let x = setInterval(function() {
    console.log(secFormat(sec))
    sec -= 1;

    if (sec <= 0) {
      endExam();
      clearInterval(x);
    }
  }, 1000);
}


function secFormat(x) {
  x = Number(x);
  let h = Math.floor(x / 3600);
  let m = Math.floor(x % 3600 / 60);
  let s = Math.floor(x % 3600 % 60);
  m += h * 60;
  if (m < 10) {
    m = "0" + m
  }
  if (s < 10) {
    s = "0" + s
  }
  return m + ":" + s;
}

function endExam() {
  alert('exma ended');
}
Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
  • [Does this help?](https://stackoverflow.com/questions/51839908/prevent-js-editing-in-console) – Robiot Jan 15 '22 at 12:22
  • You can do it by disabling right click. Nothing more to be managed. – Nevermore Jan 15 '22 at 12:22
  • 2
    You cannot stop a user from displaying anything they want in *their* browser. – Bergi Jan 15 '22 at 12:22
  • 6
    Basic rule of online programming: Assume that the user will try to cheat. Everything that is important has to be handled by the server – UnholySheep Jan 15 '22 at 12:23
  • Use backend for validation – Cid Jan 15 '22 at 12:29
  • @UnholySheep is absolutely correct. The way you handle this is, you make a request to the server at the time of submission and compare the time with the server time. If the time has elapsed then you show the user an error popup. – Salvino D'sa Jan 15 '22 at 12:30
  • @UnholySheep well you're right, but this will not work in my case. –  Jan 15 '22 at 16:16
  • 1
    You will have to explain *why* it won't work in your case. Any attempt at preventing users from modifying the JavaScript that is executed on *their* machines will only lead to people needing to figure out how to bypass your attempt – UnholySheep Jan 15 '22 at 16:41
  • 1
    @UnholySheep is correct. You cannot protect the client. From a security perspective, the client is already compromised. The only thing you can trust is the server. – Raymond Chen Jan 15 '22 at 17:40

2 Answers2

1

Simple: In your Laravel project you store the time when the user started the exam and you create a cron job that will periodically run and check whether any of the exams' time elapsed. If so, then handle that exam as failed, since the user failed to send in the answers in time.

You will not need to worry then about how the user may change the JS code, since if the server is aware of when the exam has started, then it's irrelevant what the student or the browser claims.

Your main issue is that your website assumes that the user's browser has accurate information. But the user will be able to change the JS code as they please.

You can make it more difficult to your users by wrapping a function around all your Javascript, like

function() {
    //your JS code
}();

in which case at least your functions will not be in global context. But that can be hacked as well.

Let me explain why you cannot prevent this from happening by any means:

  • One can create a small project that has the same HTML, JS as the ones you have on your site
  • Adding a local server that will be used as a proxy
  • And the user's time will simply be a constant

Even easier: The user can simply put a breakpoint somewhere in the Javascript code while he/she thinks about the solutions and then his/her time will never pass.

Never trust user data.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
1

Put your function in self executing function as below

 (function runCounter() {   
   let min = 45;   
   let sec = min * 60;  
 
   let x = setInterval(function() {
        console.log(secFormat(sec))
        sec -= 1;
    
        if (sec <= 0) {
          endExam();
          clearInterval(x);
        }   }, 1000); }
    )();

so its variables becomes private to external enviroment, i.e to console

ndotie
  • 1,830
  • 17
  • 18