Developer Update - 23 February 2023

I’m more talking about the low level parts of retrieving content. For HTTP you have a http client (in this case it’s really only HTTP GET that is used) that uses TCP packages (TCP client).
I’m not too concerned with the parsing of strings or images themselves.

And considering that it’s not unlikely that Unity’s handling of this low level parts can have vulnerabilities, then a malicious server can send a crafted TCP packet (or HTTP response) that can break stuff.
Of course it could be that sandboxing can prevent any further harm, but at this level its also possible to break sandboxing. Because now you are loading data at runtime instead of compile time, and loading data that can cause undefined behavior. Of course it could also be that EAC terminates the program at this point, so might be that the worst that ever could happen is the game crashing for the user point of view.

This is more on the unlikely side of things I’ll give that, but both considering the amount of users. And the fact that there are some very eager hackers out there, that would do this kind of stuff simply for the “shits and giggles” well…

Granted the primary reason for the whole trusted/untrusted URL thing was originally most likely just to try to prevent unwanted content than malicious content/malware.
And this issue I’m describing is not really a new one in that sense. But it is more widely exposed if world creators always expect users to have untrusted URLs enabled.

As someone who has both programmed low-level network drivers and entire HTTP servers, I can 100% assure you that that’s not possible. You cannot gain remote code execution by just sending a string of text, because the processor stores data and code in different sections, so that it may never try to execute data. Especially not if the client script is running in an emulator (which is what Udon essentially is). The worst damage you can do to a Udon script is trigger an exception, in which case the script simply gets disabled. That’s how a sandbox works.
By your logic, video players are a security risk, because someone may upload a malicious video that breaks the video decoder and bricks your system, which is actually more feasible, since video decoders are complex pieces of software that often have bugs. But once again, separate code and data sections means the worst you can do is a crash.

4 Likes

Seconding many of the comments here around the current limitations being very… limiting.

I understand the need for this to be maybe rolled out slowly and carefully, but it would be nicer if limits could be applied smartly and dynamically.

For example, I generally keep my VRC camera in 4k mode now, this means image sizes of 3840x2160 so I’m going to need to process and shrink every photo before it can be shared using this.

I feel like 4k would be a more reasonable limit, or allowing them as a user performance option. If this is a concern about Quest memory usage, well, different sizes could apply per-platform and for when a larger than supported image is downloaded, it could be downloaded but then right away scaled down first to 2k for quest players so it would only briefly spike the memory usage while processing.
If it’s a concern about downloads slowly filling up the user’s RAM with texture files, well, a badly made world or avatar can do that anyway right now, if a world is known to crash due to bad downloading behaviour, it’ll get reported or just fall out of favour, no harm done.

In terms of preventing heavy network traffic, it might be good if rather than long delays between images, this could be smartly scaled? For example, during avatar downloading, image loading could be deprioritised and throttled, or in worlds with a large number of players requiring more voice and navigation traffic it could also be slowed down. And of course, players could have a network throttle control within the UI they could apply if they are on restrictive ISPs.
But for anyone with an unmetered fibre internet, these sorts of limits are kinda silly.

I think download prioritization will be a good adding and specially for the Quest 2.
Perhaps Quest 2 should have a more optimized UIMenu or maybe its own version because when I play and I sometimes try to open the worlds page the quest freezes and since the UIMenu change I feel that the invitations somehow make the game more prone to crashes like it’s too hard for the quest to load an invite
I really liked UIMenu and I believe you are working on improving it and the download prioritization already helps a lot

What does unity do with such an image? Is it dumped into 4096x4096 texture with a lot of wasted pixels? Or does it stretch the image to 4096x4096? You might want to start taking 8k screenshots as those will look better in a 4k texture.

I wonder how well Quest 2 can perform doing that, while still running VRChat in the background.

I really hope VRChat keeps image loading like this long enough to see what can be done. Maybe Bad Apple, but in remote images. Each remote images has to have enough frame data to last 6 seconds

Sorry, too late! :sweat_smile:

Yes! :smiley: I requested this feature a couple of years ago and it’s great to see it’s coming soon.

2 Likes

