mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-23 06:55:08 +01:00
Add more validation
- Check max length of strings and byte arrays - Check that tx ID has 64 chars - Add ExtraDataMapValidator for validating extraDataMap fields
This commit is contained in:
parent
122bc80cdd
commit
73db81a34f
5 changed files with 98 additions and 6 deletions
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.common.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
/**
|
||||
* Validator for extraDataMap fields used in network payloads.
|
||||
* Ensures that we don't get the network attacked by huge data inserted there.
|
||||
*/
|
||||
@Slf4j
|
||||
public class ExtraDataMapValidator {
|
||||
// ExtraDataMap is only used for exceptional cases to not break backward compatibility.
|
||||
// We don't expect many entries there.
|
||||
public final static int MAX_SIZE = 10;
|
||||
public final static int MAX_KEY_LENGTH = 100;
|
||||
public final static int MAX_VALUE_LENGTH = 100000; // 100 kb
|
||||
|
||||
public static Map<String, String> getValidatedExtraDataMap(@Nullable Map<String, String> extraDataMap) {
|
||||
return getValidatedExtraDataMap(extraDataMap, MAX_SIZE, MAX_KEY_LENGTH, MAX_VALUE_LENGTH);
|
||||
}
|
||||
|
||||
public static Map<String, String> getValidatedExtraDataMap(@Nullable Map<String, String> extraDataMap, int maxSize, int maxKeyLength, int maxValueLength) {
|
||||
if (extraDataMap == null)
|
||||
return null;
|
||||
|
||||
try {
|
||||
checkArgument(extraDataMap.entrySet().size() <= maxSize, "Size of map must not exceed " + maxSize);
|
||||
extraDataMap.forEach((key, value) -> {
|
||||
checkArgument(key.length() <= maxKeyLength, "Length of key must not exceed " + maxKeyLength);
|
||||
checkArgument(value.length() <= maxValueLength, "Length of value must not exceed " + maxValueLength);
|
||||
});
|
||||
return extraDataMap;
|
||||
} catch (Throwable t) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
public static void validate(@Nullable Map<String, String> extraDataMap) {
|
||||
validate(extraDataMap, MAX_SIZE, MAX_KEY_LENGTH, MAX_VALUE_LENGTH);
|
||||
}
|
||||
|
||||
public static void validate(@Nullable Map<String, String> extraDataMap, int maxSize, int maxKeyLength, int maxValueLength) {
|
||||
if (extraDataMap == null)
|
||||
return;
|
||||
|
||||
checkArgument(extraDataMap.entrySet().size() <= maxSize, "Size of map must not exceed " + maxSize);
|
||||
extraDataMap.forEach((key, value) -> {
|
||||
checkArgument(key.length() <= maxKeyLength, "Length of key must not exceed " + maxKeyLength);
|
||||
checkArgument(value.length() <= maxValueLength, "Length of value must not exceed " + maxValueLength);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -17,12 +17,15 @@
|
|||
|
||||
package bisq.core.dao.governance.blindvote;
|
||||
|
||||
import bisq.core.btc.wallet.Restrictions;
|
||||
import bisq.core.dao.governance.period.PeriodService;
|
||||
import bisq.core.dao.governance.proposal.ProposalValidationException;
|
||||
import bisq.core.dao.state.DaoStateService;
|
||||
import bisq.core.dao.state.model.blockchain.Tx;
|
||||
import bisq.core.dao.state.model.governance.DaoPhase;
|
||||
|
||||
import bisq.common.util.ExtraDataMapValidator;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import java.util.Optional;
|
||||
|
@ -58,12 +61,20 @@ public class BlindVoteValidator {
|
|||
checkNotNull(blindVote.getEncryptedVotes(), "encryptedProposalList must not be null");
|
||||
checkArgument(blindVote.getEncryptedVotes().length > 0,
|
||||
"encryptedProposalList must not be empty");
|
||||
checkNotNull(blindVote.getTxId(), "txId must not be null");
|
||||
checkArgument(!blindVote.getTxId().isEmpty(), "txId must not be empty");
|
||||
checkArgument(blindVote.getStake() > 0, "stake must be positive");
|
||||
checkArgument(blindVote.getEncryptedVotes().length <= 100000,
|
||||
"encryptedProposalList must not exceed 100kb");
|
||||
|
||||
checkNotNull(blindVote.getTxId(), "Tx ID must not be null");
|
||||
checkArgument(blindVote.getTxId().length() == 64, "Tx ID must be 64 chars");
|
||||
checkArgument(blindVote.getStake() >= Restrictions.getMinNonDustOutput().value, "Stake must be at least MinNonDustOutput");
|
||||
|
||||
checkNotNull(blindVote.getEncryptedMeritList(), "getEncryptedMeritList must not be null");
|
||||
checkArgument(blindVote.getEncryptedMeritList().length > 0,
|
||||
"getEncryptedMeritList must not be empty");
|
||||
checkArgument(blindVote.getEncryptedMeritList().length <= 100000,
|
||||
"getEncryptedMeritList must not exceed 100kb");
|
||||
|
||||
ExtraDataMapValidator.validate(blindVote.getExtraDataMap());
|
||||
} catch (Throwable e) {
|
||||
log.warn(e.toString());
|
||||
throw new ProposalValidationException(e);
|
||||
|
|
|
@ -28,6 +28,8 @@ import bisq.core.dao.state.model.governance.DaoPhase;
|
|||
import bisq.core.dao.state.model.governance.Proposal;
|
||||
import bisq.core.dao.state.model.governance.ReimbursementProposal;
|
||||
|
||||
import bisq.common.util.ExtraDataMapValidator;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -66,6 +68,8 @@ public abstract class ProposalValidator implements ConsensusCritical {
|
|||
checkArgument(proposal.getLink().length() <= 200, "Link must not exceed 200 chars");
|
||||
if (proposal.getTxId() != null)
|
||||
checkArgument(proposal.getTxId().length() == 64, "Tx ID must be 64 chars");
|
||||
|
||||
ExtraDataMapValidator.validate(proposal.getExtraDataMap());
|
||||
} catch (Throwable throwable) {
|
||||
throw new ProposalValidationException(throwable);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import bisq.common.app.Capabilities;
|
|||
import bisq.common.app.Capability;
|
||||
import bisq.common.crypto.Sig;
|
||||
import bisq.common.proto.persistable.PersistablePayload;
|
||||
import bisq.common.util.ExtraDataMapValidator;
|
||||
|
||||
import io.bisq.generated.protobuffer.PB;
|
||||
|
||||
|
@ -88,7 +89,7 @@ public class TempProposalPayload implements LazyProcessedPayload, ProtectedStora
|
|||
@Nullable Map<String, String> extraDataMap) {
|
||||
this.proposal = proposal;
|
||||
this.ownerPubKeyEncoded = ownerPubPubKeyEncoded;
|
||||
this.extraDataMap = extraDataMap;
|
||||
this.extraDataMap = ExtraDataMapValidator.getValidatedExtraDataMap(extraDataMap);
|
||||
|
||||
ownerPubKey = Sig.getPublicKeyFromBytes(ownerPubKeyEncoded);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import bisq.core.dao.state.model.blockchain.TxType;
|
|||
import bisq.common.proto.ProtobufferRuntimeException;
|
||||
import bisq.common.proto.network.NetworkPayload;
|
||||
import bisq.common.proto.persistable.PersistablePayload;
|
||||
import bisq.common.util.ExtraDataMapValidator;
|
||||
|
||||
import io.bisq.generated.protobuffer.PB;
|
||||
|
||||
|
@ -64,13 +65,13 @@ public abstract class Proposal implements PersistablePayload, NetworkPayload, Co
|
|||
byte version,
|
||||
long creationDate,
|
||||
@Nullable String txId,
|
||||
@SuppressWarnings("NullableProblems") Map<String, String> extraDataMap) {
|
||||
@Nullable Map<String, String> extraDataMap) {
|
||||
this.name = name;
|
||||
this.link = link;
|
||||
this.version = version;
|
||||
this.creationDate = creationDate;
|
||||
this.txId = txId;
|
||||
this.extraDataMap = extraDataMap;
|
||||
this.extraDataMap = ExtraDataMapValidator.getValidatedExtraDataMap(extraDataMap);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue