summaryrefslogtreecommitdiffstats
path: root/src/corelib/serialization/qxmlstream_p.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-02-26 10:42:10 +0100
committerLars Knoll <lars.knoll@qt.io>2020-02-26 22:08:38 +0100
commitfd4be84d23a0db4186cb42e736a9de3af722c7f7 (patch)
tree2c1820728acb10a4235b68191f00f45dc5731370 /src/corelib/serialization/qxmlstream_p.h
parent86f7d44089138b181642ee22989519f188c75bd5 (diff)
Add an expansion limit for entities
Recursively defined entities can easily exhaust all available memory. Limit entity expansion to a default of 4096 characters to avoid DoS attacks when a user loads untrusted content. Added a setter and getter to allow modifying the expansion limit. [ChangeLog][QtCore][QXmlStream] QXmlStreamReader does now by default limit the expansion of entities to 4096 characters. Documents where a single entity expands to more characters than the limit are not considered well formed. The limit is there to avoid DoS attacks through recursively expanding entities when loading untrusted content. The limit can be changed through the QXmlStreamReader::setEntityExpansionLimit() method. Fixes: QTBUG-47417 Change-Id: I94387815d74fcf34783e136387ee57fac5ded0c9 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/corelib/serialization/qxmlstream_p.h')
-rw-r--r--src/corelib/serialization/qxmlstream_p.h14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/corelib/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h
index 9c94e6d434..103b123b10 100644
--- a/src/corelib/serialization/qxmlstream_p.h
+++ b/src/corelib/serialization/qxmlstream_p.h
@@ -774,9 +774,19 @@ public:
QHash<QStringView, Entity> entityHash;
QHash<QStringView, Entity> parameterEntityHash;
QXmlStreamSimpleStack<Entity *>entityReferenceStack;
+ int entityExpansionLimit = 4096;
+ int entityLength = 0;
inline bool referenceEntity(Entity &entity) {
if (entity.isCurrentlyReferenced) {
- raiseWellFormedError(QXmlStream::tr("Recursive entity detected."));
+ raiseWellFormedError(QXmlStream::tr("Self-referencing entity detected."));
+ return false;
+ }
+ // entityLength represents the amount of additional characters the
+ // entity expands into (can be negative for e.g. &amp;). It's used to
+ // avoid DoS attacks through recursive entity expansions
+ entityLength += entity.value.size() - entity.name.size() - 2;
+ if (entityLength > entityExpansionLimit) {
+ raiseWellFormedError(QXmlStream::tr("Entity expands to more characters than the entity expansion limit."));
return false;
}
entity.isCurrentlyReferenced = true;
@@ -1308,6 +1318,8 @@ bool QXmlStreamReaderPrivate::parse()
case 10:
entityReferenceStack.pop()->isCurrentlyReferenced = false;
+ if (entityReferenceStack.isEmpty())
+ entityLength = 0;
clearSym();
break;