-3

Im having a hard time to understand the use of (-) operator in JS for non math proposes. I have the following code :

let jeff = (new URL(location).searchParams.get('jeff') || "No parameters.");
eval(`ma = "Ma name ${jeff}"`);
document.write(ma)

And the Following URL :

basic.html?jeff=%22-alert(1)-%22

Im having a hard time to understand how the alert is being raised. Appreciate the help.

I was expecting to get a string printed and not the execution of alert function.

  • 2
    `-` operator is subtraction and nothing else, as there is no operator overloading in Javascript (yet). The `-` you see is NOT an operator, it is a string. Do `decodeURI("basic.html?jeff=%22-alert(1)-%22")` and you will get: `'basic.html?jeff="-alert(1)-"'`. So it is part of the URL parameter `jeff`, probably to be used to execute javascript later down the line. – ibrahim tanyalcin Nov 06 '22 at 09:16
  • @SebastianSimon, Actually i tried other operators like plus (+), and only with (-) it executes the alert function. So for : `basic.html?jeff="+alert(1)+"` The JS wont execute the alert function – daniel avihasira Nov 06 '22 at 09:35

1 Answers1

1

What is the subtraction operator - used for in JavaScript, other than math?

This is a strange question, but it’s not the real question you’re asking here.

I’m having a hard time to understand how the alert is being raised.

This is the actual concern.

If you don’t understand how a process like this works, it helps to go through it step by step.

Look at the first line:

let jeff = (new URL(location).searchParams.get("jeff") || "No parameters.");

The URL constructor stringifies its first argument and parses it as a URL. location is the object that holds information about the current page’s URL. It’s stringified as the full URL. The searchParams property is a URLSearchParams object, which holds all the query parameters of the URL, such as ?jeff=%22-alert(1)-%22, in a structured, decoded way. .get("jeff") attempts to get the value of the jeff parameter.

Note that URLs are subject to encoding. %22 is the percent encoding of the quote character "; %2B is the percent encoding of the plus character +; + is the URL encoding of a single space ; and so on.

The || "No parameters." defaults to the string "No parameters." if the jeff parameter is empty or not present. If your location is https://example.com/?jeff=%22-alert(1)-%22 The result, which is assigned to the variable jeff, is '"-alert(1)-"'.

Second line:

eval(`ma = "Ma name ${jeff}"`);

`ma = "Ma name ${jeff}"` is a template literal which interpolates the variable jeff into the rest of the string; the resulting string is 'ma = "Ma name "-alert(1)-""'. eval executes strings as code. So, effectively, this line says: ma = "Ma name "-alert(1)-"" (or somewhat cleaner: ma = "Ma name " - alert(1) - "";).

This subtracts alert(1) from "Ma name ", and then subtracts "" from that intermediate result. In order to evaluate this, alert(1) is executed. That’s how the alert window appears. Both the intermediate and the final result are NaN, because they involve the return value from the alert, namely undefined. NaN is then assigned to the variable ma.

Third line:

document.write(ma)

This just writes the resulting NaN (as the string "NaN") into the open document stream (or, if closed, opens a new one, then writes into it).


Run this snippet to examine the intermediate results. Note that the eval and the reference to the real location have been removed in the snippet; this is just to give you a general idea of how intermediate results might be examined.

const locationHref = "https://example.com/?jeff=%22-alert(1)-%22",
  urlObject = new URL(locationHref),
  searchParams = urlObject.searchParams,
  jeffParameter = searchParams.get("jeff"),
  jeff = jeffParameter || "No parameters.",
  jeffIfNotFound = null || "No parameters.",
  interpolatedString = `ma = "Ma name ${jeff}"`;

console.log({
  locationHref,
  urlObject,
  searchParams, // Look at this in your browser console; the Stack Snippet doesn’t show a very useful representation.
  jeffParameter,
  jeff,
  jeffIfNotFound,
  interpolatedString
});
.as-console-wrapper { max-height: 100% !important; top: 0; }

Back to your first question:

What is the subtraction operator - used for in JavaScript, other than math?

There is nothing special about - in this code. Try any of the operators in this query string: ?jeff=%22**alert(1)/alert(1)*alert(1)>>>~alert(1)^alert(1)===alert(1)||!alert(1)<%22, and many more; this’ll alert six times with the meaningless result 1.

The Subtraction Operator is only used for math. Any other application is either a hack or meaningless.

Actually, I tried other operators like plus (+)

But you didn’t URL-encode it correctly.

new URLSearchParams("jeff=a+b").get("jeff"); // Result: "a b".
new URLSearchParams("jeff=a%2Bb").get("jeff"); // Result: "a+b".
new URLSearchParams("jeff=a%2Bb%25c%26%26d").get("jeff"); // Result: "a+b%c&&d".

The + works just the same way. The important thing is that functions will execute in order to be evaluated. If they’re somewhere in the middle of operators, then they’re the operands which will be evaluated; it doesn’t matter which operators are used (unless they’re short-circuiting, in which case evaluation may be skipped).

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75