May 4th 2025: Today I Learned (TIL)


Today I noticed the Report-To
response header and learned that it’s a header that the browser consumes / uses and sends reports. For example, I noticed this while I was trying to apply to many companies on https://www.instahyre.com/ automatically using JavaScript. I opened up the list of jobs page at https://www.instahyre.com/candidate/opportunities/?matching=true or the list of jobs page in a search, like https://www.instahyre.com/candidate/opportunities/?company_size=0&job_functions=%2Fapi%2Fv1%2Fjob_function%2F8&job_type=0&search=true or https://www.instahyre.com/candidate/opportunities/?company_size=0&job_functions=%2Fapi%2Fv1%2Fjob_function%2F8,%2Fapi%2Fv1%2Fjob_function%2F10&job_type=0&search=true
Initially I was clicking the Apply
button a lot. At some point I realized I could use JavaScript, not exactly on my own maybe, instead I was bored clicking blindly and I recalled someone mention to use JavaScript to apply on LinkedIn and I was like “Hmm, why not just try that this time?”. So, I did try
I used the following JavaScript code and pasted it in my Google Chrome Browser Console window
Note: Weirdly it didn’t ask me to first type
allow pasting
or something of that sort, to prevent randomly just copy-pasting JavaScript code that I don’t know anything about, which could steal API tokens, cookies, personal information, credential information, using web requests and/ using the web page (front-end) and send it over to some remote server of the hacker
// without retrying for rate limiting errors
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function clickButtons() {
let start = Date.now()
let i = 0;
while (true) {
let error = document.querySelector("#messages > div > div > div > div > div")
if (error) {
console.log("Found some error");
let closeErrorButton = document.querySelector("#messages > div > div > div > button");
if (closeErrorButton) {
console.log("Closing the error");
closeErrorButton.click();
}
console.log("Gonna exit now");
let end = Date.now();
console.log("time elapsed in milliseconds is: ", end - start);
break;
}
await sleep(500);
let button = document.querySelector("#candidate-suggested-employers > div > div:nth-child(3) > div > div > div.application-modal-wrap > div.container > div.row.bar-actions.ng-scope > div.apply.ng-scope > button");
if (button && !button.disabled) {
button.click()
i++;
console.log(`clicked ${i} times`)
}
}
}
clickButtons();
When I did this automation, I noticed an error on the front-end at some point, which said something like “Something went wrong. Please try again later”. On checking, it was clear that Instahyre had implemented Rate Limiting on their backend systems, which is a great thing. I noticed that their apply
endpoint was giving a 429
HTTP response, which translates to Too Many Requests
and in the response, I noticed that it says some interesting things in the Response Headers, like Retry-After
, Report-To
etc
I used the Retry-After
to understand when I can retry later. I think it was around 30 minutes, in seconds. I’m not sure what’s the retry-after time when this rate limiting is violated the second time, third time etc. Usually it’s an exponential backoff, at least that’s kind of ideal, where the retry-after time just keeps increasing, and that too increasing exponentially, so that the attacker (in many cases) is stopped from bombarding the backend systems with requests
You can quickly do a search of retry-after header
and you will get details, for example - https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Retry-After and other search results
I generally trust the Mozilla Developer Network (MDN) documentation and website, and also trust the AI answers (which usually gives links to it’s source) and also Stack Overflow answers
I also noticed how there’s a Report-To
header, which basically tells the client, in this case, our browser, to report this incident somewhere. Where? That’s mentioned in the Report-To
header. I’m guessing that the browser does this automatically and that this implementation is done in the browser’s code, or else, the front-end code (JavaScript, TypeScript etc) has to do this I guess? Not sure
Looking at https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/report-to , looks like it’s not implemented in all browsers as of this writing. You can also find some information at https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Report-To
Report-To
is actually part of CSP Directives / Headers. CSP is short for Content Security Policy. https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy and you can find directives, reporting directives etc in it
On reading a bit more, especially at https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Report-To , you will notice that Report-To
has been deprecated and not recommended and has been replaced by Reporting-Endpoints
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Reporting-Endpoints
You can also read more about Content Security Policy and related things at
Subscribe to my newsletter
Read articles from Karuppiah Natarajan directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Karuppiah Natarajan
Karuppiah Natarajan
I like learning new stuff - anything, including technology. I love tinkering with new tools, systems and services, especially open source projects