File tree Expand file tree Collapse file tree
framework/fit/java/fit-util/src/main/java/modelengine/fitframework/util/support Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -204,20 +204,41 @@ private File getTarget(ZipEntry entry) {
204204 }
205205 }
206206
207+ // 使用专门的方法验证并构建安全的目标路径
208+ return this .validateAndBuildTargetPath (entry );
209+ }
210+
211+ /**
212+ * 验证 ZIP entry 并构建安全的目标路径,防止 Zip Slip 路径遍历攻击(CWE-22)。
213+ * <p>
214+ * 此方法实现以下安全措施:
215+ * <ul>
216+ * <li>检测绝对路径攻击(以 {@code /}、{@code \} 或驱动器字母开头的路径)。</li>
217+ * <li>使用 {@link Path#normalize()} 规范化路径,消除 {@code ..} 和 {@code .} 等元素。</li>
218+ * <li>使用 {@link Path#startsWith(Path)} 验证路径未逃逸目标目录。</li>
219+ * </ul>
220+ * </p>
221+ *
222+ * @param entry 表示待解包的 ZIP 文件项的 {@link ZipEntry}。
223+ * @return 表示经过安全验证的目标文件的 {@link File}。
224+ * @throws SecurityException 如果检测到潜在的路径遍历攻击。
225+ */
226+ private File validateAndBuildTargetPath (ZipEntry entry ) {
207227 String name = entry .getName ();
208228
209- // 检查是否包含绝对路径字符(以'/'或驱动器字母开头)
229+ // 第一道防线: 检查是否包含绝对路径字符(以'/'或驱动器字母开头)
210230 if (name .startsWith ("/" ) || name .startsWith ("\\ " ) || (name .length () > 1 && name .charAt (1 ) == ':' )) {
211231 if (!this .security .isCrossPath ()) {
212232 throw new SecurityException (StringUtils .format ("Detected a potential path traversal attack. [path={0}]" ,
213233 name ));
214234 }
215235 }
216236
237+ // 第二道防线:构建规范化路径并验证
217238 Path targetDir = this .getTargetDirectory ().toPath ().normalize ();
218239 Path targetPath = targetDir .resolve (name ).normalize ();
219240
220- // 使用Path.startsWith进行前缀检查(比String.startsWith更安全)
241+ // 第三道防线: 使用Path.startsWith进行前缀检查(比String.startsWith更安全)
221242 if (!this .security .isCrossPath () && !targetPath .startsWith (targetDir )) {
222243 throw new SecurityException (StringUtils .format ("Detected a potential path traversal attack. [path={0}]" ,
223244 name ));
You can’t perform that action at this time.
0 commit comments