Skip to content
This repository has been archived by the owner on Jul 24, 2024. It is now read-only.

Commit

Permalink
Properly encode SessionService URL parameters and bump version to 1.4.
Browse files Browse the repository at this point in the history
Fixes potential URL query parameter attacks on server-side user authentication. Thanks to @Ry0taK for reporting.
  • Loading branch information
Steveice10 authored and Steveice10 committed Aug 23, 2021
1 parent 65c30e3 commit d25d5ef
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 5 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>com.github.steveice10</groupId>
<artifactId>mcauthlib</artifactId>
<version>1.4-SNAPSHOT</version>
<version>1.4</version>
<packaging>jar</packaging>

<name>MCAuthLib</name>
Expand Down
20 changes: 18 additions & 2 deletions src/main/java/com/github/steveice10/mc/auth/service/Service.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.github.steveice10.mc.auth.service;

import java.io.UnsupportedEncodingException;
import java.net.Proxy;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.Map;

/**
* Base class for auth-related services.
Expand Down Expand Up @@ -80,12 +83,25 @@ public URI getEndpointUri(String endpoint) {
* @param queryParams Query parameters to append to the URI.
* @return The URI for the given endpoint.
*/
public URI getEndpointUri(String endpoint, String queryParams) {
public URI getEndpointUri(String endpoint, Map<String, String> queryParams) {
URI base = this.getEndpointUri(endpoint);
try {
return new URI(base.getScheme(), base.getAuthority(), base.getPath(), queryParams, base.getFragment());
StringBuilder queryString = new StringBuilder();
for(Map.Entry<String, String> queryParam : queryParams.entrySet()) {
if(queryString.length() > 0) {
queryString.append("&");
}

queryString.append(queryParam.getKey())
.append('=')
.append(URLEncoder.encode(queryParam.getValue(), "UTF-8"));
}

return new URI(base.getScheme(), base.getAuthority(), base.getPath(), queryString.toString(), base.getFragment());
} catch(URISyntaxException e) {
throw new IllegalArgumentException("Arguments resulted in invalid endpoint URI.", e);
} catch(UnsupportedEncodingException e) {
throw new IllegalStateException("UTF-8 encoding not supported.", e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
Expand Down Expand Up @@ -77,7 +80,11 @@ public void joinServer(GameProfile profile, String authenticationToken, String s
* @throws RequestException If an error occurs while making the request.
*/
public GameProfile getProfileByServer(String name, String serverId) throws RequestException {
HasJoinedResponse response = HTTP.makeRequest(this.getProxy(), this.getEndpointUri(HAS_JOINED_ENDPOINT, "username=" + name + "&serverId=" + serverId), null, HasJoinedResponse.class);
Map<String, String> queryParams = new HashMap<>();
queryParams.put("username", name);
queryParams.put("serverId", serverId);

HasJoinedResponse response = HTTP.makeRequest(this.getProxy(), this.getEndpointUri(HAS_JOINED_ENDPOINT, queryParams), null, HasJoinedResponse.class);
if(response != null && response.id != null) {
GameProfile result = new GameProfile(response.id, name);
result.setProperties(response.properties);
Expand All @@ -100,7 +107,7 @@ public GameProfile fillProfileProperties(GameProfile profile) throws ProfileExce
}

try {
MinecraftProfileResponse response = HTTP.makeRequest(this.getProxy(), this.getEndpointUri(PROFILE_ENDPOINT + "/" + UUIDSerializer.fromUUID(profile.getId()), "unsigned=false"), null, MinecraftProfileResponse.class);
MinecraftProfileResponse response = HTTP.makeRequest(this.getProxy(), this.getEndpointUri(PROFILE_ENDPOINT + "/" + UUIDSerializer.fromUUID(profile.getId()), Collections.singletonMap("unsigned", "false")), null, MinecraftProfileResponse.class);
if(response == null) {
throw new ProfileNotFoundException("Couldn't fetch profile properties for " + profile + " as the profile does not exist.");
}
Expand Down

0 comments on commit d25d5ef

Please sign in to comment.