3
\$\begingroup\$

So, recently in the Hello World CnR challenge I've come across this crack to my submission.

I don't think it's ever clearly defined before in any CnRs what exactly is allowed as an input and what is not.

So, what exactly constitutes a valid input to a function? What is allowed and what is not allowed?

\$\endgroup\$
2
  • 1
    \$\begingroup\$ How is that crack different from the crack you said was correct? \$\endgroup\$
    – Stephen
    Commented Aug 7, 2017 at 18:20
  • 1
    \$\begingroup\$ @StepHen You can see my own solution which does not involve any global variables. I accepted that crack and this one as valid because it's trivial to wrap the extra stuff inside the payload. The one linked in the question, however, is not possible. \$\endgroup\$
    – Voile
    Commented Aug 7, 2017 at 18:23

9 Answers 9

4
\$\begingroup\$

Input should not rely on existing custom state

The value given as input should not rely on any other state - global variables, environment variables, etc. - created by the robber. It may set this state itself, but cannot rely on them being set prior to the input being given to the function.

The following JavaScript is valid, since the input does not rely on any external state - although a global variable is created, it is not important for the input to work (only for creating the input);

obj = {a: 1};
f(Object.freeze(obj));

The following JavaScript is invalid, since the input relies on non-input state (namely that there exists a global function called g):

g = () => "Hello, World!";
f("g"); // f = string => eval(string)()

The following JavaScript is valid, since the input creates the state itself (it creates a global variable called g)

input = "g=()=>'Hello, World!',g";
f(input); // f = string => eval(string)()

The following JavaScript is not valid, since it relies on non-input state (namely overwriting a variable used by the cop)

v = () => true;
f([]); // v = [].every; f = array => v.call(array, v=>v)
\$\endgroup\$
3
\$\begingroup\$

Robber answer should not completely modify the language's behaviour such that passing any solution is trivial

...Which is called a hack, not a crack. It's a standard loophole.

e.g Overriding equality and comparison operators for everything in the language (Ruby, and C++, I'm looking at you).

\$\endgroup\$
4
  • \$\begingroup\$ Lets divide to hacks, intended crack, unintended cracks. This is unintended crack, not hack. Another example of Hack & Crack \$\endgroup\$ Commented Aug 8, 2017 at 5:56
  • \$\begingroup\$ @ЕвгенийНовиков I opened this meta post exactly because that answer is stretching the definition of "input" too far, though. If that is allowed as a input, any code that completely overwrites the cop function would be allowed, and every cop becomes trivial. (Even things like f=_='' can be cracked effortlessly.) I'd definitely say this is against the spirit of CnR challenges. \$\endgroup\$
    – Voile
    Commented Aug 8, 2017 at 6:42
  • \$\begingroup\$ First example isn't override. It usable only in this case, and can't make another CnR trivial \$\endgroup\$ Commented Aug 8, 2017 at 6:44
  • \$\begingroup\$ It depends on eval \$\endgroup\$ Commented Aug 8, 2017 at 6:45
2
\$\begingroup\$

Robber inputs should be standalone and performs all the necessary tasks (including global assignments) at least after being passed into the function

So, for example, given this cop:

from random import uniform
def f(a):
    return a == uniform(0,float('+inf'))

This Python class which is equal to anything is a valid input because it stands up to itself:

class Wildcard(object):
    def __eq__(self, other):
        return True
w = Wildcard()
print(f(w))

This JS snippet, however, is not:

Cop: 
f=()=>1==2

Robber:
f=()=>2==2,f('foobar')

or:

Cop:
g=()=>false,f=()=>g()

Robber:
f((g=()=>true))

Because they have effects that occur before the cop function is even evaluated.

If they are performed after the control flow is passed inside the cop function, then it is okay. e.g:

Cop:
f=e=>{i=NaN;while(e!=i);return}

Robber:
f({valueOf:()=>(i=0,0)})

Strictly speaking, every action must be performed at least after the cop function is evaluated. So if the Robber's proposed solution is:

var i=0;
var e={toString:()=>['a','b','c','true'][i++]}

He should transform it so that everything is sit inside a variable:

var e={i:0, toString:()=>['a','b','c','true'][e.i++]}

which would allow one to call the cop solution directly like f(e).

\$\endgroup\$
6
  • \$\begingroup\$ So, is (function () { var i = 0; return { toString() { return [...'abc', 'true'][i++]; } }; }())valid? \$\endgroup\$
    – tsh
    Commented Aug 8, 2017 at 5:27
  • \$\begingroup\$ In JS submissions not all inputs are evaluated. Sometimes robber need to create object with special properties, then pass it \$\endgroup\$ Commented Aug 8, 2017 at 6:00
  • \$\begingroup\$ example \$\endgroup\$ Commented Aug 8, 2017 at 6:09
  • 1
    \$\begingroup\$ To clarify a bit: An input which stands to itself should still work if you put this input into a variable, create a fresh new context, define the cop program again there and pass the variable directly into the cop program. This is more in spirit of what a input actually is. \$\endgroup\$
    – Voile
    Commented Aug 8, 2017 at 6:35
  • \$\begingroup\$ @Voile Agree, that override of robbers program is hack. Some of that are boring, some not. \$\endgroup\$ Commented Aug 8, 2017 at 9:54
  • \$\begingroup\$ Not necessary; you can do the same thing for the python submission with type("Wildcard",(object,},{"__eq__":lambda:True})() \$\endgroup\$ Commented Aug 11, 2017 at 13:26
2
\$\begingroup\$

Input should match what the cop function actually receives

or

Input is not a statement

A typical way of stretching the definition of input too far is when said "input" is a statement, and only the evaluated result of it is actually passed into the cop function.

For example:

cop:
f=_=>[].some(e=>e)

robber:
f(Array.prototype.some=_=>true)

This proposed input is not an input because while the robber proposed Array.prototype.some=_=>true, what the function actually receives is Array.prototype.some (or _=>true), which does not match what the robber has stated.

Additionally, passing in either of the two actual input above (that the cop function actually receives) doesn't work:

f(Array.prototype.some) // -> false
f(_=>true) // -> false

Which means this robber crack is not valid.

\$\endgroup\$
2
  • \$\begingroup\$ I feel this is redundant. By definition, the input is what the function receives. If you decide to throw more code in between the parentheses when calling the function, then that is fine - but it is not part of the input if it is not part of what the function receives. \$\endgroup\$
    – Birjolaxew
    Commented Aug 9, 2017 at 7:57
  • \$\begingroup\$ Yes, I raised this as a separate answer because some robbers are providing input that is of this specific form (statement that is composed by a side effect + an actual input). \$\endgroup\$
    – Voile
    Commented Aug 9, 2017 at 8:05
1
\$\begingroup\$

Crack can be object, modifed before sending

JS example

Cop's sumbission

var crackme = x => { x["foo"] = ""; if(x["foo"] == "bar"){ return "OK"; } }

Robber's crack

var key = {"foo":"bar"};
Object.freeze(key);
crackme(key);
\$\endgroup\$
5
  • \$\begingroup\$ @IanH. = isn't mistake! ) \$\endgroup\$ Commented Aug 8, 2017 at 6:12
  • \$\begingroup\$ My bad, misread the statement. \$\endgroup\$
    – Ian H.
    Commented Aug 8, 2017 at 6:12
  • \$\begingroup\$ @IanH. It's not a bug, it's a feature ) \$\endgroup\$ Commented Aug 8, 2017 at 6:13
  • \$\begingroup\$ Never said that it's a bug. \$\endgroup\$
    – Ian H.
    Commented Aug 8, 2017 at 6:14
  • \$\begingroup\$ @IanH. Oh, its a joke \$\endgroup\$ Commented Aug 8, 2017 at 6:14
