Sanitize cookie keys in Wikibase extension. Fixes #3745. (#3746)

This commit is contained in:
Antonin Delpeuch 2021-03-18 07:47:38 +01:00 committed by GitHub
parent 2cd7e903bc
commit 2a6003c5d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 2 deletions

View File

@ -40,6 +40,8 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.apache.commons.lang.StringUtils.isBlank; import static org.apache.commons.lang.StringUtils.isBlank;
import static org.apache.commons.lang.StringUtils.isNotBlank; import static org.apache.commons.lang.StringUtils.isNotBlank;
@ -67,6 +69,8 @@ public class LoginCommand extends Command {
static final String CONSUMER_SECRET = "wb-consumer-secret"; static final String CONSUMER_SECRET = "wb-consumer-secret";
static final String ACCESS_TOKEN = "wb-access-token"; static final String ACCESS_TOKEN = "wb-access-token";
static final String ACCESS_SECRET = "wb-access-secret"; static final String ACCESS_SECRET = "wb-access-secret";
static final Pattern cookieKeyDisallowedCharacters = Pattern.compile("[^a-zA-Z0-9\\-!#$%&'*+.?\\^_`|~]");
@Override @Override
public void doPost(HttpServletRequest request, HttpServletResponse response) public void doPost(HttpServletRequest request, HttpServletResponse response)
@ -83,7 +87,7 @@ public class LoginCommand extends Command {
CommandUtilities.respondError(response, "missing parameter '" + API_ENDPOINT + "'"); CommandUtilities.respondError(response, "missing parameter '" + API_ENDPOINT + "'");
return; return;
} }
String mediawikiApiEndpointPrefix = mediawikiApiEndpoint + '-'; String mediawikiApiEndpointPrefix = sanitizeCookieKey(mediawikiApiEndpoint + '-');
if ("true".equals(request.getParameter("logout"))) { if ("true".equals(request.getParameter("logout"))) {
manager.logout(mediawikiApiEndpoint); manager.logout(mediawikiApiEndpoint);
@ -268,4 +272,13 @@ public class LoginCommand extends Command {
return str.replaceAll("[\n\r]", ""); return str.replaceAll("[\n\r]", "");
} }
} }
/**
* Removes special characters from cookie keys,
* replacing them by hyphens.
*/
static String sanitizeCookieKey(String key) {
Matcher matcher = cookieKeyDisallowedCharacters.matcher(key);
return matcher.replaceAll("-");
}
} }

View File

@ -40,7 +40,7 @@ import static org.testng.Assert.*;
public class LoginCommandTest extends CommandTest { public class LoginCommandTest extends CommandTest {
private static final String apiEndpoint = "https://www.wikidata.org/w/api.php"; private static final String apiEndpoint = "https://www.wikidata.org/w/api.php";
private static final String apiEndpointPrefix = apiEndpoint + "-"; private static final String apiEndpointPrefix = sanitizeCookieKey(apiEndpoint) + "-";
private static final String username = "my_username"; private static final String username = "my_username";
private static final String password = "my_password"; private static final String password = "my_password";
@ -567,4 +567,9 @@ public class LoginCommandTest extends CommandTest {
assertEquals(removeCRLF("a\rb\nc\r\n\r\nd"), "abcd"); assertEquals(removeCRLF("a\rb\nc\r\n\r\nd"), "abcd");
assertEquals(removeCRLF(null), ""); assertEquals(removeCRLF(null), "");
} }
@Test
public void testSanitizeCookieKey() {
assertEquals(sanitizeCookieKey("https://www.wikidata.org/"), "https---www.wikidata.org-");
}
} }