This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch 4_1_X
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/4_1_X by this push:
new 8d6ce7ae1d Sanitize CSV cells to prevent spreadsheet formula injections
8d6ce7ae1d is described below
commit 8d6ce7ae1dbd63a54b3a3c194489c6f3e7b3c1c2
Author: Francesco Chicchiriccò <[email protected]>
AuthorDate: Tue Aug 11 14:42:32 2026 +0200
Sanitize CSV cells to prevent spreadsheet formula injections
---
.../java/pushpull/stream/CSVStreamConnector.java | 40 ++++++++++++++--------
1 file changed, 26 insertions(+), 14 deletions(-)
diff --git
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/CSVStreamConnector.java
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/CSVStreamConnector.java
index cfe628e116..8a30c3e3db 100644
---
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/CSVStreamConnector.java
+++
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/CSVStreamConnector.java
@@ -33,6 +33,7 @@ import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.Strings;
import org.apache.commons.lang3.mutable.Mutable;
import org.apache.syncope.common.rest.api.beans.CSVPullSpec;
import org.apache.syncope.core.persistence.api.entity.ConnInstance;
@@ -60,23 +61,35 @@ import org.springframework.util.CollectionUtils;
public class CSVStreamConnector implements Connector, AutoCloseable {
- private static final Logger LOG =
LoggerFactory.getLogger(CSVStreamConnector.class);
+ protected static final Logger LOG =
LoggerFactory.getLogger(CSVStreamConnector.class);
- private final String keyColumn;
+ protected static String sanitize(final Object value) {
+ if (value == null) {
+ return null;
+ }
+
+ String v = value.toString().trim();
+ if (Strings.CS.startsWithAny(v, "=", "+", "-", "@", "\t", "\n", "\r"))
{
+ return "'" + v;
+ }
+ return v;
+ }
+
+ protected final String keyColumn;
- private final String arrayElementsSeparator;
+ protected final String arrayElementsSeparator;
- private final CsvSchema.Builder schemaBuilder;
+ protected final CsvSchema.Builder schemaBuilder;
- private final InputStream in;
+ protected final InputStream in;
- private final OutputStream out;
+ protected final OutputStream out;
- private final List<String> columns;
+ protected final List<String> columns;
- private MappingIterator<Map<String, String>> reader;
+ protected MappingIterator<Map<String, String>> reader;
- private SequenceWriter writer;
+ protected SequenceWriter writer;
public CSVStreamConnector(
final String keyColumn,
@@ -175,14 +188,13 @@ public class CSVStreamConnector implements Connector,
AutoCloseable {
if (CollectionUtils.isEmpty(attr.getValue()) ||
attr.getValue().getFirst() == null) {
row.put(attr.getName(), null);
} else if (attr.getValue().size() == 1) {
- row.put(attr.getName(), attr.getValue().getFirst().toString());
- } else if (arrayElementsSeparator == null) {
- row.put(attr.getName(), attr.getValue().toString());
+ row.put(attr.getName(), sanitize(attr.getValue().getFirst()));
} else {
row.put(
attr.getName(),
- attr.getValue().stream().map(Object::toString).
-
collect(Collectors.joining(arrayElementsSeparator)));
+
attr.getValue().stream().map(CSVStreamConnector::sanitize).
+
collect(Collectors.joining(arrayElementsSeparator == null
+ ? ";" : arrayElementsSeparator)));
}
});
try {