chore(security): fixes
This commit is contained in:
28
.github/codeql-config.yml
vendored
Normal file
28
.github/codeql-config.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
name: BentoPDF CodeQL config
|
||||||
|
|
||||||
|
paths-ignore:
|
||||||
|
- dist
|
||||||
|
- dist-test
|
||||||
|
- coverage
|
||||||
|
- node_modules
|
||||||
|
- vendor
|
||||||
|
- bentopdf-pymupdf-wasm
|
||||||
|
- libreoffice-wasm-package
|
||||||
|
- bentopdf-airgap-bundle
|
||||||
|
- public/pdfjs-viewer
|
||||||
|
- public/pdfjs-annotation-viewer
|
||||||
|
- public/libreoffice-wasm
|
||||||
|
- public/coherentpdf.browser.min.js
|
||||||
|
- public/workers
|
||||||
|
- public/embedpdf
|
||||||
|
- docs/.vitepress
|
||||||
|
- '**/*.min.js'
|
||||||
|
- '**/*.d.ts'
|
||||||
|
|
||||||
|
query-filters:
|
||||||
|
- exclude:
|
||||||
|
id: js/log-injection
|
||||||
|
- exclude:
|
||||||
|
id: js/tainted-format-string
|
||||||
|
- exclude:
|
||||||
|
id: js/file-system-race
|
||||||
22
.github/workflows/codeql.yml
vendored
22
.github/workflows/codeql.yml
vendored
@@ -32,26 +32,8 @@ jobs:
|
|||||||
uses: github/codeql-action/init@v3
|
uses: github/codeql-action/init@v3
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
queries: security-extended,security-and-quality
|
queries: security-extended
|
||||||
config: |
|
config-file: ./.github/codeql-config.yml
|
||||||
paths-ignore:
|
|
||||||
- dist
|
|
||||||
- dist-test
|
|
||||||
- coverage
|
|
||||||
- node_modules
|
|
||||||
- vendor
|
|
||||||
- bentopdf-pymupdf-wasm
|
|
||||||
- libreoffice-wasm-package
|
|
||||||
- bentopdf-airgap-bundle
|
|
||||||
- public/pdfjs-viewer
|
|
||||||
- public/pdfjs-annotation-viewer
|
|
||||||
- public/libreoffice-wasm
|
|
||||||
- public/coherentpdf.browser.min.js
|
|
||||||
- public/workers
|
|
||||||
- public/embedpdf
|
|
||||||
- docs/.vitepress
|
|
||||||
- '**/*.min.js'
|
|
||||||
- '**/*.d.ts'
|
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v3
|
uses: github/codeql-action/analyze@v3
|
||||||
|
|||||||
@@ -145,7 +145,9 @@ function processFileForLanguage(
|
|||||||
href.startsWith('#') ||
|
href.startsWith('#') ||
|
||||||
href.startsWith('mailto:') ||
|
href.startsWith('mailto:') ||
|
||||||
href.startsWith('tel:') ||
|
href.startsWith('tel:') ||
|
||||||
href.startsWith('javascript:')
|
href.startsWith('javascript:') ||
|
||||||
|
href.startsWith('data:') ||
|
||||||
|
href.startsWith('vbscript:')
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -235,7 +235,9 @@ export const rewriteLinks = (): void => {
|
|||||||
href.startsWith('mailto:') ||
|
href.startsWith('mailto:') ||
|
||||||
href.startsWith('tel:') ||
|
href.startsWith('tel:') ||
|
||||||
href.startsWith('#') ||
|
href.startsWith('#') ||
|
||||||
href.startsWith('javascript:')
|
href.startsWith('javascript:') ||
|
||||||
|
href.startsWith('data:') ||
|
||||||
|
href.startsWith('vbscript:')
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -754,7 +754,8 @@ function renderField(field: FormField): void {
|
|||||||
contentEl.appendChild(img);
|
contentEl.appendChild(img);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(
|
console.warn(
|
||||||
`Failed to render barcode preview for field "${field.name}":`,
|
'Failed to render barcode preview for field:',
|
||||||
|
String(field.name).replace(/[\r\n]+/g, ' '),
|
||||||
error
|
error
|
||||||
);
|
);
|
||||||
contentEl.innerHTML = `<div class="flex flex-col items-center text-center p-1 text-gray-400"><i data-lucide="qr-code" class="w-6 h-6 mb-1"></i><span class="text-[10px] leading-tight">Invalid data</span></div>`;
|
contentEl.innerHTML = `<div class="flex flex-col items-center text-center p-1 text-gray-400"><i data-lucide="qr-code" class="w-6 h-6 mb-1"></i><span class="text-[10px] leading-tight">Invalid data</span></div>`;
|
||||||
@@ -2320,11 +2321,17 @@ downloadBtn.addEventListener('click', async () => {
|
|||||||
if (existingField) {
|
if (existingField) {
|
||||||
radioGroup = existingField as PDFRadioGroup;
|
radioGroup = existingField as PDFRadioGroup;
|
||||||
radioGroups.set(groupName, radioGroup);
|
radioGroups.set(groupName, radioGroup);
|
||||||
console.log(`Using existing radio group from PDF: ${groupName}`);
|
console.log(
|
||||||
|
'Using existing radio group from PDF:',
|
||||||
|
String(groupName).replace(/[\r\n]+/g, ' ')
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
radioGroup = form.createRadioGroup(groupName);
|
radioGroup = form.createRadioGroup(groupName);
|
||||||
radioGroups.set(groupName, radioGroup);
|
radioGroups.set(groupName, radioGroup);
|
||||||
console.log(`Created new radio group: ${groupName}`);
|
console.log(
|
||||||
|
'Created new radio group:',
|
||||||
|
String(groupName).replace(/[\r\n]+/g, ' ')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2690,7 +2697,8 @@ downloadBtn.addEventListener('click', async () => {
|
|||||||
pdfPage.drawImage(pngImage, { x, y, width, height });
|
pdfPage.drawImage(pngImage, { x, y, width, height });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn(
|
console.warn(
|
||||||
`Failed to generate barcode for field "${field.name}":`,
|
'Failed to generate barcode for field:',
|
||||||
|
String(field.name).replace(/[\r\n]+/g, ' '),
|
||||||
e
|
e
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -554,7 +554,10 @@ async function addNodeToCanvas(
|
|||||||
try {
|
try {
|
||||||
const node = createNodeByType(type);
|
const node = createNodeByType(type);
|
||||||
if (!node) {
|
if (!node) {
|
||||||
console.error('Node type not found in registry:', type);
|
console.error(
|
||||||
|
'Node type not found in registry:',
|
||||||
|
String(type).replace(/[\r\n]+/g, ' ')
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await editor.addNode(node);
|
await editor.addNode(node);
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export class EncryptNode extends BaseWorkflowNode {
|
|||||||
return {
|
return {
|
||||||
pdf: await processBatch(pdfInputs, async (input) => {
|
pdf: await processBatch(pdfInputs, async (input) => {
|
||||||
const qpdf = await initializeQpdf();
|
const qpdf = await initializeQpdf();
|
||||||
const uid = `${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
const uid = `${Date.now()}_${crypto.randomUUID().slice(0, 7)}`;
|
||||||
const inputPath = `/tmp/input_encrypt_${uid}.pdf`;
|
const inputPath = `/tmp/input_encrypt_${uid}.pdf`;
|
||||||
const outputPath = `/tmp/output_encrypt_${uid}.pdf`;
|
const outputPath = `/tmp/output_encrypt_${uid}.pdf`;
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export class LinearizeNode extends BaseWorkflowNode {
|
|||||||
return {
|
return {
|
||||||
pdf: await processBatch(pdfInputs, async (input) => {
|
pdf: await processBatch(pdfInputs, async (input) => {
|
||||||
const qpdf = await initializeQpdf();
|
const qpdf = await initializeQpdf();
|
||||||
const uid = `${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
const uid = `${Date.now()}_${crypto.randomUUID().slice(0, 7)}`;
|
||||||
const inputPath = `/tmp/input_linearize_${uid}.pdf`;
|
const inputPath = `/tmp/input_linearize_${uid}.pdf`;
|
||||||
const outputPath = `/tmp/output_linearize_${uid}.pdf`;
|
const outputPath = `/tmp/output_linearize_${uid}.pdf`;
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export class OverlayNode extends BaseWorkflowNode {
|
|||||||
const mode = modeControl?.value === 'underlay' ? '--underlay' : '--overlay';
|
const mode = modeControl?.value === 'underlay' ? '--underlay' : '--overlay';
|
||||||
|
|
||||||
const qpdf = await initializeQpdf();
|
const qpdf = await initializeQpdf();
|
||||||
const uid = `${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
const uid = `${Date.now()}_${crypto.randomUUID().slice(0, 7)}`;
|
||||||
const inputPath = `/tmp/input_overlay_${uid}.pdf`;
|
const inputPath = `/tmp/input_overlay_${uid}.pdf`;
|
||||||
const overlayPath = `/tmp/overlay_${uid}.pdf`;
|
const overlayPath = `/tmp/overlay_${uid}.pdf`;
|
||||||
const outputPath = `/tmp/output_overlay_${uid}.pdf`;
|
const outputPath = `/tmp/output_overlay_${uid}.pdf`;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export class RepairNode extends BaseWorkflowNode {
|
|||||||
return {
|
return {
|
||||||
pdf: await processBatch(pdfInputs, async (input) => {
|
pdf: await processBatch(pdfInputs, async (input) => {
|
||||||
const qpdf = await initializeQpdf();
|
const qpdf = await initializeQpdf();
|
||||||
const uid = `${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
const uid = `${Date.now()}_${crypto.randomUUID().slice(0, 7)}`;
|
||||||
const inputPath = `/tmp/input_repair_${uid}.pdf`;
|
const inputPath = `/tmp/input_repair_${uid}.pdf`;
|
||||||
const outputPath = `/tmp/output_repair_${uid}.pdf`;
|
const outputPath = `/tmp/output_repair_${uid}.pdf`;
|
||||||
|
|
||||||
|
|||||||
@@ -328,9 +328,10 @@ function createCorsProxyMiddleware(): Connect.NextHandleFunction {
|
|||||||
);
|
);
|
||||||
|
|
||||||
proxyReq.on('error', (err) => {
|
proxyReq.on('error', (err) => {
|
||||||
console.error('[CORS Proxy] Error:', err.message);
|
const msg = String(err.message).replace(/[\r\n]+/g, ' ');
|
||||||
|
console.error('[CORS Proxy] Error:', msg);
|
||||||
res.statusCode = 502;
|
res.statusCode = 502;
|
||||||
res.end(`Proxy error: ${err.message}`);
|
res.end(`Proxy error: ${msg}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (body.length > 0) {
|
if (body.length > 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user