Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
Add v2.38.2
Browse files Browse the repository at this point in the history
  • Loading branch information
YannickRe committed Jun 4, 2020
1 parent 0b43db6 commit 2f92a2a
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 84 deletions.
34 changes: 22 additions & 12 deletions azuredeploy.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.2",
"parameters": {
"siteName": {
Expand All @@ -14,13 +14,11 @@
"sku": {
"type": "string",
"allowedValues": [
"Free",
"Shared",
"Basic",
"Standard",
"Premium"
],
"defaultValue": "Free"
"defaultValue": "Basic"
},
"Worker Size": {
"type": "string",
Expand Down Expand Up @@ -74,7 +72,7 @@
"name": "[parameters('hostingPlanName')]",
"type": "Microsoft.Web/serverfarms",
"location": "[parameters('siteLocation')]",
"apiVersion": "2016-09-01",
"apiVersion": "2018-02-01",
"sku": {
"name": "[variables('sku')]"
},
Expand All @@ -88,7 +86,7 @@
"name": "[parameters('siteName')]",
"type": "Microsoft.Web/sites",
"location": "[parameters('siteLocation')]",
"apiVersion": "2016-08-01",
"apiVersion": "2018-11-01",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]"
],
Expand All @@ -101,13 +99,25 @@
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]"
},
"resources": [
{
"apiVersion": "2018-11-01",
"name": "web",
"type": "config",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('siteName'))]"
],
"properties": {
"use32BitWorkerProcess": false,
"httpsOnly": true,
"alwaysOn": true
}
},
{
"name": "appsettings",
"type": "config",
"apiVersion": "2016-08-01",
"apiVersion": "2018-11-01",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('siteName'))]",
"[resourceId('Microsoft.Web/sites/sourcecontrols', parameters('siteName'), 'web')]",
"[resourceId('Microsoft.Insights/components', variables('appInsightsName'))]"
],
"properties": {
Expand All @@ -117,18 +127,18 @@
"mail__options__auth__user": "[parameters('Email Username')]",
"mail__options__auth__pass": "[parameters('Email Password')]",
"mail__from": "[parameters('Email From Address')]",
"WEBSITE_NODE_DEFAULT_VERSION": "10.15.2",
"npm_config_arch": "x64",
"WEBSITE_NODE_DEFAULT_VERSION": "~10",
"NODE_ENV": "production",
"APPINSIGHTS_INSTRUMENTATION_KEY": "[reference(concat('Microsoft.Insights/components/', variables('appInsightsName'))).InstrumentationKey]"
}
},
{
"name": "web",
"type": "sourcecontrols",
"apiVersion": "2016-08-01",
"apiVersion": "2018-11-01",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('siteName'))]"
"[resourceId('Microsoft.Web/sites', parameters('siteName'))]",
"[resourceId('Microsoft.Web/sites/config', parameters('siteName'), 'appsettings')]"
],
"properties": {
"repoUrl": "[parameters('repoUrl')]",
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions core/server/api/canary/oembed.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
const common = require('../../lib/common');
const {extract, hasProvider} = require('oembed-parser');
const Promise = require('bluebird');
const request = require('../../lib/request');
const externalRequest = require('../../lib/request-external');
const cheerio = require('cheerio');
const _ = require('lodash');
const {URL} = require('url');

async function fetchBookmarkData(url, html) {
const metascraper = require('metascraper')([
Expand All @@ -21,7 +22,7 @@ async function fetchBookmarkData(url, html) {

try {
if (!html) {
const response = await request(url, {
const response = await externalRequest(url, {
headers: {
'user-agent': 'Ghost(https://github.com/TryGhost/Ghost)'
}
Expand Down Expand Up @@ -124,7 +125,7 @@ function fetchOembedData(_url) {

// url not in oembed list so fetch it in case it's a redirect or has a
// <link rel="alternate" type="application/json+oembed"> element
return request(url, {
return externalRequest(url, {
method: 'GET',
timeout: 2 * 1000,
followRedirect: true,
Expand Down Expand Up @@ -155,7 +156,7 @@ function fetchOembedData(_url) {
}

// fetch oembed response from embedded rel="alternate" url
return request(oembedUrl, {
return externalRequest(oembedUrl, {
method: 'GET',
json: true,
timeout: 2 * 1000,
Expand Down
6 changes: 3 additions & 3 deletions core/server/api/v0.1/oembed.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const common = require('../../lib/common');
const {extract, hasProvider} = require('oembed-parser');
const Promise = require('bluebird');
const request = require('../../lib/request');
const externalRequest = require('../../lib/request-external');
const cheerio = require('cheerio');
const _ = require('lodash');
const {URL} = require('url');
Expand Down Expand Up @@ -84,7 +84,7 @@ function fetchOembedData(_url) {

// url not in oembed list so fetch it in case it's a redirect or has a
// <link rel="alternate" type="application/json+oembed"> element
return request(url, {
return externalRequest(url, {
method: 'GET',
timeout: 2 * 1000,
followRedirect: true,
Expand Down Expand Up @@ -115,7 +115,7 @@ function fetchOembedData(_url) {
}

// fetch oembed response from embedded rel="alternate" url
return request(oembedUrl, {
return externalRequest(oembedUrl, {
method: 'GET',
json: true,
timeout: 2 * 1000,
Expand Down
6 changes: 3 additions & 3 deletions core/server/api/v2/oembed.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const common = require('../../lib/common');
const {extract, hasProvider} = require('oembed-parser');
const Promise = require('bluebird');
const request = require('../../lib/request');
const externalRequest = require('../../lib/request-external');
const cheerio = require('cheerio');
const _ = require('lodash');
const {URL} = require('url');
Expand Down Expand Up @@ -79,7 +79,7 @@ function fetchOembedData(_url) {

// url not in oembed list so fetch it in case it's a redirect or has a
// <link rel="alternate" type="application/json+oembed"> element
return request(url, {
return externalRequest(url, {
method: 'GET',
timeout: 2 * 1000,
followRedirect: true,
Expand Down Expand Up @@ -110,7 +110,7 @@ function fetchOembedData(_url) {
}

// fetch oembed response from embedded rel="alternate" url
return request(oembedUrl, {
return externalRequest(oembedUrl, {
method: 'GET',
json: true,
timeout: 2 * 1000,
Expand Down
67 changes: 67 additions & 0 deletions core/server/lib/request-external.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const got = require('got');
const {URL} = require('url');
const dns = require('dns');
const common = require('./common');
const ghostVersion = require('./ghost-version');
const config = require('../config');
const validator = require('../data/validation').validator;

function isPrivateIp(addr) {
return /^(::f{4}:)?10\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
/^(::f{4}:)?192\.168\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
/^(::f{4}:)?172\.(1[6-9]|2\d|30|31)\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
/^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
/^(::f{4}:)?169\.254\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
/^f[cd][0-9a-f]{2}:/i.test(addr) ||
/^fe80:/i.test(addr) ||
/^::1$/.test(addr) ||
/^::$/.test(addr);
}

function errorIfHostnameResolvesToPrivateIp(options) {
// allow requests through to local Ghost instance
const siteUrl = new URL(config.get('url'));
const requestUrl = new URL(options.href);
if (requestUrl.host === siteUrl.host) {
return Promise.resolve();
}

dns.lookup(options.hostname, {}, (err, address) => {
if (err) {
throw err;
}

if (isPrivateIp(address)) {
throw new common.errors.InternalServerError({
message: 'URL resolves to a non-permitted private IP block',
code: 'URL_PRIVATE_INVALID',
context: options.href
});
}

return Promise.resolve();
});
}

// same as our normal request lib but if any request in a redirect chain resolves
// to a private IP address it will be blocked before the request is made.
const externalRequest = got.extend({
headers: {
'user-agent': 'Ghost/' + ghostVersion.original + ' (https://github.com/TryGhost/Ghost)'
},
hooks: {
init: [(options) => {
if (!options.hostname || !validator.isURL(options.hostname)) {
throw new common.errors.InternalServerError({
message: 'URL empty or invalid.',
code: 'URL_MISSING_INVALID',
context: options.href
});
}
}],
beforeRequest: [errorIfHostnameResolvesToPrivateIp],
beforeRedirect: [errorIfHostnameResolvesToPrivateIp]
}
});

module.exports = externalRequest;
2 changes: 1 addition & 1 deletion core/server/web/admin/views/default-prod.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
<div id="ember-basic-dropdown-wormhole"></div>


<script src="assets/vendor.min-995634bcc05458654bf7d7764b948dca.js"></script>
<script src="assets/vendor.min-9a614fcf6610a3db1a11c9b341a727e7.js"></script>
<script src="assets/ghost.min-b0a755237f752946124f52a7d192be0e.js"></script>

</body>
Expand Down
2 changes: 1 addition & 1 deletion core/server/web/admin/views/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
<div id="ember-basic-dropdown-wormhole"></div>


<script src="assets/vendor.min-995634bcc05458654bf7d7764b948dca.js"></script>
<script src="assets/vendor.min-9a614fcf6610a3db1a11c9b341a727e7.js"></script>
<script src="assets/ghost.min-b0a755237f752946124f52a7d192be0e.js"></script>

</body>
Expand Down
Loading

0 comments on commit 2f92a2a

Please sign in to comment.