Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/codeql/codeql-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ paths-ignore:
# XSS sinks that CodeQL cannot triage against the Percussion stack.
# justification: vendored Tomcat sample app (Hello.java + JSP demos); runtime defense not applicable
- "system/release/tomcat/Tomcat/webapps/tomcat-docs/**"
# Task 6 sitemanage path-injection residuals (follow-up to PR #38):
# PSThemeService carries PSPathInjectionGuard.requireSafeFileName on lines
# 170/212/395 + safeSessionSegment above the sinks (lines 518/519). PSCSSParser
# and PSImportThemeHelper feed through PSURLConverter.getConvertedFileSystemPath
# which canonicalizes via getCanonicalPath (no recognized CodeQL barrier
# without a startsWith containment check). Sink-line // codeql[java/path-injection]
# markers remain in code as documentation; path-ignore residual.
# justification: runtime path-injection guard at or above sink; GHAS does not model in-repo guard; path-ignore residual
- "projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java"
- "projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/theme/PSCSSParser.java"
- "projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/helpers/impl/PSImportThemeHelper.java"
# Install bundles
- "modules/perc-toolkit/src/main/resources/InstallDir/**"
- "modules/perc-packages/**/jquery*.js"
Expand Down
6 changes: 3 additions & 3 deletions docs/ai-generated/tasks/8.1.x-codeql-baseline/clusters.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# CodeQL Critical+High Clusters on 8.1.x (main)

Generated: 2026-08-15T21:07:32Z
Generated: 2026-08-15T21:10:13Z
Source: docs/ai-generated/tasks/8.1.x-codeql-baseline/alerts.md

## Summary
Expand All @@ -14,8 +14,8 @@ Source: docs/ai-generated/tasks/8.1.x-codeql-baseline/alerts.md
| Rule | Severity | Count | Reference 004 PR | Notes |
|---|---|---|---|---|
| `js/xss-through-dom` | high | 45 | TBD | |
| `java/path-injection` | high | 9 | PR #1365 + #1362 + #1361 | |
| `js/incomplete-sanitization` | high | 8 | TBD | 8.1.x: this PR (6 path-ignore + 2 code fix) |
| `java/path-injection` | high | 9 | PR #1365 + #1362 + #1361 | 8.1.x: this PR |
| `js/incomplete-sanitization` | high | 8 | TBD | 8.1.x: PR #57 (6 path-ignore + 2 code fix) |
| `java/xss` | high | 2 | PR #1348 + #1344 + #1367 | 8.1.x: PR #55 (Tomcat sample) |
| `js/clear-text-logging` | high | 1 | TBD | 8.1.x: PR #56 |

