Remove default call to lockdown (#22)
* restore test * suppression de l'appel à lockdown par défaut * improving readme * ses@1.14 * add section on securing fillOdtTemplate
This commit is contained in:
parent
98817e9d34
commit
a31f57026d
56
package-lock.json
generated
56
package-lock.json
generated
@ -11,7 +11,7 @@
|
|||||||
"@xmldom/xmldom": "^0.9.8",
|
"@xmldom/xmldom": "^0.9.8",
|
||||||
"@zip.js/zip.js": "^2.7.57",
|
"@zip.js/zip.js": "^2.7.57",
|
||||||
"image-size": "^2.0.2",
|
"image-size": "^2.0.2",
|
||||||
"ses": "^1.12.0"
|
"ses": "^1.14.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-commonjs": "^25.0.7",
|
"@rollup/plugin-commonjs": "^25.0.7",
|
||||||
@ -42,10 +42,22 @@
|
|||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@endo/cache-map": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@endo/cache-map/-/cache-map-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-owFGshs/97PDw9oguZqU/px8Lv1d0KjAUtDUiPwKHNXRVUE/jyettEbRoTbNJR1OaI8biMn6bHr9kVJsOh6dXw==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/@endo/env-options": {
|
"node_modules/@endo/env-options": {
|
||||||
"version": "1.1.8",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/@endo/env-options/-/env-options-1.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/@endo/env-options/-/env-options-1.1.11.tgz",
|
||||||
"integrity": "sha512-Xtxw9n33I4guo8q0sDyZiRuxlfaopM454AKiELgU7l3tqsylCut6IBZ0fPy4ltSHsBib7M3yF7OEMoIuLwzWVg==",
|
"integrity": "sha512-p9OnAPsdqoX4YJsE98e3NBVhIr2iW9gNZxHhAI2/Ul5TdRfoOViItzHzTqrgUVopw6XxA1u1uS6CykLMDUxarA==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
|
"node_modules/@endo/immutable-arraybuffer": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@endo/immutable-arraybuffer/-/immutable-arraybuffer-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-u+NaYB2aqEugQ3u7w3c5QNkPogf8q/xGgsPaqdY6pUiGWtYiTiFspKFcha6+oeZhWXWQ23rf0KrUq0kfuzqYyQ==",
|
||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/gen-mapping": {
|
"node_modules/@jridgewell/gen-mapping": {
|
||||||
@ -3628,12 +3640,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ses": {
|
"node_modules/ses": {
|
||||||
"version": "1.12.0",
|
"version": "1.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/ses/-/ses-1.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/ses/-/ses-1.14.0.tgz",
|
||||||
"integrity": "sha512-jvmwXE2lFxIIY1j76hFjewIIhYMR9Slo3ynWZGtGl5M7VUCw3EA0wetS+JCIbl2UcSQjAT0yGAHkyxPJreuC9w==",
|
"integrity": "sha512-T07hNgOfVRTLZGwSS50RnhqrG3foWP+rM+Q5Du4KUQyMLFI3A8YA4RKl0jjZzhihC1ZvDGrWi/JMn4vqbgr/Jg==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@endo/env-options": "^1.1.8"
|
"@endo/cache-map": "^1.1.0",
|
||||||
|
"@endo/env-options": "^1.1.11",
|
||||||
|
"@endo/immutable-arraybuffer": "^1.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/set-blocking": {
|
"node_modules/set-blocking": {
|
||||||
@ -4584,10 +4598,20 @@
|
|||||||
"@jridgewell/trace-mapping": "^0.3.9"
|
"@jridgewell/trace-mapping": "^0.3.9"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@endo/cache-map": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@endo/cache-map/-/cache-map-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-owFGshs/97PDw9oguZqU/px8Lv1d0KjAUtDUiPwKHNXRVUE/jyettEbRoTbNJR1OaI8biMn6bHr9kVJsOh6dXw=="
|
||||||
|
},
|
||||||
"@endo/env-options": {
|
"@endo/env-options": {
|
||||||
"version": "1.1.8",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/@endo/env-options/-/env-options-1.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/@endo/env-options/-/env-options-1.1.11.tgz",
|
||||||
"integrity": "sha512-Xtxw9n33I4guo8q0sDyZiRuxlfaopM454AKiELgU7l3tqsylCut6IBZ0fPy4ltSHsBib7M3yF7OEMoIuLwzWVg=="
|
"integrity": "sha512-p9OnAPsdqoX4YJsE98e3NBVhIr2iW9gNZxHhAI2/Ul5TdRfoOViItzHzTqrgUVopw6XxA1u1uS6CykLMDUxarA=="
|
||||||
|
},
|
||||||
|
"@endo/immutable-arraybuffer": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@endo/immutable-arraybuffer/-/immutable-arraybuffer-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-u+NaYB2aqEugQ3u7w3c5QNkPogf8q/xGgsPaqdY6pUiGWtYiTiFspKFcha6+oeZhWXWQ23rf0KrUq0kfuzqYyQ=="
|
||||||
},
|
},
|
||||||
"@jridgewell/gen-mapping": {
|
"@jridgewell/gen-mapping": {
|
||||||
"version": "0.3.2",
|
"version": "0.3.2",
|
||||||
@ -7156,11 +7180,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ses": {
|
"ses": {
|
||||||
"version": "1.12.0",
|
"version": "1.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/ses/-/ses-1.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/ses/-/ses-1.14.0.tgz",
|
||||||
"integrity": "sha512-jvmwXE2lFxIIY1j76hFjewIIhYMR9Slo3ynWZGtGl5M7VUCw3EA0wetS+JCIbl2UcSQjAT0yGAHkyxPJreuC9w==",
|
"integrity": "sha512-T07hNgOfVRTLZGwSS50RnhqrG3foWP+rM+Q5Du4KUQyMLFI3A8YA4RKl0jjZzhihC1ZvDGrWi/JMn4vqbgr/Jg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@endo/env-options": "^1.1.8"
|
"@endo/cache-map": "^1.1.0",
|
||||||
|
"@endo/env-options": "^1.1.11",
|
||||||
|
"@endo/immutable-arraybuffer": "^1.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"set-blocking": {
|
"set-blocking": {
|
||||||
|
|||||||
@ -42,6 +42,6 @@
|
|||||||
"@xmldom/xmldom": "^0.9.8",
|
"@xmldom/xmldom": "^0.9.8",
|
||||||
"@zip.js/zip.js": "^2.7.57",
|
"@zip.js/zip.js": "^2.7.57",
|
||||||
"image-size": "^2.0.2",
|
"image-size": "^2.0.2",
|
||||||
"ses": "^1.12.0"
|
"ses": "^1.14.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
readme.md
16
readme.md
@ -99,8 +99,7 @@ And then run the code:
|
|||||||
```js
|
```js
|
||||||
import {join} from 'node:path';
|
import {join} from 'node:path';
|
||||||
|
|
||||||
import {getOdtTemplate} from '../scripts/odf/odtTemplate-forNode.js'
|
import {getOdtTemplate, fillOdtTemplate} from '@odfjs/odfjs'
|
||||||
import {fillOdtTemplate} from '../scripts/node.js'
|
|
||||||
|
|
||||||
// replace with your template path
|
// replace with your template path
|
||||||
const templatePath = join(import.meta.dirname, './tests/data/template-anniversaire.odt')
|
const templatePath = join(import.meta.dirname, './tests/data/template-anniversaire.odt')
|
||||||
@ -126,6 +125,19 @@ There are also loops in the form:
|
|||||||
They can be used to generate lists or tables in .odt files from data and a template using this syntax
|
They can be used to generate lists or tables in .odt files from data and a template using this syntax
|
||||||
|
|
||||||
|
|
||||||
|
#### Securing calls to fillOdtTemplate
|
||||||
|
|
||||||
|
`fillOdtTemplate` evaluate arbitrary JavaScript code in `{#each <collection> as élément}` and `{#if <condition>}` and in `{<expression>}`
|
||||||
|
|
||||||
|
By default, `fillOdtTemplate` limits access to global functions to only ECMAScript defaults via the use of [ses' Compartment](https://www.npmjs.com/package/ses#compartment), this prevents naïve data exfiltration
|
||||||
|
|
||||||
|
However, `fillOdtTemplate` is vulnerable to [prototype pollution](https://cheatsheetseries.owasp.org/cheatsheets/Prototype_Pollution_Prevention_Cheat_Sheet.html) inside template code. Two main ways to be secure are:
|
||||||
|
- control the set of possible templates
|
||||||
|
- call ses' `lockdown` which freezes Javascript intrinsics before calling `fillOdtTemplate` (this may lead to incompatibilities)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Demo
|
### Demo
|
||||||
|
|
||||||
https://odfjs.github.io/odfjs/
|
https://odfjs.github.io/odfjs/
|
||||||
|
|||||||
@ -7,8 +7,6 @@ import prepareTemplateDOMTree from './prepareTemplateDOMTree.js';
|
|||||||
import 'ses'
|
import 'ses'
|
||||||
import fillOdtElementTemplate from './fillOdtElementTemplate.js';
|
import fillOdtElementTemplate from './fillOdtElementTemplate.js';
|
||||||
|
|
||||||
lockdown();
|
|
||||||
|
|
||||||
|
|
||||||
/** @import {Reader, ZipWriterAddDataOptions} from '@zip.js/zip.js' */
|
/** @import {Reader, ZipWriterAddDataOptions} from '@zip.js/zip.js' */
|
||||||
/** @import {ODFManifest, ODFManifestFileEntry} from '../manifest.js' */
|
/** @import {ODFManifest, ODFManifestFileEntry} from '../manifest.js' */
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import { listZipEntries } from '../helpers/zip-analysis.js';
|
|||||||
import { getContentDocument } from '../../scripts/odf/odt/getOdtTextContent.js';
|
import { getContentDocument } from '../../scripts/odf/odt/getOdtTextContent.js';
|
||||||
|
|
||||||
|
|
||||||
test.skip('template filling preserves images', async t => {
|
test('template filling preserves images', async t => {
|
||||||
const templatePath = join(import.meta.dirname, '../fixtures/template-avec-image.odt')
|
const templatePath = join(import.meta.dirname, '../fixtures/template-avec-image.odt')
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user