Fix for security hotspot related to safe archive expansion
[cps.git] / cps-rest / src / main / java / org / onap / cps / rest / utils / ZipFileSizeValidator.java
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Bell Canada.
4  *  ================================================================================
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *
16  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19
20 package org.onap.cps.rest.utils;
21
22 import lombok.Getter;
23 import lombok.Setter;
24 import org.onap.cps.spi.exceptions.ModelValidationException;
25
26 @Setter
27 @Getter
28 public class ZipFileSizeValidator {
29
30     private static final int THRESHOLD_ENTRIES = 10000;
31     private static final int THRESHOLD_SIZE = 100000000;
32     private static final double THRESHOLD_RATIO = 40;
33     private static final String INVALID_ZIP = "Invalid ZIP archive content.";
34
35     private int totalSizeArchive = 0;
36     private int totalEntryInArchive = 0;
37     private long compressedSize = 0;
38
39     /**
40      * Increment the totalEntryInArchive by 1.
41      */
42     public void incrementTotalEntryInArchive() {
43         totalEntryInArchive++;
44     }
45
46     /**
47      * Update the totalSizeArchive by numberOfBytesRead.
48      * @param numberOfBytesRead the number of bytes of each entry
49      */
50     public void updateTotalSizeArchive(final int numberOfBytesRead) {
51         totalSizeArchive += numberOfBytesRead;
52     }
53
54     /**
55      * Validate the total Compression size of the zip.
56      * @param totalEntrySize the size of the unzipped entry.
57      */
58     public void validateCompresssionRatio(final int totalEntrySize) {
59         final double compressionRatio = (double) totalEntrySize / compressedSize;
60         if (compressionRatio > THRESHOLD_RATIO) {
61             throw new ModelValidationException(INVALID_ZIP,
62                 String.format("Ratio between compressed and uncompressed data exceeds the CPS limit"
63                     + " %s.", THRESHOLD_RATIO));
64         }
65     }
66
67     /**
68      * Validate the total Size and number of entries in the zip.
69      */
70     public void validateSizeAndEntries() {
71         if (totalSizeArchive > THRESHOLD_SIZE) {
72             throw new ModelValidationException(INVALID_ZIP,
73                 String.format("The uncompressed data size exceeds the CPS limit %s bytes.", THRESHOLD_SIZE));
74         }
75         if (totalEntryInArchive > THRESHOLD_ENTRIES) {
76             throw new ModelValidationException(INVALID_ZIP,
77                 String.format("The number of entries in the archive exceeds the CPS limit %s.",
78                     THRESHOLD_ENTRIES));
79         }
80     }
81 }