Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
every time someone writes a clever thing that Just Works Without Any Code by using intense amounts of reflection it ends up being vulnerable to a million things like this by default which all have to specially patched out, and yet you will never convince anyone that this is a bad way of writing software

like yes this should definitely not expose the class but really it should only expose things that opt in to being exposed (and ideally opt in for each specific purpose) and at that point maybe you’re not really getting as much from reflection as you originally dreamed and maybe clients should just be calling into a specifically planned interface

Adbot
ADBOT LOVES YOU

Amethyst
Mar 28, 2004

I CANNOT HELP BUT MAKE THE DCSS THREAD A FETID SWAMP OF UNFUN POSTING
plz notice me trunk-senpai
Maybe reflection is a bad idea in general

Quackles
Aug 11, 2018

Pixels of Light.


I still don't understand what reflection is.

brains
May 12, 2004

Quackles posted:

I still don't understand what reflection is.

turn your monitor off

Shame Boy
Mar 2, 2010

Quackles posted:

I still don't understand what reflection is.

you see that class? you can query that class. at runtime!

Shame Boy
Mar 2, 2010

serious answer: in languages like C++ a "class" is more or less a convenient abstraction around some functions and a chunk of memory, once it gets compiled there's not really much information about the structure of the class (in terms of human-readable code structure, anyway) it's all just memory locations and such. in languages like java however a bunch more information about the class gets saved along with it (its fully qualified name, method names, variable names etc.) which means you can then dynamically mess with that information at runtime, to do mundane stuff like determine what specific sub-class an object is if you only know its general parent class, or exciting stuff like "let users pass in arbitrary strings that you then look up against classes to see if that class has the string as a function name, then call the function"

it's called reflection because the program can look at itself you see

Shame Boy fucked around with this message at 09:48 on Mar 31, 2022

distortion park
Apr 25, 2011


rjmccall posted:

every time someone writes a clever thing that Just Works Without Any Code by using intense amounts of reflection it ends up being vulnerable to a million things like this by default which all have to specially patched out, and yet you will never convince anyone that this is a bad way of writing software

like yes this should definitely not expose the class but really it should only expose things that opt in to being exposed (and ideally opt in for each specific purpose) and at that point maybe you’re not really getting as much from reflection as you originally dreamed and maybe clients should just be calling into a specifically planned interface