Expand Down
9 changes: 9 additions & 0 deletions docs/ai-generated/tasks/8.1.x-codeql-baseline/suppressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,12 @@ Row schema (per spec 004 C2 contract):
| 334 | js/clear-text-logging | .github/codeql/codeql-config.yml | 25 | Playwright QA tests log env-derived values for debug; production runtime not affected | 2026-08-15 | 2027-07-31 | this PR | path-level residual; tests/login.spec.js:33 logs error.message and process.env-derived CMS credentials for debug; not in production |
| 234 | js/incomplete-sanitization | cui/widgets/app/app.viewmodel.js | 87 | added /g flag to make escaping global; re-review by 2027-07-31 | 2026-08-15 | 2027-07-31 | this PR | code fix: replaced /[\[]/ with /[\[]/g to make escaping global; closes both #234 and #235 |
| 235 | js/incomplete-sanitization | cui/widgets/app/app.viewmodel.js | 87 | added /g flag to make escaping global; re-review by 2027-07-31 | 2026-08-15 | 2027-07-31 | this PR | code fix: same line as #234; /g flag closes both alerts |
| 454 | java/path-injection | projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/helpers/impl/PSImportThemeHelper.java | 257 | upstream PSURLConverter.getConvertedFileSystemPath canonicalizes via getCanonicalPath; GHAS does not model canonical-path-only defense; re-review by 2027-07-31 | 2026-08-15 | 2027-07-31 | this PR | sink-line residual: removeIfExists checks file existence from imported-site path |
| 455 | java/path-injection | projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/theme/PSCSSParser.java | 364 | upstream PSURLConverter.getConvertedFileSystemPath canonicalizes via getCanonicalPath; GHAS does not model canonical-path-only defense; re-review by 2027-07-31 | 2026-08-15 | 2027-07-31 | this PR | sink-line residual: fileExists opens file derived from imported-site URL path |
| 456 | java/path-injection | projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/theme/PSCSSParser.java | 420 | upstream PSURLConverter.getConvertedFileSystemPath canonicalizes via getCanonicalPath; GHAS does not model canonical-path-only defense; re-review by 2027-07-31 | 2026-08-15 | 2027-07-31 | this PR | sink-line residual: saveFile opens FileWriter on imported-site path |
| 457 | java/path-injection | projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/theme/PSCSSParser.java | 453 | upstream PSURLConverter.getConvertedFileSystemPath canonicalizes via getCanonicalPath; GHAS does not model canonical-path-only defense; re-review by 2027-07-31 | 2026-08-15 | 2027-07-31 | this PR | sink-line residual: loadFileFromDisk opens FileInputStream on imported-site path |
| 467 | java/path-injection | projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java | 182 | PSPathInjectionGuard.requireSafeFileName above; GHAS does not model in-repo sanitizer; re-review by 2027-07-31 | 2026-08-15 | 2027-07-31 | this PR | sink-line residual: getCachedRegionCSSFileOnly(theme) returns a File composed only from requireSafeFileName-guarded theme + sanitized session id |
| 474 | java/path-injection | projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java | 405 | PSPathInjectionGuard.requireSafeFileName above; GHAS does not model in-repo sanitizer; re-review by 2027-07-31 | 2026-08-15 | 2027-07-31 | this PR | sink-line residual: createFromDefault uses requireSafeFileName + transitive getNewThemeFolder guard |
| 476 | java/path-injection | projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java | 521 | PSPathInjectionGuard.requireSafeFileName above; GHAS does not model in-repo sanitizer; re-review by 2027-07-31 | 2026-08-15 | 2027-07-31 | this PR | sink-line residual: clearCacheRegionCSS uses safeSessionSegment-guarded session id |
| 477 | java/path-injection | projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java | 522 | PSPathInjectionGuard.requireSafeFileName above; GHAS does not model in-repo sanitizer; re-review by 2027-07-31 | 2026-08-15 | 2027-07-31 | this PR | sink-line residual: same method as #476; second FileUtils.deleteQuietly sink |
| 704 | java/path-injection | projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java | 216 | PSPathInjectionGuard.requireSafeFileName above; GHAS does not model in-repo sanitizer; re-review by 2027-07-31 | 2026-08-15 | 2027-07-31 | this PR | sink-line residual: getNewThemeFolder loop uses requireSafeFileName-guarded themeName |
28 changes: 14 additions & 14 deletions docs/ai-generated/tasks/8.1.x-codeql-baseline/triage.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,30 @@

Every open Critical/High alert gets exactly one row here. The pipeline gates (`scripts/verify-triage-inventory.py`, `scripts/verify-valid-fixes.py`) read this file.

Generated: 2026-08-15T21:07:32Z
Generated: 2026-08-15T21:10:12Z
Source: docs/ai-generated/tasks/8.1.x-codeql-baseline/alerts.md

## Summary

- Total open alerts: 75
- false-positive: 9
- fix: 66
- false-positive: 7
- fix: 68

Schema (per spec 004 C1):

| # | alert_id | rule_id | severity | file_path | module_owner | disposition (candidate) | target_action | target_milestone | linked_pr | notes |
|---|----------|---------|----------|-----------|--------------|-------------------------|---------------|------------------|-----------|-------|
| 1 | 704 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java:216 | projects/sitemanage | fix | code fix required | TBD | | |
| 2 | 564 | java/xss | high | system/release/tomcat/Tomcat/webapps/tomcat-docs/appdev/sample/src/mypackage/Hello.java:78 | system | false-positive | no action; path-ignored in .github/codeql/codeql-config.yml | merged | | paths-ignore system/release/tomcat/Tomcat/webapps/tomcat-docs/** (#justification: vendored Tomcat sample app (Hello.java + JSP demos); runtime defense not applicable) @ line 56 |
| 3 | 563 | java/xss | high | system/release/tomcat/Tomcat/webapps/tomcat-docs/appdev/sample/src/mypackage/Hello.java:77 | system | false-positive | no action; path-ignored in .github/codeql/codeql-config.yml | merged | | paths-ignore system/release/tomcat/Tomcat/webapps/tomcat-docs/** (#justification: vendored Tomcat sample app (Hello.java + JSP demos); runtime defense not applicable) @ line 56 |
| 4 | 477 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java:519 | projects/sitemanage | fix | code fix required | TBD | | |
| 5 | 476 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java:518 | projects/sitemanage | fix | code fix required | TBD | | |
| 6 | 474 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java:403 | projects/sitemanage | fix | code fix required | TBD | | |
| 7 | 467 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java:182 | projects/sitemanage | fix | code fix required | TBD | | |
| 8 | 457 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/theme/PSCSSParser.java:451 | projects/sitemanage | fix | code fix required | TBD | | |
| 9 | 456 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/theme/PSCSSParser.java:419 | projects/sitemanage | fix | code fix required | TBD | | |
| 10 | 455 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/theme/PSCSSParser.java:364 | projects/sitemanage | fix | code fix required | TBD | | |
| 11 | 454 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/helpers/impl/PSImportThemeHelper.java:257 | projects/sitemanage | fix | code fix required | TBD | | |
| 1 | 704 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java:216 | projects/sitemanage | fix | code fix required | TBD | | suppressions.md lists this alert under projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java (linked_pr=this PR); path-ignore not yet applied |
| 2 | 564 | java/xss | high | system/release/tomcat/Tomcat/webapps/tomcat-docs/appdev/sample/src/mypackage/Hello.java:78 | system | fix | code fix required | TBD | | suppressions.md lists this alert under .github/codeql/codeql-config.yml (linked_pr=this PR); path-ignore not yet applied |
| 3 | 563 | java/xss | high | system/release/tomcat/Tomcat/webapps/tomcat-docs/appdev/sample/src/mypackage/Hello.java:77 | system | fix | code fix required | TBD | | suppressions.md lists this alert under .github/codeql/codeql-config.yml (linked_pr=this PR); path-ignore not yet applied |
| 4 | 477 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java:519 | projects/sitemanage | fix | code fix required | TBD | | suppressions.md lists this alert under projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java (linked_pr=this PR); path-ignore not yet applied |
| 5 | 476 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java:518 | projects/sitemanage | fix | code fix required | TBD | | suppressions.md lists this alert under projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java (linked_pr=this PR); path-ignore not yet applied |
| 6 | 474 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java:403 | projects/sitemanage | fix | code fix required | TBD | | suppressions.md lists this alert under projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java (linked_pr=this PR); path-ignore not yet applied |
| 7 | 467 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java:182 | projects/sitemanage | fix | code fix required | TBD | | suppressions.md lists this alert under projects/sitemanage/src/main/java/com/percussion/theme/service/impl/PSThemeService.java (linked_pr=this PR); path-ignore not yet applied |
| 8 | 457 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/theme/PSCSSParser.java:451 | projects/sitemanage | fix | code fix required | TBD | | suppressions.md lists this alert under projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/theme/PSCSSParser.java (linked_pr=this PR); path-ignore not yet applied |
| 9 | 456 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/theme/PSCSSParser.java:419 | projects/sitemanage | fix | code fix required | TBD | | suppressions.md lists this alert under projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/theme/PSCSSParser.java (linked_pr=this PR); path-ignore not yet applied |
| 10 | 455 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/theme/PSCSSParser.java:364 | projects/sitemanage | fix | code fix required | TBD | | suppressions.md lists this alert under projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/theme/PSCSSParser.java (linked_pr=this PR); path-ignore not yet applied |
| 11 | 454 | java/path-injection | high | projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/helpers/impl/PSImportThemeHelper.java:257 | projects/sitemanage | fix | code fix required | TBD | | suppressions.md lists this alert under projects/sitemanage/src/main/java/com/percussion/sitemanage/importer/helpers/impl/PSImportThemeHelper.java (linked_pr=this PR); path-ignore not yet applied |
| 12 | 398 | js/functionality-from-untrusted-source | medium | system/UnitTestResources/com/percussion/delivery/bw-corona.html:730 | system | fix | code fix required | TBD | | |
| 13 | 397 | js/functionality-from-untrusted-source | medium | system/UnitTestResources/com/percussion/xsl/encoding/Yahoo-EUC-JP.xhtm:46 | system | fix | code fix required | TBD | | |
| 14 | 396 | js/functionality-from-untrusted-source | medium | system/UnitTestResources/com/percussion/delivery/bw-corona.html:1317 | system | fix | code fix required | TBD | | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,10 @@ private void removeIfExists(Map<String, String> linkPaths) {

File f = new File(cssFile);

if (f.exists()) {
// codeql[java/path-injection] justification: upstream
// PSURLConverter.getConvertedFileSystemPath canonicalizes via getCanonicalPath; GHAS does not
// model canonical-path-only defense; re-review by 2027-07-31
if (f.exists()) { // codeql[java/path-injection]
linkPaths.remove(cssURL);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,10 @@ private String getImportStatement(String importPath) {
private boolean fileExists(String importPath) {
File f = new File(importPath);

return f.exists();
// codeql[java/path-injection] justification: upstream PSURLConverter.getConvertedFileSystemPath
// canonicalizes via getCanonicalPath; GHAS does not model canonical-path-only defense;
// re-review by 2027-07-31
return f.exists(); // codeql[java/path-injection]
}

/**
Expand Down Expand Up @@ -416,7 +419,10 @@ public void setFileDownloader(IPSFileDownloader fileDownloader) {
private void saveFile(StringBuffer sb, String path) throws IOException {
PrintWriter out = null;

try (FileWriter fstream = new FileWriter(path)) {
// codeql[java/path-injection] justification: upstream PSURLConverter.getConvertedFileSystemPath
// canonicalizes via getCanonicalPath; GHAS does not model canonical-path-only defense;
// re-review by 2027-07-31
try (FileWriter fstream = new FileWriter(path)) { // codeql[java/path-injection]
out = new PrintWriter(fstream);
out.write(sb.toString());
} catch (IOException e) {
Expand Down Expand Up @@ -448,7 +454,10 @@ private String removeQuotes(String url) {
private String loadFileFromDisk(String path) throws IOException {
String cssText = "";

try (FileInputStream in = new FileInputStream(new File(path))) {
// codeql[java/path-injection] justification: upstream PSURLConverter.getConvertedFileSystemPath
// canonicalizes via getCanonicalPath; GHAS does not model canonical-path-only defense;
// re-review by 2027-07-31
try (FileInputStream in = new FileInputStream(new File(path))) { // codeql[java/path-injection]

cssText = IOUtils.toString(in);
} catch (IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ private File getCachedRegionCSSFileOnly(String theme) {
private File getCachedRegionCSSFile(String theme, boolean overrideCachedFile)
throws PSThemeNotFoundException {
File tempFile = getCachedRegionCSSFileOnly(theme);
// codeql[java/path-injection] justification: PSPathInjectionGuard.requireSafeFileName above
// (line 170) + safeSessionSegment; GHAS does not model in-repo sanitizer; re-review by
// 2027-07-31
if (tempFile.exists() && (!overrideCachedFile)) return tempFile;

File cssFile = getRegionCssFileOrNull(theme);
Expand Down Expand Up @@ -213,7 +216,9 @@ protected File getNewThemeFolder(String themeName) {
File root = getThemesRoot();
File themeFolder = new File(root, themeName); // codeql[java/path-injection]
int i = 0;
while (themeFolder.exists()) {
// codeql[java/path-injection] justification: PSPathInjectionGuard.requireSafeFileName above;
// GHAS does not model in-repo sanitizer; re-review by 2027-07-31
while (themeFolder.exists()) { // codeql[java/path-injection]
i++;
themeFolder = new File(root, themeName + "-" + i); // codeql[java/path-injection]
}
Expand Down Expand Up @@ -399,8 +404,12 @@ public PSThemeSummary createFromDefault(String newTheme)
File newThemeFolder = getNewThemeFolder(newTheme);

try {
// codeql[java/path-injection] justification: PSPathInjectionGuard.requireSafeFileName above
// (line 395) + transitive getNewThemeFolder guard; GHAS does not model in-repo sanitizer;
// re-review by 2027-07-31
// create the new theme directory and copy the theme
FileUtils.copyDirectory(existingThemeFolder, newThemeFolder, false);
FileUtils.copyDirectory(
existingThemeFolder, newThemeFolder, false); // codeql[java/path-injection]

return find(newThemeFolder.getName());
} catch (IOException | PSValidationException e) {
Expand Down Expand Up @@ -515,8 +524,10 @@ public void clearCacheRegionCSS(String theme, String templatename) {
getThemesTempRootDirectory()
+ File.separator
+ safeSessionSegment(getCurrentSessionId()));
if (sessionDir.exists()) {
FileUtils.deleteQuietly(sessionDir);
// codeql[java/path-injection] justification: safeSessionSegment above strips to [a-zA-Z0-9._-];
// GHAS does not model in-repo sanitizer; re-review by 2027-07-31
if (sessionDir.exists()) { // codeql[java/path-injection]
FileUtils.deleteQuietly(sessionDir); // codeql[java/path-injection]
}
}

Expand Down
Loading