Skip to content

Commit 3ad16cc

Browse files
authored
Adds adjustable ZipSecureFile Inflation Ratio for AAS Environment (#938)
* Adds adjustable ZipSecureFile Inflation Ratio for AAS Environment * Adapts ZipBomb Handling - Adds Error Message * Adds missing throw declerations * Adapts Exception Handling * Adapts Default from 1.0 to 0.1
1 parent fe08a53 commit 3ad16cc

File tree

13 files changed

+55
-22
lines changed

13 files changed

+55
-22
lines changed

basyx.aasenvironment/basyx.aasenvironment-core/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/environmentloader/CompleteEnvironment.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.eclipse.digitaltwin.aas4j.v3.dataformat.json.JsonDeserializer;
3939
import org.eclipse.digitaltwin.aas4j.v3.dataformat.xml.XmlDeserializer;
4040
import org.eclipse.digitaltwin.aas4j.v3.model.Environment;
41+
import org.eclipse.digitaltwin.basyx.core.exceptions.ZipBombException;
4142

4243
/**
4344
* Represents an environment and its relatedFiles
@@ -92,11 +93,11 @@ public List<InMemoryFile> getRelatedFiles() {
9293
return relatedFiles;
9394
}
9495

95-
public static CompleteEnvironment fromFile(File file) throws DeserializationException, InvalidFormatException, IOException {
96+
public static CompleteEnvironment fromFile(File file) throws DeserializationException, InvalidFormatException, IOException, ZipBombException {
9697
return fromInputStream(new FileInputStream(file), EnvironmentType.getFromFilePath(file.getPath()));
9798
}
9899

99-
public static CompleteEnvironment fromInputStream(InputStream inputStream, EnvironmentType envType) throws DeserializationException, InvalidFormatException, IOException {
100+
public static CompleteEnvironment fromInputStream(InputStream inputStream, EnvironmentType envType) throws DeserializationException, InvalidFormatException, IOException, ZipBombException {
100101
Environment environment = null;
101102
List<InMemoryFile> relatedFiles = null;
102103

@@ -109,9 +110,16 @@ public static CompleteEnvironment fromInputStream(InputStream inputStream, Envir
109110
environment = deserializer.read(inputStream);
110111
}
111112
if(envType == EnvironmentType.AASX) {
112-
AASXDeserializer deserializer = new AASXDeserializer(inputStream);
113-
relatedFiles = deserializer.getRelatedFiles();
114-
environment = deserializer.read();
113+
try {
114+
AASXDeserializer deserializer = new AASXDeserializer(inputStream);
115+
relatedFiles = deserializer.getRelatedFiles();
116+
environment = deserializer.read();
117+
} catch (Exception e) {
118+
if (e.getMessage().startsWith("Zip bomb")) {
119+
throw new ZipBombException(e);
120+
}
121+
throw e;
122+
}
115123
}
116124

117125
return new CompleteEnvironment(environment, relatedFiles);

basyx.aasenvironment/basyx.aasenvironment-core/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/preconfiguration/AasEnvironmentPreconfigurationLoader.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.eclipse.digitaltwin.basyx.aasenvironment.environmentloader.CompleteEnvironment;
4343
import org.eclipse.digitaltwin.basyx.aasenvironment.environmentloader.CompleteEnvironment.EnvironmentType;
4444
import org.eclipse.digitaltwin.basyx.authorization.CommonAuthorizationProperties;
45+
import org.eclipse.digitaltwin.basyx.core.exceptions.ZipBombException;
4546
import org.slf4j.Logger;
4647
import org.slf4j.LoggerFactory;
4748
import org.springframework.beans.factory.annotation.Autowired;
@@ -77,7 +78,7 @@ public boolean shouldLoadPreconfiguredEnvironment() {
7778
}
7879

7980
public void loadPreconfiguredEnvironments(AasEnvironment aasEnvironment)
80-
throws IOException, DeserializationException, InvalidFormatException {
81+
throws IOException, DeserializationException, InvalidFormatException, ZipBombException {
8182
List<File> files = scanForEnvironments(pathsToLoad);
8283

8384
if (files.isEmpty())

basyx.aasenvironment/basyx.aasenvironment-core/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/preconfiguration/PreconfigurationLoaderInitializer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
3131
import org.eclipse.digitaltwin.aas4j.v3.dataformat.core.DeserializationException;
3232
import org.eclipse.digitaltwin.basyx.aasenvironment.AasEnvironment;
33+
import org.eclipse.digitaltwin.basyx.core.exceptions.ZipBombException;
3334
import org.springframework.beans.factory.InitializingBean;
3435
import org.springframework.beans.factory.annotation.Autowired;
3536
import org.springframework.stereotype.Component;
@@ -60,7 +61,7 @@ public void afterPropertiesSet() throws Exception {
6061
loadPreconfiguredEnvironment();
6162
}
6263

63-
private void loadPreconfiguredEnvironment() throws IOException, InvalidFormatException, DeserializationException {
64+
private void loadPreconfiguredEnvironment() throws IOException, InvalidFormatException, DeserializationException, ZipBombException {
6465
if (!preconfigurationLoader.shouldLoadPreconfiguredEnvironment()) {
6566
return;
6667
}

basyx.aasenvironment/basyx.aasenvironment-core/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/AasEnvironmentLoaderTest.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.eclipse.digitaltwin.basyx.conceptdescriptionrepository.backend.CrudConceptDescriptionRepositoryFactory;
3737
import org.eclipse.digitaltwin.basyx.conceptdescriptionrepository.backend.InMemoryConceptDescriptionBackend;
3838
import org.eclipse.digitaltwin.basyx.core.exceptions.CollidingIdentifierException;
39+
import org.eclipse.digitaltwin.basyx.core.exceptions.ZipBombException;
3940
import org.eclipse.digitaltwin.basyx.core.filerepository.InMemoryFileRepository;
4041
import org.eclipse.digitaltwin.basyx.core.pagination.PaginationInfo;
4142
import org.eclipse.digitaltwin.basyx.submodelrepository.SubmodelRepository;
@@ -79,7 +80,7 @@ public void setUp() {
7980
conceptDescriptionRepository = Mockito.spy(CrudConceptDescriptionRepositoryFactory.builder().backend(new InMemoryConceptDescriptionBackend()).create());
8081
}
8182

82-
protected void loadRepositories(List<String> pathsToLoad) throws IOException, DeserializationException, InvalidFormatException {
83+
protected void loadRepositories(List<String> pathsToLoad) throws IOException, DeserializationException, InvalidFormatException, ZipBombException {
8384
DefaultAASEnvironment envLoader = new DefaultAASEnvironment(aasRepository, submodelRepository, conceptDescriptionRepository);
8485

8586
for (String path: pathsToLoad) {
@@ -89,7 +90,7 @@ protected void loadRepositories(List<String> pathsToLoad) throws IOException, De
8990
}
9091

9192
@Test
92-
public void testWithResourceFile_AllElementsAreDeployed() throws InvalidFormatException, IOException, DeserializationException {
93+
public void testWithResourceFile_AllElementsAreDeployed() throws InvalidFormatException, IOException, DeserializationException, ZipBombException {
9394
loadRepositories(List.of(TEST_ENVIRONMENT_JSON));
9495

9596
Assert.assertEquals(2, aasRepository.getAllAas(null, null, PaginationInfo.NO_LIMIT).getResult().size());
@@ -98,7 +99,7 @@ public void testWithResourceFile_AllElementsAreDeployed() throws InvalidFormatEx
9899
}
99100

100101
@Test
101-
public void testDeployedTwiceNoVersion_AllDeployedButNotOverriden() throws InvalidFormatException, IOException, DeserializationException {
102+
public void testDeployedTwiceNoVersion_AllDeployedButNotOverriden() throws InvalidFormatException, IOException, DeserializationException, ZipBombException {
102103
loadRepositories(List.of(TEST_ENVIRONMENT_JSON));
103104
loadRepositories(List.of(TEST_ENVIRONMENT_JSON));
104105

@@ -114,7 +115,7 @@ public void testDeployedTwiceNoVersion_AllDeployedButNotOverriden() throws Inval
114115
}
115116

116117
@Test
117-
public void testDeployedTwiceWithSameVersion_AllDeployedButNotOverriden() throws InvalidFormatException, IOException, DeserializationException {
118+
public void testDeployedTwiceWithSameVersion_AllDeployedButNotOverriden() throws InvalidFormatException, IOException, DeserializationException, ZipBombException {
118119
loadRepositories(List.of(TEST_ENVIRONMENT_VERSION_ON_SECOND_JSON));
119120
loadRepositories(List.of(TEST_ENVIRONMENT_VERSION_ON_SECOND_JSON));
120121

@@ -130,7 +131,7 @@ public void testDeployedTwiceWithSameVersion_AllDeployedButNotOverriden() throws
130131
}
131132

132133
@Test
133-
public void testDeployedTwiceNewRevision_ElementsAreOverriden() throws InvalidFormatException, IOException, DeserializationException {
134+
public void testDeployedTwiceNewRevision_ElementsAreOverriden() throws InvalidFormatException, IOException, DeserializationException, ZipBombException {
134135
loadRepositories(List.of(TEST_ENVIRONMENT_VERSION_ON_SECOND_JSON));
135136
loadRepositories(List.of(TEST_ENVIRONMENT_VERSION_AND_REVISION_ON_SECOND_JSON));
136137

@@ -159,7 +160,7 @@ public void testDuplicateShellIdsInEnvironments_ExceptionIsThrown() {
159160
}
160161

161162
@Test
162-
public void testWithResourceFile_NoExceptionsWhenReuploadAfterElementsAreRemoved() throws InvalidFormatException, IOException, DeserializationException {
163+
public void testWithResourceFile_NoExceptionsWhenReuploadAfterElementsAreRemoved() throws InvalidFormatException, IOException, DeserializationException, ZipBombException {
163164
AasEnvironment envLoader = new DefaultAASEnvironment(aasRepository, submodelRepository, conceptDescriptionRepository);
164165

165166
loadRepositoriesWithEnvironment(List.of(TEST_ENVIRONMENT_JSON), envLoader);
@@ -178,7 +179,7 @@ public void testWithResourceFile_NoExceptionsWhenReuploadAfterElementsAreRemoved
178179
}
179180

180181
@Test
181-
public void testWithResourceFile_ExceptionIsThrownWhenReuploadWithExistingElements() throws InvalidFormatException, IOException, DeserializationException {
182+
public void testWithResourceFile_ExceptionIsThrownWhenReuploadWithExistingElements() throws InvalidFormatException, IOException, DeserializationException, ZipBombException {
182183
AasEnvironment envLoader = new DefaultAASEnvironment(aasRepository, submodelRepository, conceptDescriptionRepository);
183184

184185
loadRepositoriesWithEnvironment(List.of(TEST_ENVIRONMENT_JSON), envLoader);
@@ -191,7 +192,7 @@ public void testWithResourceFile_ExceptionIsThrownWhenReuploadWithExistingElemen
191192
Assert.assertThrows(expectedMsg, CollidingIdentifierException.class, () -> loadRepositoriesWithEnvironment(List.of(TEST_ENVIRONMENT_JSON), envLoader));
192193
}
193194

194-
private void loadRepositoriesWithEnvironment(List<String> pathsToLoad, AasEnvironment aasEnvironment) throws IOException, DeserializationException, InvalidFormatException {
195+
private void loadRepositoriesWithEnvironment(List<String> pathsToLoad, AasEnvironment aasEnvironment) throws IOException, DeserializationException, InvalidFormatException, ZipBombException {
195196

196197
for (String path: pathsToLoad) {
197198
File file = rLoader.getResource(path).getFile();

basyx.aasenvironment/basyx.aasenvironment-core/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/PreconfigurationLoaderTextualResourceTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.eclipse.digitaltwin.aas4j.v3.dataformat.core.DeserializationException;
3232
import org.eclipse.digitaltwin.basyx.aasenvironment.base.DefaultAASEnvironment;
3333
import org.eclipse.digitaltwin.basyx.aasenvironment.preconfiguration.AasEnvironmentPreconfigurationLoader;
34+
import org.eclipse.digitaltwin.basyx.core.exceptions.ZipBombException;
3435
import org.eclipse.digitaltwin.basyx.core.pagination.PaginationInfo;
3536
import org.junit.Assert;
3637
import org.junit.Test;
@@ -45,13 +46,13 @@
4546
public class PreconfigurationLoaderTextualResourceTest extends AasEnvironmentLoaderTest {
4647

4748
@Override
48-
protected void loadRepositories(List<String> pathsToLoad) throws IOException, InvalidFormatException, DeserializationException {
49+
protected void loadRepositories(List<String> pathsToLoad) throws IOException, InvalidFormatException, DeserializationException, ZipBombException {
4950
AasEnvironmentPreconfigurationLoader envLoader = new AasEnvironmentPreconfigurationLoader(rLoader, pathsToLoad);
5051
envLoader.loadPreconfiguredEnvironments(new DefaultAASEnvironment(aasRepository, submodelRepository, conceptDescriptionRepository));
5152
}
5253

5354
@Test
54-
public void testWithEmptyResource_NoElementsAreDeployed() throws InvalidFormatException, IOException, DeserializationException {
55+
public void testWithEmptyResource_NoElementsAreDeployed() throws InvalidFormatException, IOException, DeserializationException, ZipBombException {
5556
loadRepositories(List.of());
5657
Assert.assertTrue(aasRepository.getAllAas(null, null, PaginationInfo.NO_LIMIT).getResult().isEmpty());
5758
Assert.assertTrue(submodelRepository.getAllSubmodels(PaginationInfo.NO_LIMIT).getResult().isEmpty());

basyx.aasenvironment/basyx.aasenvironment-feature-authorization/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/feature/authorization/AuthorizedAASEnvironmentPreconfigurationLoader.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.eclipse.digitaltwin.basyx.client.internal.authorization.TokenManager;
3636
import org.eclipse.digitaltwin.basyx.client.internal.authorization.grant.AccessTokenProvider;
3737
import org.eclipse.digitaltwin.basyx.client.internal.authorization.grant.GrantType;
38+
import org.eclipse.digitaltwin.basyx.core.exceptions.ZipBombException;
3839
import org.slf4j.Logger;
3940
import org.slf4j.LoggerFactory;
4041
import org.springframework.beans.factory.annotation.Value;
@@ -104,7 +105,7 @@ public AuthorizedAASEnvironmentPreconfigurationLoader(ResourceLoader resourceLoa
104105

105106
@Override
106107
public void loadPreconfiguredEnvironments(AasEnvironment aasEnvironment)
107-
throws IOException, InvalidFormatException, DeserializationException {
108+
throws IOException, InvalidFormatException, DeserializationException, ZipBombException {
108109
if (isEnvironmentSet()) {
109110
setUpTokenProvider();
110111
configureSecurityContext();

basyx.aasenvironment/basyx.aasenvironment-http/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/http/AASEnvironmentHTTPApi.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
3232
import org.eclipse.digitaltwin.aas4j.v3.dataformat.core.DeserializationException;
3333
import org.eclipse.digitaltwin.aas4j.v3.model.Result;
34+
import org.eclipse.digitaltwin.basyx.core.exceptions.ZipBombException;
3435
import org.springframework.core.io.Resource;
3536
import org.springframework.http.ResponseEntity;
3637
import org.springframework.validation.annotation.Validated;
@@ -83,5 +84,5 @@ ResponseEntity<Boolean> uploadEnvironment(
8384
@Parameter(description = "An environment file (XML, JSON, AASX)") @Valid @RequestParam("file") MultipartFile envFile,
8485
@Parameter(description = "Flag to indicate if already existing Ids should be ignored when reuploading an environment (default: false)", schema = @Schema(defaultValue = "false"))
8586
@RequestParam(value = "ignore-duplicates", required = false, defaultValue = "false") boolean ignoreDuplicates
86-
) throws IOException, InvalidFormatException, DeserializationException;
87+
) throws IOException, InvalidFormatException, DeserializationException, ZipBombException;
8788
}

basyx.aasenvironment/basyx.aasenvironment-http/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/http/AasEnvironmentApiHTTPController.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.eclipse.digitaltwin.basyx.aasenvironment.environmentloader.CompleteEnvironment;
3737
import org.eclipse.digitaltwin.basyx.aasenvironment.environmentloader.CompleteEnvironment.EnvironmentType;
3838
import org.eclipse.digitaltwin.basyx.core.exceptions.ElementDoesNotExistException;
39+
import org.eclipse.digitaltwin.basyx.core.exceptions.ZipBombException;
3940
import org.eclipse.digitaltwin.basyx.http.Base64UrlEncodedIdentifier;
4041
import org.springframework.beans.factory.annotation.Autowired;
4142
import org.springframework.core.io.ByteArrayResource;
@@ -104,7 +105,7 @@ public ResponseEntity<Resource> generateSerializationByIds(
104105
@Override
105106
public ResponseEntity<Boolean> uploadEnvironment(
106107
@RequestParam(value = "file") MultipartFile envFile,
107-
@RequestParam(value = "ignore-duplicates", required = false, defaultValue = "false") boolean ignoreDuplicates) throws IOException, InvalidFormatException, DeserializationException {
108+
@RequestParam(value = "ignore-duplicates", required = false, defaultValue = "false") boolean ignoreDuplicates) throws IOException, InvalidFormatException, DeserializationException, ZipBombException {
108109
EnvironmentType envType = EnvironmentType.getFromMimeType(envFile.getContentType());
109110

110111
if (envType == null)

basyx.aasenvironment/basyx.aasenvironment.component/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/component/AasEnvironmentConfiguration.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@
2727

2828
import java.util.List;
2929

30+
import org.apache.poi.openxml4j.util.ZipSecureFile;
3031
import org.eclipse.digitaltwin.basyx.aasenvironment.AasEnvironment;
3132
import org.eclipse.digitaltwin.basyx.aasenvironment.AasEnvironmentFactory;
3233
import org.eclipse.digitaltwin.basyx.aasenvironment.feature.AasEnvironmentFeature;
3334
import org.eclipse.digitaltwin.basyx.aasenvironment.feature.DecoratedAasEnvironmentFactory;
3435
import org.eclipse.digitaltwin.basyx.aasenvironment.preconfiguration.AasEnvironmentPreconfigurationLoader;
36+
import org.springframework.beans.factory.annotation.Value;
3537
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
3638
import org.springframework.context.annotation.Bean;
3739
import org.springframework.context.annotation.Configuration;
@@ -48,7 +50,8 @@ public class AasEnvironmentConfiguration {
4850

4951
@Bean
5052
@ConditionalOnMissingBean
51-
public static AasEnvironment getAasEnvironment(AasEnvironmentFactory aasEnvironmentFactory, List<AasEnvironmentFeature> features) {
53+
public static AasEnvironment getAasEnvironment(AasEnvironmentFactory aasEnvironmentFactory, List<AasEnvironmentFeature> features, @Value("${basyx.aasenvironment.minInflateRatio:0.1}") double minInflateRatio) {
54+
ZipSecureFile.setMinInflateRatio(minInflateRatio);
5255
return new DecoratedAasEnvironmentFactory(aasEnvironmentFactory, features).create();
5356
}
5457

basyx.aasenvironment/basyx.aasenvironment.component/src/main/resources/application.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ basyx.backend = InMemory
2020
# basyx.cors.allowed-origins=http://localhost:3000, http://localhost:4000
2121
# basyx.cors.allowed-methods=GET,POST,PATCH,DELETE,PUT,OPTIONS,HEAD
2222

23+
# basyx.aasenvironment.minInflateRatio=0.00001
24+
2325
####################################################################################
2426
# Preconfiguring the Environment;
2527
####################################################################################

0 commit comments

Comments
 (0)