Aha, someone pointed that out! Seems like I’m far from the first one to think of this, hope it can be of some help to you and others. It’s all I could think about a couple years ago when I had to spend a good 9-10 months on a 15Mbit connection.

Very excited for [REDACTED], I hope it’s helpful.

Sure, this is definitely feasible. However, like I said before, this is just engineering around a forced restriction that barely serves to actually stop a problem that doesn’t exist. It’s extra dev time for something that could be solved with a more dynamic limit with checks for abuse, as well as a way for users to limit the number of requests/bandwidth on their end.

I would find it strange if downloading images and then updating a texture would cost that much performance, especially since it is going to be a temporary FPS/performance drop when the world loads.

Yeah, providers don’t like it when you hammer them with requests. But they should have their own DDOS protection, and it’s less about the number of requests and more about bandwidth. Plenty of websites (including this one) may do a few dozen requests on load, and that’s each time the webpage is loaded (assuming some of the images aren’t cached).

It should not be up to VRChat to impose limits due to other webservers. The only exception I can see is clear abuse (which can be checked by frequency of requests to mark worlds for moderation), or limits to help prevent the clients’ network capacity from being abused (which could be a thing the user sets).

While I agree, it is to prevent abuse with worlds writing and storing data about users. Currently, you could have a user copy and paste a string from one text box into a VRCUrlInputField. With this, I can still store data by putting it into query parameters. This makes sure the user is explicitly consenting to the data being transferred. Perhaps in the future we can have this feature where users can manually whitelist each world, but otherwise, I understand why they made the decision.

If it was unrestricted, I could I send 1 request every 5 seconds with query parameters as long as the VRCUrl allows (especially doing higher bit-depth encoding with alphanumeric and symbols), and who knows what sort of data I can store about the users and their experience in the world. Things like heatmaps would be cool, but at that point, you have the opportunity for random users to collect data on people in Invite Only worlds. What others sorts of data would they try to collect? Could they encode your IK/movement into these requests and have a playback of user positions and timings? It’s a big privacy issue.

2 Likes

Just to add maybe a stick or two to this fire to hopefully promote change for the better,

I’ve been waiting for something like this for ages, as I’d love to be able to store a bunch of small YuGiOh card art images in a GitHub repo, then download them at runtime. (I’m making a world for players to have YuGiOh duels in). I wouldn’t download every card (though that would be the ideal scenario), just a couple hundred or so to help greatly reduce world size (to help the world stay under the shockingly low 100MB quest limit), and development time. I’d also imagine this would be fine since the images are closer to 256x512, not 2048x2048 (so the total size would be around 25-50MB before compression, and around 3-4MB after if compression would even be necessary). But also as others have stated, the 5-second delay makes this, or anything like this, impossible. I’d have to simply load maybe 12 cards at the bottom of the list and settle for that, but at that point why even bother?

And I understand my use case may be a bit extreme, and that I could certainly just download atlases, but the problem still remains. I can only download so many cards using atlases before the delay becomes apparent to the end user (as 2048x2048 doesn’t provide much room for an atlas of 256x512 images), and even then, I’d now have to figure out how to parse those atlases in the first place. The problem isn’t solved, it just changes from “how can I compress these images efficiently” to “how can I download and parse these images without the user noticing”. And despite my case, others have made very valid points. Even the proposed art gallery idea would be janky at best with any delay greater than 2 seconds. It’s a decent start, but that delay makes the feature fairly useless outside of loading a few posters in an atlas, or a couple images/textures.

If a shorter delay wouldn’t be possible (though I know it would be, at least in some capacity), maybe just implement some sort of easy atlasing solution with a higher image size cap? Or maybe allow users to download one single GitHub folder full of tiny images (as a zip file or something similar that the client unzips at runtime) as opposed to… one tiny image… per 5 seconds… and just put a size cap on that. Uhhh, other bad-idea solutions include requiring download links to be approved per world update to make sure they aren’t abusing the system, then greatly reducing the delay to those specific links. Or, as others have mentioned, simply adjusting the delay to something more usable.

3 Likes

This would allow for easy data exfiltration

