[poppler] 2 commits - poppler/Array.cc poppler/Array.h poppler/Catalog.cc poppler/Page.cc poppler/Stream.cc poppler/Stream.h poppler/XRef.cc poppler/XRef.h

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Dec 8 22:38:23 UTC 2019


 poppler/Array.cc   |    2 +-
 poppler/Array.h    |    2 +-
 poppler/Catalog.cc |   21 ++++++++++++++++++---
 poppler/Page.cc    |    2 +-
 poppler/Stream.cc  |    8 ++++++++
 poppler/Stream.h   |    7 +++++--
 poppler/XRef.cc    |   29 +++++++++++++++++++++++++++++
 poppler/XRef.h     |    4 ++++
 8 files changed, 67 insertions(+), 8 deletions(-)

New commits:
commit 6dc7ff20af627de8576bf6aaad8e3ea4ef43ba52
Author: Albert Astals Cid <aacid at kde.org>
Date:   Sun Dec 8 23:38:13 2019 +0100

    Update (C)

diff --git a/poppler/Array.cc b/poppler/Array.cc
index f32dc38a..7f1fcdda 100644
--- a/poppler/Array.cc
+++ b/poppler/Array.cc
@@ -18,7 +18,7 @@
 // Copyright (C) 2013 Thomas Freitag <Thomas.Freitag at alfa.de>
 // Copyright (C) 2013, 2017, 2019 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2017 Adrian Johnson <ajohnson at redneon.com>
-// Copyright (C) 2018 Adam Reichold <adam.reichold at t-online.de>
+// Copyright (C) 2018, 2019 Adam Reichold <adam.reichold at t-online.de>
 //
 // To see a description of the changes please see the Changelog file that
 // came with your tarball or type make ChangeLog if you are building from git
diff --git a/poppler/Array.h b/poppler/Array.h
index 9232423a..ce84c3a7 100644
--- a/poppler/Array.h
+++ b/poppler/Array.h
@@ -18,7 +18,7 @@
 // Copyright (C) 2013 Thomas Freitag <Thomas.Freitag at alfa.de>
 // Copyright (C) 2017-2019 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2017 Adrian Johnson <ajohnson at redneon.com>
-// Copyright (C) 2018 Adam Reichold <adam.reichold at t-online.de>
+// Copyright (C) 2018, 2019 Adam Reichold <adam.reichold at t-online.de>
 //
 // To see a description of the changes please see the Changelog file that
 // came with your tarball or type make ChangeLog if you are building from git
diff --git a/poppler/Page.cc b/poppler/Page.cc
index f642018a..87621ca2 100644
--- a/poppler/Page.cc
+++ b/poppler/Page.cc
@@ -29,7 +29,7 @@
 // Copyright (C) 2013 Jason Crain <jason at aquaticape.us>
 // Copyright (C) 2013, 2017 Adrian Johnson <ajohnson at redneon.com>
 // Copyright (C) 2015 Philipp Reinkemeier <philipp.reinkemeier at offis.de>
-// Copyright (C) 2018 Adam Reichold <adam.reichold at t-online.de>
+// Copyright (C) 2018, 2019 Adam Reichold <adam.reichold at t-online.de>
 //
 // To see a description of the changes please see the Changelog file that
 // came with your tarball or type make ChangeLog if you are building from git
commit ce81e411086342af083e04f53dfd90d9e3628922
Author: Albert Astals Cid <aacid at kde.org>
Date:   Sat Dec 7 00:18:53 2019 +0100

    Make sure Base URI is encrypted if the document is before using it
    
    Otherwise we may be being targetted by a link content exfiltration

diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc
index ba4ec060..45115b8a 100644
--- a/poppler/Catalog.cc
+++ b/poppler/Catalog.cc
@@ -101,11 +101,26 @@ Catalog::Catalog(PDFDoc *docA) {
   acroForm = catDict.dictLookup("AcroForm");
 
   // read base URI
-  Object obj = catDict.dictLookup("URI");
+  // Before using the base URI we need to make sure the string is encrypted, for that we need to check the last Ref to it, that
+  // it can be either the String itself, the URI dict if the Base string is inside the URI dict or the Catalog dict if
+  // the Base string is inside the URI dict that is inside the Catalog dict
+  Ref refToCheck = xref->getRoot();
+  Ref auxRef;
+  Object obj = catDict.getDict()->lookup("URI", &auxRef);
   if (obj.isDict()) {
-    Object obj2 = obj.dictLookup("Base");
+    if (auxRef != Ref::INVALID()) {
+      refToCheck = auxRef;
+    }
+    Object obj2 = obj.getDict()->lookup("Base", &auxRef);
     if (obj2.isString()) {
-      baseURI = obj2.getString()->copy();
+      if (auxRef != Ref::INVALID()) {
+	refToCheck = auxRef;
+      }
+      if (!xref->isEncrypted() || xref->isRefEncrypted(refToCheck)) {
+	baseURI = obj2.getString()->copy();
+      } else {
+	error(errSyntaxError, -1, "Base URI is not encrypted and the document is. This may be a hacking attempt");
+      }
     }
   }
 
diff --git a/poppler/Stream.cc b/poppler/Stream.cc
index 76a542af..3cf464c1 100644
--- a/poppler/Stream.cc
+++ b/poppler/Stream.cc
@@ -175,6 +175,14 @@ Stream *Stream::addFilters(Dict *dict, int recursion) {
   return str;
 }
 
+bool Stream::isEncrypted() const {
+  for (const Stream *str = this; str != nullptr; str = str->getNextStream()) {
+    if (str->getKind() == strCrypt)
+      return true;
+  }
+  return false;
+}
+
 class BaseStreamStream : public Stream
 {
 public:
diff --git a/poppler/Stream.h b/poppler/Stream.h
index 46f2b375..4f606325 100644
--- a/poppler/Stream.h
+++ b/poppler/Stream.h
@@ -219,12 +219,15 @@ public:
 			      StreamColorSpaceMode * /*csMode*/) {}
 
   // Return the next stream in the "stack".
-  virtual Stream *getNextStream() { return nullptr; }
+  virtual Stream *getNextStream() const { return nullptr; }
 
   // Add filters to this stream according to the parameters in <dict>.
   // Returns the new stream.
   Stream *addFilters(Dict *dict, int recursion = 0);
 
+  // Returns true if this stream includes a crypt filter.
+  bool isEncrypted() const;
+
 private:
   friend class Object; // for incRef/decRef
 
@@ -344,7 +347,7 @@ public:
   Stream *getUndecodedStream() override { return str->getUndecodedStream(); }
   Dict *getDict() override { return str->getDict(); }
   Object *getDictObject() override { return str->getDictObject(); }
-  Stream *getNextStream() override { return str; }
+  Stream *getNextStream() const override { return str; }
 
   int getUnfilteredChar () override { return str->getUnfilteredChar(); }
   void unfilteredReset () override { str->unfilteredReset(); }
diff --git a/poppler/XRef.cc b/poppler/XRef.cc
index 8f9dd7fe..b123ad23 100644
--- a/poppler/XRef.cc
+++ b/poppler/XRef.cc
@@ -1012,6 +1012,35 @@ void XRef::getEncryptionParameters(unsigned char **fileKeyA, CryptAlgorithm *enc
   }
 }
 
+bool XRef::isRefEncrypted(Ref r)
+{
+  xrefLocker();
+
+  const XRefEntry *e = getEntry(r.num);
+  if (!e->obj.isNull()) { //check for updated object
+    return false;
+  }
+
+  switch (e->type) {
+    case xrefEntryUncompressed:
+    {
+      return encrypted && !e->getFlag(XRefEntry::Unencrypted);
+    }
+
+    case xrefEntryCompressed:
+    {
+      const Object objStr = fetch(e->offset, 0);
+      return objStr.getStream()->isEncrypted();
+    }
+
+    default:
+    {
+    }
+  }
+
+  return false;
+}
+
 bool XRef::okToPrint(bool ignoreOwnerPW) const {
   return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permPrint);
 }
diff --git a/poppler/XRef.h b/poppler/XRef.h
index 2e72ae54..8950980b 100644
--- a/poppler/XRef.h
+++ b/poppler/XRef.h
@@ -128,6 +128,9 @@ public:
   // Is the file encrypted?
   bool isEncrypted() const { return encrypted; }
 
+  // Is the given Ref encrypted?
+  bool isRefEncrypted(Ref r);
+
   // Check various permissions.
   bool okToPrint(bool ignoreOwnerPW = false) const;
   bool okToPrintHighRes(bool ignoreOwnerPW = false) const;
@@ -163,6 +166,7 @@ public:
   // Return the catalog object reference.
   int getRootNum() const { return rootNum; }
   int getRootGen() const { return rootGen; }
+  Ref getRoot() const { return { rootNum, rootGen }; }
 
   // Get end position for a stream in a damaged file.
   // Returns false if unknown or file is not damaged.


More information about the poppler mailing list