1
\$\begingroup\$

Microcontroller input can be series of I/O signals

With timings if needed.

Also it can use UART, USB or another same periphericals

Microcontroller

\$\endgroup\$
1
\$\begingroup\$

Input can be interactive

stdin <-> stdout

Howto

We need to make a biderectional pipe

mkfifo fifo0 fifo1
prog1 > fifo0 < fifo1 &
prog2 < fifo0 > fifo1

Minuses

  • tio doesn't support it now

Pluses

  • Way to new extraordinary cracks
  • We can patch tio to add this support
\$\endgroup\$
1
\$\begingroup\$

If the cop's code has a "natural way" of getting input, that's the only thing allowed to use by default

Consider this cop. It shows TeX code that reads input from stdin using \read16to. This is a clear indicator that your input should indeed come from stdin.

Now, TeX allows to call a program from within a code snippet you provide at the commandline, and I used this in my suggested crack to first redefine one of TeX's macros before the cop code is executed. According to the general rules in the challenge, input may come from command line arguments as well. But it conflicts with what I said above. Therefore, I suggest the following guidelines:

  • Input should use the "natural way" that's obviously provided by cop's code if not explicitly stated otherwise in cop's description.
  • Other forms of input are valid only if you can prove they are strictly necessary for a crack.
  • To avoid any ambiguity, a cop submission should explicitly state which method of input is acceptable.

To clarify: I'm unsure whether my suggested crack would be valid according to these guidelines. I don't see any other way of cracking the cop in question, but that doesn't mean there is none. The cop author claims it's possible using only stdin. I would require such a solution to work with any implementation of TeX, so if it relies on some undocumented behavior of some TeX implementations, I'd consider it "impossible" (because the cop doesn't mention which TeX implementation to use).

Therefore I would now wait and see, I'm just posting this answer as suggested guidelines and a base for discussion.

\$\endgroup\$
1
  • \$\begingroup\$ In general, it's a good idea for the cop to mention how the input is fed into the cop program because there are many possible ways to do this (inline code? function argument? stdin? executable arguments?). Clarifying this removes the ambiguity and prevents people from unintentionally cracking their entries by using alternative inputs :P \$\endgroup\$
    – Voile
    Commented Aug 10, 2017 at 6:01
-2
\$\begingroup\$

Input Should Fit Inside the Function Call

Simply put, if your language allows you to place it in between the parentheses (or other language construct), it is allowed. If you cannot place it in between the parentheses (or other), it is not allowed.

If you cannot pass it to the function as is, you can't pass it. If, for example, your language doesn't support anonymous functions or anonymous objects, then unless the cop explicitly states that you have to construct the input outside the function call, you can't.

\$\endgroup\$
1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .