Compare commits

..
Author SHA1 Message Date
Anthony Stirling f1cdf6992f fix 2025-08-05 15:01:01 +01:00
Anthony Stirling e284f818b7 test 2025-08-05 14:51:27 +01:00
a 662389d897 Merge branch 'SecurityFixesTest' of git@github.com:Stirling-Tools/Stirling-PDF.git into SecurityFixesTest 2025-08-05 14:37:29 +01:00
Anthony Stirling 9deb900de4 furhter 2025-08-05 14:37:22 +01:00
Anthony StirlingandGitHub b5aa595842 Update build.gradle 2025-08-05 14:10:53 +01:00
Anthony Stirling 2c6f27a0b0 security fixes test 2025-08-05 13:37:25 +01:00
9 changed files with 48 additions and 72 deletions
+3 -3
View File
@@ -88,7 +88,7 @@ jobs:
- name: Generate tags
id: meta
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
if: github.ref != 'refs/heads/main'
with:
images: |
@@ -134,7 +134,7 @@ jobs:
- name: Generate tags ultra-lite
id: meta2
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
if: github.ref != 'refs/heads/main'
with:
images: |
@@ -165,7 +165,7 @@ jobs:
- name: Generate tags fat
id: meta3
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
with:
images: |
${{ secrets.DOCKER_HUB_USERNAME }}/s-pdf
+9 -2
View File
@@ -43,6 +43,7 @@ ENV DISABLE_ADDITIONAL_FEATURES=true \
RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
echo "@community https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
apk update && \
apk upgrade --no-cache -a && \
apk add --no-cache \
ca-certificates \
@@ -55,6 +56,11 @@ RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/a
openssl \
openssl-dev \
openjdk21-jre \
# Security updates - remove when Alpine base image updates these
# libjxl fixes CVE-2024-11403, CVE-2024-11498
# rav1e fixes CVE-2025-4574, GHSA-2rxc-gjrp-vjhx, RUSTSEC-2024-0404, GHSA-pg9f-39pc-qf8g
libjxl \
rav1e \
# Doc conversion
gcompat \
libc6-compat \
@@ -73,8 +79,9 @@ RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/a
python3 \
ocrmypdf \
py3-pip \
py3-pillow@testing \
py3-pdf2image@testing \
# py3-pillow fixes CVE-2025-48379 - ensure Pillow 11.3.0+ instead of 11.2.1
py3-pillow \
py3-pdf2image \
# URW Base 35 fonts for better PDF rendering
font-urw-base35 && \
python3 -m venv /opt/venv && \
+9 -2
View File
@@ -57,6 +57,7 @@ ENV DISABLE_ADDITIONAL_FEATURES=true \
RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
echo "@community https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
apk update && \
apk upgrade --no-cache -a && \
apk add --no-cache \
ca-certificates \
@@ -69,6 +70,11 @@ RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/a
openssl \
openssl-dev \
openjdk21-jre \
# Security updates - remove when Alpine base image updates these
# libjxl fixes CVE-2024-11403, CVE-2024-11498
# rav1e fixes CVE-2025-4574, GHSA-2rxc-gjrp-vjhx, RUSTSEC-2024-0404, GHSA-pg9f-39pc-qf8g
libjxl \
rav1e \
# Doc conversion
gcompat \
libc6-compat \
@@ -88,8 +94,9 @@ RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/a
python3 \
ocrmypdf \
py3-pip \
py3-pillow@testing \
py3-pdf2image@testing && \
# py3-pillow fixes CVE-2025-48379 - ensure Pillow 11.3.0+ instead of 11.2.1
py3-pillow \
py3-pdf2image && \
python3 -m venv /opt/venv && \
/opt/venv/bin/pip install --no-cache-dir --upgrade pip setuptools && \
/opt/venv/bin/pip install --no-cache-dir --upgrade unoserver weasyprint && \
+9 -3
View File
@@ -24,9 +24,10 @@ COPY scripts/installFonts.sh /scripts/installFonts.sh
COPY app/core/build/libs/*.jar app.jar
# Set up necessary directories and permissions
RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \
RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
echo "@community https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
apk update && \
apk upgrade --no-cache -a && \
apk add --no-cache \
ca-certificates \
@@ -36,7 +37,12 @@ RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /et
curl \
shadow \
su-exec \
openjdk21-jre && \
openjdk21-jre \
# Security updates - remove when Alpine base image updates these
# libjxl fixes CVE-2024-11403, CVE-2024-11498
# rav1e fixes CVE-2025-4574, GHSA-2rxc-gjrp-vjhx, RUSTSEC-2024-0404, GHSA-pg9f-39pc-qf8g
libjxl \
rav1e && \
# User permissions
mkdir -p /configs /logs /customFiles /usr/share/fonts/opentype/noto /tmp/stirling-pdf /pipeline/watchedFolders /pipeline/finishedFolders && \
chmod +x /scripts/*.sh && \
+1 -1
View File
@@ -41,5 +41,5 @@ dependencies {
api 'org.snakeyaml:snakeyaml-engine:2.10'
api "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.9"
api 'jakarta.mail:jakarta.mail-api:2.1.3'
runtimeOnly 'org.eclipse.angus:angus-mail:2.0.4'
runtimeOnly 'org.eclipse.angus:angus-mail:2.0.3'
}
@@ -56,20 +56,13 @@ public class TempFileCleanupService {
|| fileName.startsWith("pdf-stream-")
|| fileName.startsWith("PDFBox")
|| fileName.startsWith("input_")
|| fileName.startsWith("overlay-")
|| fileName.startsWith("signature")
|| fileName.startsWith("original_")
|| fileName.startsWith("preprocessed_")
|| fileName.startsWith("temp")
|| fileName.startsWith("gs_")
|| fileName.startsWith("MultiPart");
|| fileName.startsWith("overlay-");
// File patterns that identify common system temp files
private static final Predicate<String> IS_SYSTEM_TEMP_FILE =
fileName ->
fileName.matches("lu\\d+[a-z0-9]*(\\.tmp)?")
fileName.matches("lu\\d+[a-z0-9]*\\.tmp")
|| fileName.matches("ocr_process\\d+")
|| fileName.contains("ocrmypdf.io.")
|| (fileName.startsWith("tmp") && !fileName.contains("jetty"))
|| fileName.startsWith("OSL_PIPE_")
|| (fileName.endsWith(".tmp") && !fileName.contains("jetty"));
@@ -77,9 +70,8 @@ public class TempFileCleanupService {
// File patterns that should be excluded from cleanup
private static final Predicate<String> SHOULD_SKIP =
fileName ->
(fileName.contains("jetty")
&& !fileName.startsWith("jetty-0_0_0_0-8080--_-any-"))
|| fileName.startsWith("jetty-docbase")
fileName.contains("jetty")
|| fileName.startsWith("jetty-")
|| "proc".equals(fileName)
|| "sys".equals(fileName)
|| "dev".equals(fileName)
@@ -403,18 +395,6 @@ public class TempFileCleanupService {
log.debug("Could not check file info, skipping: {}", path);
}
// Fallback: if file is in our managed temp directories and older than maxAge, delete it
// regardless of filename pattern (this catches any temp files we might have missed)
if (!shouldDelete && maxAgeMillis > 0 && lastModified > 0) {
boolean isInManagedTempDir = isInManagedTempDirectory(path);
boolean isOlderThanMaxAge = (currentTime - lastModified) > maxAgeMillis;
if (isInManagedTempDir && isOlderThanMaxAge) {
shouldDelete = true;
log.debug("Deleting old file in managed temp directory: {}", path);
}
}
// Check file age against maxAgeMillis only if it's not an empty file that we've already
// decided to delete
if (!isEmptyFile && shouldDelete && maxAgeMillis > 0) {
@@ -425,38 +405,6 @@ public class TempFileCleanupService {
return shouldDelete;
}
/** Check if a path is within one of our managed temp directories. */
private boolean isInManagedTempDirectory(Path path) {
try {
ApplicationProperties.TempFileManagement tempFiles =
applicationProperties.getSystem().getTempFileManagement();
String baseTmpDir = tempFiles.getBaseTmpDir();
String libreOfficeDir = tempFiles.getLibreofficeDir();
// Check if path is under our main temp directory
if (baseTmpDir != null && !baseTmpDir.isEmpty()) {
Path baseTempPath = Path.of(baseTmpDir).toAbsolutePath().normalize();
if (path.toAbsolutePath().normalize().startsWith(baseTempPath)) {
return true;
}
}
// Check if path is under LibreOffice temp directory
if (libreOfficeDir != null && !libreOfficeDir.isEmpty()) {
Path libreOfficePath = Path.of(libreOfficeDir).toAbsolutePath().normalize();
if (path.toAbsolutePath().normalize().startsWith(libreOfficePath)) {
return true;
}
}
} catch (Exception e) {
log.debug("Error checking if path is in managed temp directory: {}", path, e);
}
return false;
}
/** Clean up LibreOffice temporary files. This method is called after LibreOffice operations. */
public void cleanupLibreOfficeTempFiles() {
// Cleanup known LibreOffice temp directories
+4 -1
View File
@@ -41,7 +41,7 @@ dependencies {
api 'org.springframework.boot:spring-boot-starter-data-jpa'
api 'org.springframework.boot:spring-boot-starter-oauth2-client'
api 'org.springframework.boot:spring-boot-starter-mail'
api 'io.swagger.core.v3:swagger-core-jakarta:2.2.35'
api 'io.swagger.core.v3:swagger-core-jakarta:2.2.34'
implementation 'com.bucket4j:bucket4j_jdk17-core:8.14.0'
// https://mvnrepository.com/artifact/com.bucket4j/bucket4j_jdk17
@@ -56,6 +56,9 @@ dependencies {
implementation "org.opensaml:opensaml-core:$openSamlVersion"
implementation "org.opensaml:opensaml-saml-api:$openSamlVersion"
implementation "org.opensaml:opensaml-saml-impl:$openSamlVersion"
// Security vulnerability fixes - remove when parent dependencies update
implementation 'com.nimbusds:nimbus-jose-jwt:10.0.2' // CVE-2025-53864 - from spring-boot-starter-oauth2-client
implementation 'com.google.guava:guava:33.4.8-jre' // CVE-2023-2976, CVE-2020-8908 - from OpenSAML dependencies above
}
implementation 'com.coveo:saml-client:5.0.0'
}
+9 -2
View File
@@ -28,7 +28,7 @@ ext {
bouncycastleVersion = "1.81"
springSecuritySamlVersion = "6.5.2"
openSamlVersion = "4.3.2"
commonmarkVersion = "0.25.1"
commonmarkVersion = "0.25.0"
googleJavaFormatVersion = "1.28.0"
tempJrePath = null
}
@@ -57,7 +57,7 @@ repositories {
allprojects {
group = 'stirling.software'
version = '1.1.1'
version = '1.1.2'
configurations.configureEach {
exclude group: 'commons-logging', module: 'commons-logging'
@@ -128,6 +128,13 @@ subprojects {
imports {
mavenBom "org.springframework.boot:spring-boot-dependencies:$springBootVersion"
}
dependencies {
// Security vulnerability fixes - remove when Spring Security updates these
dependency 'com.nimbusds:nimbus-jose-jwt:10.0.2' // CVE-2025-53864 - from spring-boot-starter-oauth2-client
dependency 'com.google.guava:guava:33.4.8-jre' // CVE-2023-2976, CVE-2020-8908 - from OpenSAML dependencies
dependency 'commons-io:commons-io:2.14.0' // CVE-2024-47554 - from various dependencies
dependency 'org.apache.commons:commons-lang3:3.18.0' // CVE-2025-48924 - from transitive dependencies
}
}
dependencies {
-2
View File
@@ -1027,6 +1027,4 @@ ignore = [
[zh_TW]
ignore = [
'language.direction',
'poweredBy',
'showJS.tags',
]