Why where they even motivated to use reflection in this case though? Surely the endpoint knows what data shape it is expecting? (Working out the expected data shape might use reflection but I don't see why that would happen during the http req/res flow)

4lokos basilisk
Jul 17, 2008


distortion park posted:

Why where they even motivated to use reflection in this case though? Surely the endpoint knows what data shape it is expecting? (Working out the expected data shape might use reflection but I don't see why that would happen during the http req/res flow)

well what if we make the endpoint dynamically and enterprisely automatedly do different things depending on what type of objects get sent to it

and what if we do all this because we can, and never think about how it can be abused :)

Powerful Two-Hander
Mar 10, 2004

Mods please change my name to "Tooter Skeleton" TIA.


distortion park posted:

Why where they even motivated to use reflection in this case though? Surely the endpoint knows what data shape it is expecting? (Working out the expected data shape might use reflection but I don't see why that would happen during the http req/res flow)

I mean there are legit reasons why you might not know the concrete type e.g. it's implementing an interface and you don't know what sort of IFart it is from inspection and you have to tell the endpoint "this is actually type MyFart", but I'd say that you should make the types available to create limited to explicitly defined implementations only and also not let you call methods arbitrarily either, or in fact at all.

redleader
Aug 18, 2005

Engage according to operational parameters

Kitfox88 posted:

number 2 factor authentication

BlankSystemDaemon
Mar 13, 2009



rafikki posted:

yeah, I’m trying to sift through the noise to figure out how seriously to take all this
eeh, about an 8.8, op

Powerful Two-Hander
Mar 10, 2004

Mods please change my name to "Tooter Skeleton" TIA.


Penisface posted:

well what if we make the endpoint dynamically and enterprisely automatedly do different things depending on what type of objects get sent to it

and what if we do all this because we can, and never think about how it can be abused :)

or ofc you could do this and loudly proclaim your genius at "creating a system where we define the behaviour as config not code" just like all those "generates SQL in the browser and passes it as a string to an exec handler" disaster zones that used to get created

Amethyst
Mar 28, 2004

I CANNOT HELP BUT MAKE THE DCSS THREAD A FETID SWAMP OF UNFUN POSTING
plz notice me trunk-senpai

distortion park posted:

Why where they even motivated to use reflection in this case though? Surely the endpoint knows what data shape it is expecting? (Working out the expected data shape might use reflection but I don't see why that would happen during the http req/res flow)

in spring you can just write a http endpoint like this:

code:
@RequestMapping(value = "/echodogname", method = "POST")
public String echoDogName(Dog dog){
	return dog.name;
}
so if you call this endpoint with a json payload {"name" : "rex"} spring will automatically map the name to the "name" property of the dog, using the Dog.setName() function.

spring figures all of this out dynamically by examining the structure of the dog object at runtime.

If it didn't do this the function would be way longer. Java is staticly typed, it's not like javascript where you can just come up with a dynamically structured object on the spot. You would have to tell java explicitly how to map each property.

Amethyst
Mar 28, 2004

I CANNOT HELP BUT MAKE THE DCSS THREAD A FETID SWAMP OF UNFUN POSTING
plz notice me trunk-senpai
reflection is everywhere in java land and it's hard to read and annoying

for some reason people hate using abstract classes now and the way to call methods on child classes is to by retrieving the method by it's name via reflection and invoking it. why? WHY? this is what abstract classes are for

BattleMaster
Aug 14, 2000

Shame Boy posted:

serious answer: in languages like C++ a "class" is more or less a convenient abstraction around some functions and a chunk of memory, once it gets compiled there's not really much information about the structure of the class (in terms of human-readable code structure, anyway) it's all just memory locations and such. in languages like java however a bunch more information about the class gets saved along with it (its fully qualified name, method names, variable names etc.) which means you can then dynamically mess with that information at runtime, to do mundane stuff like determine what specific sub-class an object is if you only know its general parent class, or exciting stuff like "let users pass in arbitrary strings that you then look up against classes to see if that class has the string as a function name, then call the function"

it's called reflection because the program can look at itself you see

my hot take is that language constructs shouldn't really continue to exist in an identifiable way after compilation

Main Paineframe
Oct 27, 2010
reflection is what you use when the language design or the framework design say you shouldn't mess with something, but you want to mess with it anyway because you feel like you found a really clever way to do things

Cybernetic Vermin
Apr 18, 2005

reflection is good for decoupling, code where every component has to be aware of and relate to the type hierarchy of every other component becomes a mess. it is simultaneously true that one needs to be careful and it should be designed with more concern for security, but pretending that we should just not do it is where you instead start passing around random string serializations or untyped collections of stuff all over the place, and probably ultimately recreating dynamism by doing some even worse eval() garbage.

Cybernetic Vermin fucked around with this message at 15:16 on Mar 31, 2022

akadajet
Sep 14, 2003

spankmeister posted:

This video explains the whole blockchain game scam (and straight up exploitation of labor) quite well:

https://www.youtube.com/watch?v=YQ_xWvX1n9g&t=5909s

I can't follow any of this, and I'm sure that's by design.

4lokos basilisk
Jul 17, 2008


Cybernetic Vermin posted:

reflection is good for decoupling, code where every component has to be aware of and relate to the type hierarchy of every other component becomes a mess. it is simultaneously true that one needs to be careful and it should be designed with more concern for security, but pretending that we should just not do it is where you instead start passing around random string serializations or untyped collections of stuff all over the place, and probably ultimately recreating dynamism by doing some even worse eval() garbage.

if integration points between different components are allowed to become so finicky that you need reflection or some other magical technology, i would argue that the design is too complex.

admittedly i am thinking about REST endpoints here, which in microservice land need to be decoupled so that client/service code can evolve independently. isn’t this why the standard is json/xml for transmitting complex data, and not a magically serialized java object?

Cybernetic Vermin
Apr 18, 2005

Penisface posted:

if integration points between different components are allowed to become so finicky that you need reflection or some other magical technology, i would argue that the design is too complex.

admittedly i am thinking about REST endpoints here, which in microservice land need to be decoupled so that client/service code can evolve independently. isn’t this why the standard is json/xml for transmitting complex data, and not a magically serialized java object?

the reason the standard is xml/json is to make it go on a wire, do you figure that in general the solution lies in having less strong typing and encapsulation?

distortion park
Apr 25, 2011


Amethyst posted:

in spring you can just write a http endpoint like this:

code:
@RequestMapping(value = "/echodogname", method = "POST")
public String echoDogName(Dog dog){
	return dog.name;
}
so if you call this endpoint with a json payload {"name" : "rex"} spring will automatically map the name to the "name" property of the dog, using the Dog.setName() function.

spring figures all of this out dynamically by examining the structure of the dog object at runtime.

If it didn't do this the function would be way longer. Java is staticly typed, it's not like javascript where you can just come up with a dynamically structured object on the spot. You would have to tell java explicitly how to map each property.

I get the role of reflection to simplify the API code, but not why this seems to be used at request handling time (as opposed to at startup time or equivalent). i.e. the expected fields should come from the definition of Dog (which presumably wouldn't include anything other than "name", and is known at startup in theory) rather than from the data that is being sent.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Generally you want your code to be using strongly-typed model classes instead of, idk, using a hashmap or some similar kind of bag with strings as keys and you're never really sure whether a given field actually exists or not.

To transform a serialised wire format into that strongly-typed class, you basically have three choices:
- Hand-written code that transforms the serialised format into your strongly-typed class
- A code generator reads your schema and creates ^. Sometimes this also generates your strongly-typed class itself.
- A reflective framework that determines at runtime how to fill in your strongly-typed class from the serialised wire format.

I generally advocate for the second option, but there are use cases for the other two.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Kitfox88 posted:

number 2 factor authentication

Shamefully overlooked post

Cybernetic Vermin posted:

reflection is good for decoupling, code where every component has to be aware of and relate to the type hierarchy of every other component becomes a mess. it is simultaneously true that one needs to be careful and it should be designed with more concern for security, but pretending that we should just not do it is where you instead start passing around random string serializations or untyped collections of stuff all over the place, and probably ultimately recreating dynamism by doing some even worse eval() garbage.

Reflection is pretty neat, conceptually, though there are obvious security concerns so care needs to be taken.

One use case for reflection is to examine a class for a specific attribute, and to allow for annotation based preprocessing. For example, JUnit has the @Before, @After, and @Test annotations, which are the most common ones, although there are others. At runtime, the testing framework can examine every class in the test suite, and determine how to set up / run / tear down the test at runtime. Similarly, dependency injection can be provided for arbitrary classes (see Google Guice); if you can inspect the constrictor for the class, and all of the members with @Inject, you can determine how to build it at runtime. There's annotation preprocessing, which allows for compile time dependency injection like Dagger, but that's another can of worms, especially when debugging.

As mentioned above, if you're an idiot, or dealing with 3rd party code, you can inspect otherwise private member contents / functions and change their visibility / invoke them / etc at runtime. This is usually a bad idea, but it might be necessary in certain circumstances.

You may be writing a framework that wants to know if certain other plugins do/do not exist in the runtime, without having to know about them at compile time. Think of being able to load all DLLs in a directory; this can be but is not always a good thing. I can create a turd module for your butt framework which is then available at runtime to expose to a user so that they can choose it for the poo poo action, in addition to the Blood and Brick modules that support it.

It has perfectly valid reasons to exist, and perfectly valid reasons to not want it to exist.

E: JNI, which is how Java communicates back and forth between native code and bytecode, necessarily needs to use reflection due to the nature of running in a VM and thus not being able to just link to the class from native code. JNI is pretty interesting stuff, though that's less reflection and more limited to things you should already know about.

Volmarias fucked around with this message at 16:15 on Mar 31, 2022

Achmed Jones
Oct 16, 2004



i made people patch some reflection bugs like this at oldjob. they werent happy to do it. i hope they see this news and remember and say "hey thanks achmed"

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Achmed Jones posted:

i made people patch some reflection bugs like this at oldjob. they werent happy to do it. i hope they see this news and remember and say "hey thanks achmed"

They won't

Achmed Jones
Oct 16, 2004



Volmarias posted:

They won't

O_O

distortion park
Apr 25, 2011


Jabor posted:

Generally you want your code to be using strongly-typed model classes instead of, idk, using a hashmap or some similar kind of bag with strings as keys and you're never really sure whether a given field actually exists or not.

To transform a serialised wire format into that strongly-typed class, you basically have three choices:
- Hand-written code that transforms the serialised format into your strongly-typed class
- A code generator reads your schema and creates ^. Sometimes this also generates your strongly-typed class itself.
- A reflective framework that determines at runtime how to fill in your strongly-typed class from the serialised wire format.

I generally advocate for the second option, but there are use cases for the other two.

That's a nice breakdown thanks. I guess my thinking is that a good version of 3 should be basically equivalent to 2, you just define the schema using the language native types rather than starting with a custom schema format. In almost all sensible use cases it shouldn't be using the incoming data as the starting point for deserialization (outside of known discriminator fields)

Quackles
Aug 11, 2018

Pixels of Light.


brains posted:

turn your monitor off

my screen is all scratched up :(

Cybernetic Vermin
Apr 18, 2005

beyond reflection i do wonder how many hilariously huge security bugs hide in dumb use of cglib across the java ecosystem. harder to analyse, but i expect the new interest in this stuff will get there in time.

one problem certainly that the tools involved are so blunt (i.e. reflection just breaking into intended-to-be-encapsulated data), but more than that there is so much unprincipled use where it should almost all be wrapped up in a reasonably carefully validated libraries.

Shame Boy
Mar 2, 2010

BattleMaster posted:

my hot take is that language constructs shouldn't really continue to exist in an identifiable way after compilation

i like that the capybara's back, by the way :3:

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

Jabor posted:

Generally you want your code to be using strongly-typed model classes instead of, idk, using a hashmap or some similar kind of bag with strings as keys and you're never really sure whether a given field actually exists or not.

To transform a serialised wire format into that strongly-typed class, you basically have three choices:
- Hand-written code that transforms the serialised format into your strongly-typed class
- A code generator reads your schema and creates ^. Sometimes this also generates your strongly-typed class itself.
- A reflective framework that determines at runtime how to fill in your strongly-typed class from the serialised wire format.

I generally advocate for the second option, but there are use cases for the other two.

java in particular makes it sufficiently trivial to integrate compile-time codegen into your build that doing it at runtime should be an incredibly niche thing. in other languages it's sometimes a nightmare hassle to use codegen and there's a much stronger case for doing it at runtime.

distortion park posted:

That's a nice breakdown thanks. I guess my thinking is that a good version of 3 should be basically equivalent to 2, you just define the schema using the language native types rather than starting with a custom schema format. In almost all sensible use cases it shouldn't be using the incoming data as the starting point for deserialization (outside of known discriminator fields)

where people inevitably run into security problems is when they try to make runtime things which are more flexible than what you can do with compile-time things. suppose instead of taking a concrete class your function takes an IFoo and the deserialization figures out which implementing class to generate. in a codegen-based approach you obviously need to have a fixed set of possible classes at compile time, but in the runtime reflection version you might be tempted to support things like dynamically loading new jar files that contain class definitions if the input json says it should be a concrete type that you don't have loaded. this lets you do all sorts of cool things that you couldn't do otherwise and you can brag about how much more powerful your thing is than the competing library based on codegen, but it also basically always results in giant security problems.

the 1st amendment
Mar 10, 2022

by Jeffrey of YOSPOS
whoopsie daisy

BattleMaster
Aug 14, 2000

Shame Boy posted:

i like that the capybara's back, by the way :3:

I thought the pulp space pirate lady was kind of neat (I got it when a big pile of pulp magazine art was handed out as avatars) but capybaras are obviously the superior subject for avatars

Kesper North
Nov 3, 2011

EMERGENCY POWER TO PARTY
As a former enterprise Java developer I want to say that hearing all of your opinions about all of this is incredibly empowering, because these issues were part of what led me to loving hate writing code for a living, and reflect the security concerns I raised while working on and contributing code to open source projects like, uhh, log4j and, er, spring

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
the security industry thanks you for your service :patriot:

Agile Vector
May 21, 2007

scrum bored



brains posted:

turn your monitor off

:golfclap:

spankmeister
Jun 15, 2008






akadajet posted:

I can't follow any of this, and I'm sure that's by design.

yes. all of that stuff exists solely to get you to buy their funny money, because they need more suckers to buy into the scam for them to make money

Zamujasa
Oct 27, 2010



Bread Liar
reflection and "hmm i will just investigate this string. ah, a class exists. i will stuff things into it" sounds like a violation of security rule #1, never trust user input


granted i also think that the current hyperfocus on microservices for everything is dumb

Beyond ReTarTed.
Dec 19, 2021

by Jeffrey of YOSPOS
4k dementia

Adbot
ADBOT LOVES YOU

redleader
Aug 18, 2005

Engage according to operational parameters
if you're deserializing something directly into an interface, you deserve every problem you get

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply