Skip to content

Commit e333019

Browse files
gatsbybotLekoArts
andauthored
fix(gatsby-transformer-remark): Disallow JS frontmatter by default (#37244) (#37297)
(cherry picked from commit 77b8ccd) Co-authored-by: Lennart <[email protected]>
1 parent 3e7e996 commit e333019

File tree

3 files changed

+129
-56
lines changed

3 files changed

+129
-56
lines changed

packages/gatsby-transformer-remark/README.md

+85-56
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,46 @@ Parses Markdown files using [remark](http://remark.js.org/).
44

55
## Install
66

7-
`npm install gatsby-transformer-remark`
8-
9-
## How to use
10-
11-
```javascript
12-
// In your gatsby-config.js
13-
plugins: [
14-
{
15-
resolve: `gatsby-transformer-remark`,
16-
options: {
17-
// Footnotes mode (default: true)
18-
footnotes: true,
19-
// GitHub Flavored Markdown mode (default: true)
20-
gfm: true,
21-
// Plugins configs
22-
plugins: [],
7+
Install the plugin to your site:
8+
9+
```shell
10+
npm install gatsby-transformer-remark
11+
```
12+
13+
Add it to your `gatsby-config`:
14+
15+
```js:title=gatsby-config.js
16+
module.exports = {
17+
plugins: [
18+
{
19+
resolve: `gatsby-transformer-remark`,
20+
options: {},
2321
},
24-
},
25-
],
22+
],
23+
}
24+
```
25+
26+
## Options
27+
28+
```js:title=gatsby-config.js
29+
module.exports = {
30+
plugins: [
31+
{
32+
resolve: `gatsby-transformer-remark`,
33+
options: {
34+
// Footnotes mode (default: true)
35+
footnotes: true,
36+
// GitHub Flavored Markdown mode (default: true)
37+
gfm: true,
38+
// Add your gatsby-remark-* plugins here
39+
plugins: [],
40+
// Enable JS for https://github.com/jonschlinkert/gray-matter#optionsengines (default: false)
41+
// It's not advised to set this to "true" and this option will likely be removed in the future
42+
jsFrontmatterEngine: false,
43+
},
44+
},
45+
],
46+
}
2647
```
2748

2849
The following parts of `options` enable the `remark-footnotes` and `remark-gfm`
@@ -31,10 +52,30 @@ plugins:
3152
- `options.footnotes`
3253
- `options.gfm`
3354

34-
A full explanation of how to use markdown in Gatsby can be found here:
35-
[Adding Markdown Pages](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/)
55+
A full explanation of how to use markdown in Gatsby can be found here: [Adding Markdown Pages](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/)
56+
57+
There are many `gatsby-remark-*` plugins which you can install to customize how Markdown is processed. Check out the [source code for using-remark](https://github.com/gatsbyjs/gatsby/tree/master/examples/using-remark) as an example.
58+
59+
### `gray-matter` options
60+
61+
`gatsby-transformer-remark` uses [gray-matter](https://github.com/jonschlinkert/gray-matter) to parse Markdown frontmatter, so you can specify any of the options mentioned [in its README](https://github.com/jonschlinkert/gray-matter#options) in the `options` key of the plugin.
3662

37-
There are many Gatsby Remark plugins which you can install to customize how Markdown is processed. Many of them are demoed at https://using-remark.gatsbyjs.org/. See also the [source code for using-remark](https://github.com/gatsbyjs/gatsby/tree/master/examples/using-remark).
63+
**Example: Excerpts**
64+
65+
If you don't want to use `pruneLength` for excerpts but a custom separator, you can specify an `excerpt_separator`:
66+
67+
```js:title=gatsby-config.js
68+
module.exports = {
69+
plugins: [
70+
{
71+
resolve: `gatsby-transformer-remark`,
72+
options: {
73+
excerpt_separator: `<!-- end -->`
74+
}
75+
},
76+
],
77+
}
78+
```
3879

3980
## Parsing algorithm
4081

@@ -120,19 +161,20 @@ By default, `absolute` is set to `false`, generating a relative path. If you'd l
120161

121162
To pass default options to the plugin generating the `tableOfContents`, configure it in `gatsby-config.js` as shown below. The options shown below are the defaults used by the plugin.
122163

123-
```javascript
124-
// In your gatsby-config.js
125-
plugins: [
126-
{
127-
resolve: `gatsby-transformer-remark`,
128-
options: {
129-
tableOfContents: {
130-
heading: null,
131-
maxDepth: 6,
164+
```js:title=gatsby-config.js
165+
module.exports = {
166+
plugins: [
167+
{
168+
resolve: `gatsby-transformer-remark`,
169+
options: {
170+
tableOfContents: {
171+
heading: null,
172+
maxDepth: 6,
173+
},
132174
},
133175
},
134-
},
135-
]
176+
],
177+
}
136178
```
137179

138180
### Excerpts
@@ -198,23 +240,6 @@ You can also get excerpts in Markdown format.
198240
}
199241
```
200242

201-
## `gray-matter` options
202-
203-
`gatsby-transformer-remark` uses [gray-matter](https://github.com/jonschlinkert/gray-matter) to parse Markdown frontmatter, so you can specify any of the options mentioned [here](https://github.com/jonschlinkert/gray-matter#options) in the `gatsby-config.js` file.
204-
205-
### Example: Excerpts
206-
207-
If you don't want to use `pruneLength` for excerpts but a custom separator, you can specify an `excerpt_separator` in the `gatsby-config.js` file:
208-
209-
```javascript
210-
{
211-
"resolve": `gatsby-transformer-remark`,
212-
"options": {
213-
"excerpt_separator": `<!-- end -->`
214-
}
215-
}
216-
```
217-
218243
Any file that does not have the given `excerpt_separator` will fall back to the default pruning method.
219244

220245
## Troubleshooting
@@ -237,14 +262,18 @@ If that is the case, you can set `truncate` option on `excerpt` field, like:
237262

238263
If your Markdown file contains HTML, `excerpt` will not return a value.
239264

240-
In that case, you can set an `excerpt_separator` in the `gatsby-config.js` file:
265+
In that case, you can set an `excerpt_separator` in the `gatsby-config`:
241266

242-
```javascript
243-
{
244-
"resolve": `gatsby-transformer-remark`,
245-
"options": {
246-
"excerpt_separator": `<!-- endexcerpt -->`
247-
}
267+
```js:title=gatsby-config.js
268+
module.exports = {
269+
plugins: [
270+
{
271+
resolve: `gatsby-transformer-remark`,
272+
options: {
273+
excerpt_separator: `<!-- endexcerpt -->`
274+
},
275+
},
276+
],
248277
}
249278
```
250279

packages/gatsby-transformer-remark/src/__tests__/gatsby-node.js

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ describe(`gatsby-node.js`, () => {
77
`"footnotes" must be a boolean`,
88
`"gfm" must be a boolean`,
99
`"plugins" must be an array`,
10+
`"jsFrontmatterEngine" must be a boolean`,
1011
]
1112

1213
const { errors, isValid } = await testPluginOptionsSchema(
@@ -15,6 +16,7 @@ describe(`gatsby-node.js`, () => {
1516
footnotes: `this should be a boolean`,
1617
gfm: `this should be a boolean`,
1718
plugins: `this should be an array`,
19+
jsFrontmatterEngine: `this should be a boolean`,
1820
}
1921
)
2022

@@ -37,6 +39,7 @@ describe(`gatsby-node.js`, () => {
3739
},
3840
},
3941
],
42+
jsFrontmatterEngine: true,
4043
}
4144
)
4245

packages/gatsby-transformer-remark/src/gatsby-node.js

+41
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ exports.shouldOnCreateNode = shouldOnCreateNode
44
exports.createSchemaCustomization = require(`./create-schema-customization`)
55
exports.setFieldsOnGraphQLNodeType = require(`./extend-node-type`)
66

7+
// Dedupe warning
8+
let warnedAboutJSFrontmatterEngine = false
9+
710
exports.pluginOptionsSchema = function ({ Joi }) {
811
return Joi.object({
912
footnotes: Joi.boolean().description(
@@ -18,5 +21,43 @@ exports.pluginOptionsSchema = function ({ Joi }) {
1821
plugins: Joi.subPlugins().description(
1922
`A list of remark plugins. See also: https://github.com/gatsbyjs/gatsby/tree/master/examples/using-remark for examples`
2023
),
24+
// TODO(v6): Remove and disallow any custom engines (including JS)
25+
jsFrontmatterEngine: Joi.boolean()
26+
.default(false)
27+
.description(
28+
`Enable JS for https://github.com/jonschlinkert/gray-matter#optionsengines`
29+
),
30+
}).custom(value => {
31+
const { jsFrontmatterEngine, engines = {} } = value || {}
32+
33+
if (jsFrontmatterEngine) {
34+
// show this warning only once in main process
35+
if (!process.env.GATSBY_WORKER_ID) {
36+
console.warn(
37+
`JS frontmatter engine is enabled in gatsby-transformer-remark (via jsFrontmatterEngine: true). This can cause a security risk, see https://github.com/gatsbyjs/gatsby/security/advisories/GHSA-7ch4-rr99-cqcw. If you are not relying on this feature we strongly suggest disabling it via the "jsFrontmatterEngine: false" plugin option. If you rely on this feature make sure to properly secure or sanitize your content source.`
38+
)
39+
}
40+
return value
41+
}
42+
43+
const js = () => {
44+
if (!warnedAboutJSFrontmatterEngine) {
45+
console.warn(
46+
`You have frontmatter declared with "---js" or "---javascript" that is not parsed by default to mitigate a security risk (see https://github.com/gatsbyjs/gatsby/security/advisories/GHSA-7ch4-rr99-cqcw). If you require this feature it can be enabled by setting "jsFrontmatterEngine: true" in the plugin options of gatsby-transformer-remark.`
47+
)
48+
warnedAboutJSFrontmatterEngine = true
49+
}
50+
// we still have to return a frontmatter, so we just stub it with empty object
51+
return {}
52+
}
53+
54+
return {
55+
...value,
56+
engines: {
57+
...engines,
58+
js,
59+
javascript: js,
60+
},
61+
}
2162
})
2263
}

0 commit comments

Comments
 (0)