Skip to content

Commit

Permalink
Protect readLine() against DoS
Browse files Browse the repository at this point in the history
  • Loading branch information
pixeebot[bot] authored Jul 17, 2024
1 parent 5a4b5fa commit b413daa
Show file tree
Hide file tree
Showing 22 changed files with 63 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

package org.elasticsearch.gradle.internal.conventions.info;

import io.github.pixee.security.BoundedLineReader;
import org.gradle.api.Action;
import org.gradle.api.logging.Logger;
import org.gradle.api.logging.Logging;
Expand Down Expand Up @@ -45,7 +46,7 @@ public static int findDefaultParallel(Project project) {
String currentID = "";

try (BufferedReader reader = new BufferedReader(new FileReader(cpuInfoFile))) {
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
for (String line = BoundedLineReader.readLine(reader, 5_000_000); line != null; line = BoundedLineReader.readLine(reader, 5_000_000)) {
if (line.contains(":")) {
List<String> parts = Arrays.stream(line.split(":", 2)).map(String::trim).collect(Collectors.toList());
String name = parts.get(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
package org.elasticsearch.gradle.internal.info;

import io.github.pixee.security.BoundedLineReader;
import org.apache.commons.io.IOUtils;
import org.elasticsearch.gradle.internal.BwcVersions;
import org.elasticsearch.gradle.internal.conventions.info.GitInfo;
Expand Down Expand Up @@ -360,7 +361,7 @@ public static String getResourceContents(String resourcePath) {
BufferedReader reader = new BufferedReader(new InputStreamReader(GlobalBuildInfoPlugin.class.getResourceAsStream(resourcePath)))
) {
StringBuilder b = new StringBuilder();
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
for (String line = BoundedLineReader.readLine(reader, 5_000_000); line != null; line = BoundedLineReader.readLine(reader, 5_000_000)) {
if (b.length() != 0) {
b.append('\n');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
package org.elasticsearch.gradle.testclusters;

import io.github.pixee.security.BoundedLineReader;
import org.gradle.api.GradleException;
import org.gradle.api.logging.Logger;
import org.gradle.api.logging.Logging;
Expand Down Expand Up @@ -245,7 +246,7 @@ public void runAndWait() throws IOException {
for (BufferedReader bufferedReader : toRead) {
if (bufferedReader.ready()) {
readData = true;
logger.lifecycle(bufferedReader.readLine());
logger.lifecycle(BoundedLineReader.readLine(bufferedReader, 5_000_000));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
package org.elasticsearch.client.benchmark.ops.bulk;

import io.github.pixee.security.BoundedLineReader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.ElasticsearchException;
Expand Down Expand Up @@ -101,7 +102,7 @@ public void execute() {
String line;
int bulkIndex = 0;
List<String> bulkData = new ArrayList<>(bulkSize);
while ((line = reader.readLine()) != null) {
while ((line = BoundedLineReader.readLine(reader, 5_000_000)) != null) {
if (bulkIndex == bulkSize) {
sendBulk(bulkData);
// reset data structures
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package org.elasticsearch.client;

import io.github.pixee.security.BoundedLineReader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
Expand Down Expand Up @@ -170,7 +171,7 @@ static String buildTraceResponse(HttpResponse httpResponse) throws IOException {
}
try (BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), charset))) {
String line;
while ((line = reader.readLine()) != null) {
while ((line = BoundedLineReader.readLine(reader, 5_000_000)) != null) {
responseLine.append("\n# ").append(line);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

package org.elasticsearch.plugins.cli;

import io.github.pixee.security.BoundedLineReader;
import org.apache.lucene.search.spell.LevenshteinDistance;
import org.apache.lucene.util.CollectionUtil;
import org.apache.lucene.util.Constants;
Expand Down Expand Up @@ -579,9 +580,9 @@ private Path downloadAndValidate(final String urlString, final Path tmpDir, fina
*/
final BufferedReader checksumReader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
if (digestAlgo.equals("SHA-1")) {
expectedChecksum = checksumReader.readLine();
expectedChecksum = BoundedLineReader.readLine(checksumReader, 5_000_000);
} else {
final String checksumLine = checksumReader.readLine();
final String checksumLine = BoundedLineReader.readLine(checksumReader, 5_000_000);
final String[] fields = checksumLine.split(" {2}");
if (officialPlugin && fields.length != 2 || officialPlugin == false && fields.length > 2) {
throw new UserException(ExitCodes.IO_ERROR, "Invalid checksum file at " + checksumUrl);
Expand All @@ -603,7 +604,7 @@ private Path downloadAndValidate(final String urlString, final Path tmpDir, fina
}
}
}
if (checksumReader.readLine() != null) {
if (BoundedLineReader.readLine(checksumReader, 5_000_000) != null) {
throw new UserException(ExitCodes.IO_ERROR, "Invalid checksum file at " + checksumUrl);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

package org.elasticsearch.server.cli;

import io.github.pixee.security.BoundedLineReader;
import org.elasticsearch.bootstrap.BootstrapInfo;

import java.io.BufferedReader;
Expand Down Expand Up @@ -76,7 +77,7 @@ void drain() {
public void run() {
try {
String line;
while ((line = reader.readLine()) != null) {
while ((line = BoundedLineReader.readLine(reader, 5_000_000)) != null) {
if (line.isEmpty() == false && line.charAt(0) == SERVER_READY_MARKER) {
ready = true;
readyOrDead.countDown();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

package org.elasticsearch.server.cli;

import io.github.pixee.security.BoundedLineReader;
import org.elasticsearch.bootstrap.ServerArgs;
import org.elasticsearch.cli.ExitCodes;
import org.elasticsearch.cli.UserException;
Expand Down Expand Up @@ -289,7 +290,7 @@ static void parse(
) throws IOException {
int lineNumber = 0;
while (true) {
final String line = br.readLine();
final String line = BoundedLineReader.readLine(br, 5_000_000);
lineNumber++;
if (line == null) {
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

package org.elasticsearch.grok;

import io.github.pixee.security.BoundedLineReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
Expand Down Expand Up @@ -138,7 +139,7 @@ private static PatternBank loadPatternsFromDirectory(List<String> patternNames,
private static void loadPatternsFromFile(Map<String, String> patternBank, InputStream inputStream) throws IOException {
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
while ((line = br.readLine()) != null) {
while ((line = BoundedLineReader.readLine(br, 5_000_000)) != null) {
String trimmedLine = line.replaceAll("^\\s+", "");
if (trimmedLine.startsWith("#") || trimmedLine.length() == 0) {
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

package org.elasticsearch.common.ssl;

import io.github.pixee.security.BoundedLineReader;
import org.elasticsearch.core.CharArrays;

import java.io.BufferedReader;
Expand Down Expand Up @@ -128,9 +129,9 @@ public static PrivateKey readPrivateKey(Path path, Supplier<char[]> passwordSupp
*/
static PrivateKey parsePrivateKey(Path keyPath, Supplier<char[]> passwordSupplier) throws IOException, GeneralSecurityException {
try (BufferedReader bReader = Files.newBufferedReader(keyPath, StandardCharsets.UTF_8)) {
String line = bReader.readLine();
String line = BoundedLineReader.readLine(bReader, 5_000_000);
while (null != line && line.startsWith(HEADER) == false) {
line = bReader.readLine();
line = BoundedLineReader.readLine(bReader, 5_000_000);
}
if (null == line) {
throw new SslConfigException("Error parsing Private Key [" + keyPath.toAbsolutePath() + "], file is empty");
Expand Down Expand Up @@ -170,18 +171,18 @@ static PrivateKey parsePrivateKey(Path keyPath, Supplier<char[]> passwordSupplie
* @throws IOException if the EC Parameter footer is missing
*/
private static BufferedReader removeECHeaders(BufferedReader bReader) throws IOException {
String line = bReader.readLine();
String line = BoundedLineReader.readLine(bReader, 5_000_000);
while (line != null) {
if (OPENSSL_EC_PARAMS_FOOTER.equals(line.trim())) {
break;
}
line = bReader.readLine();
line = BoundedLineReader.readLine(bReader, 5_000_000);
}
if (null == line || OPENSSL_EC_PARAMS_FOOTER.equals(line.trim()) == false) {
throw new IOException("Malformed PEM file, EC Parameters footer is missing");
}
// Verify that the key starts with the correct header before passing it to parseOpenSslEC
if (OPENSSL_EC_HEADER.equals(bReader.readLine()) == false) {
if (OPENSSL_EC_HEADER.equals(BoundedLineReader.readLine(bReader, 5_000_000)) == false) {
throw new IOException("Malformed PEM file, EC Key header is missing");
}
return bReader;
Expand All @@ -194,18 +195,18 @@ private static BufferedReader removeECHeaders(BufferedReader bReader) throws IOE
* @throws IOException if the EC Parameter footer is missing
*/
private static BufferedReader removeDsaHeaders(BufferedReader bReader) throws IOException {
String line = bReader.readLine();
String line = BoundedLineReader.readLine(bReader, 5_000_000);
while (line != null) {
if (OPENSSL_DSA_PARAMS_FOOTER.equals(line.trim())) {
break;
}
line = bReader.readLine();
line = BoundedLineReader.readLine(bReader, 5_000_000);
}
if (null == line || OPENSSL_DSA_PARAMS_FOOTER.equals(line.trim()) == false) {
throw new IOException("Malformed PEM file, DSA Parameters footer is missing");
}
// Verify that the key starts with the correct header before passing it to parseOpenSslDsa
if (OPENSSL_DSA_HEADER.equals(bReader.readLine()) == false) {
if (OPENSSL_DSA_HEADER.equals(BoundedLineReader.readLine(bReader, 5_000_000)) == false) {
throw new IOException("Malformed PEM file, DSA Key header is missing");
}
return bReader;
Expand All @@ -222,13 +223,13 @@ private static BufferedReader removeDsaHeaders(BufferedReader bReader) throws IO
*/
private static PrivateKey parsePKCS8(BufferedReader bReader) throws IOException, GeneralSecurityException {
StringBuilder sb = new StringBuilder();
String line = bReader.readLine();
String line = BoundedLineReader.readLine(bReader, 5_000_000);
while (line != null) {
if (PKCS8_FOOTER.equals(line.trim())) {
break;
}
sb.append(line.trim());
line = bReader.readLine();
line = BoundedLineReader.readLine(bReader, 5_000_000);
}
if (null == line || PKCS8_FOOTER.equals(line.trim()) == false) {
throw new IOException("Malformed PEM file, PEM footer is invalid or missing");
Expand Down Expand Up @@ -263,7 +264,7 @@ public static PrivateKey parsePKCS8PemString(String pemString) throws IOExceptio
private static PrivateKey parseOpenSslEC(BufferedReader bReader, Supplier<char[]> passwordSupplier) throws IOException,
GeneralSecurityException {
StringBuilder sb = new StringBuilder();
String line = bReader.readLine();
String line = BoundedLineReader.readLine(bReader, 5_000_000);
Map<String, String> pemHeaders = new HashMap<>();
while (line != null) {
if (OPENSSL_EC_FOOTER.equals(line.trim())) {
Expand All @@ -276,7 +277,7 @@ private static PrivateKey parseOpenSslEC(BufferedReader bReader, Supplier<char[]
} else {
sb.append(line.trim());
}
line = bReader.readLine();
line = BoundedLineReader.readLine(bReader, 5_000_000);
}
if (null == line || OPENSSL_EC_FOOTER.equals(line.trim()) == false) {
throw new IOException("Malformed PEM file, PEM footer is invalid or missing");
Expand All @@ -300,7 +301,7 @@ private static PrivateKey parseOpenSslEC(BufferedReader bReader, Supplier<char[]
private static PrivateKey parsePKCS1Rsa(BufferedReader bReader, Supplier<char[]> passwordSupplier) throws IOException,
GeneralSecurityException {
StringBuilder sb = new StringBuilder();
String line = bReader.readLine();
String line = BoundedLineReader.readLine(bReader, 5_000_000);
Map<String, String> pemHeaders = new HashMap<>();

while (line != null) {
Expand All @@ -315,7 +316,7 @@ private static PrivateKey parsePKCS1Rsa(BufferedReader bReader, Supplier<char[]>
} else {
sb.append(line.trim());
}
line = bReader.readLine();
line = BoundedLineReader.readLine(bReader, 5_000_000);
}
if (null == line || PKCS1_FOOTER.equals(line.trim()) == false) {
throw new IOException("Malformed PEM file, PEM footer is invalid or missing");
Expand All @@ -339,7 +340,7 @@ private static PrivateKey parsePKCS1Rsa(BufferedReader bReader, Supplier<char[]>
private static PrivateKey parseOpenSslDsa(BufferedReader bReader, Supplier<char[]> passwordSupplier) throws IOException,
GeneralSecurityException {
StringBuilder sb = new StringBuilder();
String line = bReader.readLine();
String line = BoundedLineReader.readLine(bReader, 5_000_000);
Map<String, String> pemHeaders = new HashMap<>();

while (line != null) {
Expand All @@ -354,7 +355,7 @@ private static PrivateKey parseOpenSslDsa(BufferedReader bReader, Supplier<char[
} else {
sb.append(line.trim());
}
line = bReader.readLine();
line = BoundedLineReader.readLine(bReader, 5_000_000);
}
if (null == line || OPENSSL_DSA_FOOTER.equals(line.trim()) == false) {
throw new IOException("Malformed PEM file, PEM footer is invalid or missing");
Expand All @@ -377,13 +378,13 @@ private static PrivateKey parseOpenSslDsa(BufferedReader bReader, Supplier<char[
*/
private static PrivateKey parsePKCS8Encrypted(BufferedReader bReader, char[] keyPassword) throws IOException, GeneralSecurityException {
StringBuilder sb = new StringBuilder();
String line = bReader.readLine();
String line = BoundedLineReader.readLine(bReader, 5_000_000);
while (line != null) {
if (PKCS8_ENCRYPTED_FOOTER.equals(line.trim())) {
break;
}
sb.append(line.trim());
line = bReader.readLine();
line = BoundedLineReader.readLine(bReader, 5_000_000);
}
if (null == line || PKCS8_ENCRYPTED_FOOTER.equals(line.trim()) == false) {
throw new IOException("Malformed PEM file, PEM footer is invalid or missing");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import com.google.cloud.storage.StorageRetryStrategy;
import io.github.pixee.security.BoundedLineReader;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand Down Expand Up @@ -252,7 +253,7 @@ static String getDefaultProjectId(@Nullable Proxy proxy) throws IOException {
try (InputStream input = connection.getInputStream()) {
if (connection.getResponseCode() == 200) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(input, UTF_8))) {
return reader.readLine();
return BoundedLineReader.readLine(reader, 5_000_000);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

package org.elasticsearch.discovery.ec2;

import io.github.pixee.security.BoundedLineReader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.common.Strings;
Expand Down Expand Up @@ -49,7 +50,7 @@ static Optional<String> getMetadataToken(String metadataTokenUrl) {
var in = urlConnection.getInputStream();
var reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))
) {
return Optional.ofNullable(reader.readLine()).filter(s -> s.isBlank() == false);
return Optional.ofNullable(BoundedLineReader.readLine(reader, 5_000_000)).filter(s -> s.isBlank() == false);
} catch (IOException e) {
logger.warn("Unable to get a session token from IMDSv2 URI: " + metadataTokenUrl, e);
return Optional.empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import com.amazonaws.util.EC2MetadataUtils;
import com.amazonaws.util.json.Jackson;
import io.github.pixee.security.BoundedLineReader;

import org.elasticsearch.SpecialPermission;
import org.elasticsearch.common.network.NetworkService;
Expand Down Expand Up @@ -158,7 +159,7 @@ static Settings getAvailabilityZoneNodeAttributes(Settings settings, String azMe
BufferedReader urlReader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))
) {

final String metadataResult = urlReader.readLine();
final String metadataResult = BoundedLineReader.readLine(urlReader, 5_000_000);
if ((metadataResult == null) || (metadataResult.length() == 0)) {
throw new IllegalStateException("no ec2 metadata returned from " + url);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
package org.elasticsearch.discovery.ec2;

import com.amazonaws.util.EC2MetadataUtils;
import io.github.pixee.security.BoundedLineReader;

import org.elasticsearch.common.network.NetworkService.CustomNameResolver;
import org.elasticsearch.core.IOUtils;
Expand Down Expand Up @@ -95,7 +96,7 @@ public static InetAddress[] resolve(Ec2HostnameType type) throws IOException {
in = SocketAccess.doPrivilegedIOException(urlConnection::getInputStream);
BufferedReader urlReader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));

String metadataResult = urlReader.readLine();
String metadataResult = BoundedLineReader.readLine(urlReader, 5_000_000);
if (metadataResult == null || metadataResult.length() == 0) {
throw new IOException("no gce metadata returned from [" + url + "] for [" + type.configName + "]");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

package org.elasticsearch.action.admin.cluster.node.hotthreads;

import io.github.pixee.security.BoundedLineReader;
import org.elasticsearch.action.FailedNodeException;
import org.elasticsearch.action.support.TransportAction;
import org.elasticsearch.action.support.nodes.BaseNodesResponse;
Expand Down Expand Up @@ -63,7 +64,7 @@ private LinesIterator(String input) {

private void advance() {
try {
nextLine = reader.readLine();
nextLine = BoundedLineReader.readLine(reader, 5_000_000);
} catch (IOException e) {
assert false : e; // no actual IO happens here
}
Expand Down
Loading

0 comments on commit b413daa

Please sign in to comment.