Mojira Archive
MC-251677

You can poison Player Skin Caches

The bug

On the client side, a Minecraft skin hash is created by just sha1 hashing the part after the last '/' of the full skin URL (Mojang method com.mojang.authlib.minecraft.MinecraftProfileTexture.getHash()).

So the this would be a normal Minecraft texture:

http://textures.minecraft.net/texture/266f1aaf89456c1f222dce18fbefd823e3d23ba5067bf3fe3aa94adb11990fce

But because it uses the last '/' of the complete URL (instead of only the path of the URL), you can append a URL query component, such as:

?name=texture/2e002d5e1758e79ba51d08d92a0f3a95119f2f435ae7704916507b6c565a7da8

So the complete URL looks like this:

http://textures.minecraft.net/texture/266f1aaf89456c1f222dce18fbefd823e3d23ba5067bf3fe3aa94adb11990fce?name=texture/2e002d5e1758e79ba51d08d92a0f3a95119f2f435ae7704916507b6c565a7da8

The client now thinks that the texure it is loading is for 2e002d5e1758e79ba51d08d92a0f3a95119f2f435ae7704916507b6c565a7da8, thus you can poison the skin cache (.minecraft/assets/skins).
The poisoning itself needs to be done with a head, as otherwise the texture would fail due to the signature check.

That means that when the client tries to load 2e002d5e1758e79ba51d08d92a0f3a95119f2f435ae7704916507b6c565a7da8, it actually shows the skin for 266f1aaf89456c1f222dce18fbefd823e3d23ba5067bf3fe3aa94adb11990fce.

This works for skins and capes that the player has not yet loaded aswell.

To solve this, maybe the sha1 hash should be calculated over the complete URL instead of only over a specific part of it (?).

Reproduction steps

  1. Make sure you don't have the skin for jeb_ cached locally; delete the following file, in case it exists:
    .minecraft/assets/skins/d1/d1373840bf22e36cc2a1205e27b5b9c948f00cb8
    
  2. Start Minecraft and open any world
  3. Use the following command to obtain a "poisoning" player head (has to be executed by a command block)
    /give @p minecraft:player_head{SkullOwner:{Id:[I;-2059632401,1010256381,-1438018677,1732958950],Properties:{textures:[{Value: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNTBjNDEwZmFkOGQ5ZDg4MjVhZDU2YjBlNDQzZTI3NzdhNmI0NmJmYTIwZGFjZDFkMmY1NWVkYzcxZmJlYjA2ZD9uYW1lPS83ZmQ5YmE0MmE3YzgxZWVlYTIyZjE1MjQyNzFhZTg1YThlMDQ1Y2UwYWY1YTZhZTE2YzY0MDZhZTkxN2U2OGI1In19fQ=="}]},Name:"jeb_ skin poisoned"}}
    

    Note that this shows Dinnerbone's skin.

  4. Use the following command to get the player head of jeb_
    /give @s minecraft:player_head{SkullOwner:"jeb_"}
    

    Instead of showing jeb_'s skin, it shows the skin from the previous step

Fixed

StayWithMeSenpai

[Mojang] slicedlime

2022-05-13, 06:12 PM

2023-05-25, 01:35 PM

2023-05-25, 01:35 PM

2

3

Confirmed

Important

Networking

cape, player, skin, texture

1.18.2, 22w19a, 1.19, 1.19.3

1.20 Pre-release 6