Was this actually tested and measured? As usually starting a download takes a bit of time to ramp up the speed, and it feels like sometimes connection is also limited, so if someone has a fast internet like 1 Gbps I feel like this change might acually increase download times by all the additional overhead.

Don’t get me wrong, the sorting and all is a great idea and change, just wondering if trying to limit it to 1 concurrent download is good approach, instead of 2? , 3? no idea, just guessing from what i’ve seen before

1 Like

I mean I admit I’m more of a hobby programmer. Though working as a server admin with a strong interest in security.
And so I don’t know everything on the code side, but again I wasn’t thinking about the string og image payload directly. But more on the http and TCP client side of things and their control codes (though TCP client vulnerability is extremely unlikely I admit).

But yes video players are a risk here too. It’s just that the main use would be videos (and music) so it would be (somewhat) harder to coax players into enabling untrusted URLs.
But if you suddenly need it for a lot of worlds to function at all then it’s a different matter. Exposing this potential issue a lot more.

That said I’m not saying this would be a widespread issue, just something that has to be considered.
But yeah, I do agree that the most likely issue that could crop up here is using it for crashing (which is mostly a nuisance).

To be fair… worse remote code execution bugs happened in history, where images or vidoes would be able to trigger it. Tho i still agree its rather not something to worry about in this case.

Remember though that both string and image don’t just necessarily run only on world load, but could potentially be running constantly. And so you have to think about not just about what happens on loading in for the first time, but also what happens if players are in the world for several hours.

5 seconds might be long (too long even), but the alternative would be to build more complex logic that can handle throttle codes, and things like exponential back-off time.
And if you fail to do that you are suddenly sitting with throttled requests that breaks the world outright.

These tools have to not only be made for creators that could know how to handle these things, but also for creators that have no idea. And that just wants to load images or strings from a webhost.

Limiting it to 1 request every second (or every 2 seconds) would usually be within most providers acceptable use though.

I mean it could also be that that the 5 second is there to test the waters first and then will be adjusted later (something like more advanced control logic is in the works but not ready yet).

What data, though? Its not like VRC exposes voice data or other sensitive information to Udon. I’ve seen people here suggest an opt-in to data uploading, similar to how you have to opt-in to using untrusted URLs, which feels like a good compromise, and a good way to inform player that this activity is something that worlds can be capable of.

Player names, world analytics, user input

It doesn’t have to be complex. You count the number of requests and store a timestamp from the first request. If the count hits X number, you don’t allow any more requests. Then once it is Y time from the timestamp, you clear the lock and allow requests again. If you find worlds that abuse it, you report them, or VRChat could auto-flag them for moderation in code.

I would argue that for the rest of VRChat, especially given how many people struggle with Unity and how many extremely poorly optimized avatars there are, I would imagine that sending too many network requests would be the least of our problems. People that know how to handle network requests or even setup their own server are probably going to handle network requests appropriately. At least in the case of world creators, they can probably learn that there is an issue and then fix the issue with the network requests.

Most providers are okay with dozens of requests within milliseconds. Again: If the provider has an issue, they will automatically rate-limit you. This is not the role of VRChat to impose rate limits for the sake of API providers.

This is what I’m hoping for.

Again: Who knows, maybe the 5 second rate limit is the right call. But they are imposing a restriction for problems that haven’t even had the chance to happen yet. I would much rather VRChat let the rate limit by way higher (I’d argue even 100 requests every 10 seconds) and then figure out what issues may exist from it and then come to a better rate limit solution.

Who knows? You have access to a lot of things in the VRChat world, including lots of information about the users. I know this sounds ridiculous, but it is probably possible for people to track IK data or other sorts of data, even in private rooms of say B club, and record them. If users can not consent to their data being tracked outside of VRChat, then that is a problem.

But I do agree with the consent thing, where maybe you can whitelist worlds as you join them if they utilize runtime VRCUrl requests.

Do you plan to add a setting to disable “Remote Images” for people who doesn’t have a good internet connection?

Also, if you rejoin a world or quit VRChat, are the downloaded images cached somewhere or it just downloads over and over every time you join the same worlds ?

1 Like

Hopefully the GeoGuesser world gets updated quickly. That world would profit from being able to always load new and random images so much.

2 Likes