Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sanitize taxonomies & terms data against csv injection #1076

Merged
Merged
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
76 changes: 38 additions & 38 deletions packages/contentstack-export-to-csv/src/util/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,20 +376,20 @@ function exitProgram() {
process.exit();
}

function sanitizeEntries(flatEntry) {
function sanitizeData(flatData) {
// sanitize against CSV Injections
const CSVRegex = /^[\\+\\=@\\-]/
for (key in flatEntry) {
if (typeof flatEntry[key] === 'string' && flatEntry[key].match(CSVRegex)) {
flatEntry[key] = flatEntry[key].replace(/\"/g, "\"\"");
flatEntry[key] = `"'${flatEntry[key]}"`
} else if (typeof flatEntry[key] === 'object') {
const CSVRegex = /^[\\+\\=@\\-]/;
for (key in flatData) {
if (typeof flatData[key] === 'string' && flatData[key].match(CSVRegex)) {
flatData[key] = flatData[key].replace(/\"/g, '""');
flatData[key] = `"'${flatData[key]}"`;
} else if (typeof flatData[key] === 'object') {
// convert any objects or arrays to string
// to store this data correctly in csv
flatEntry[key] = JSON.stringify(flatEntry[key]);
flatData[key] = JSON.stringify(flatData[key]);
}
}
return flatEntry;
return flatData;
}

function cleanEntries(entries, language, environments, contentTypeUid) {
Expand All @@ -414,7 +414,7 @@ function cleanEntries(entries, language, environments, contentTypeUid) {
}
}
entry = flatten(entry);
entry = sanitizeEntries(entry);
entry = sanitizeData(entry);
entry['publish_details'] = envArr;
entry['_workflow'] = workflow;
entry['ACL'] = JSON.stringify({}); // setting ACL to empty obj
Expand Down Expand Up @@ -685,15 +685,15 @@ function wait(time) {

/**
* fetch all taxonomies in the provided stack
* @param {object} payload
* @param {number} skip
* @param {number} limit
* @param {array} taxonomies
* @returns
* @param {object} payload
* @param {number} skip
* @param {number} limit
* @param {array} taxonomies
* @returns
*/
async function getAllTaxonomies(payload, skip = 0, limit = 100, taxonomies = []) {
const response = await apiRequestHandler(payload, skip, limit);
if(response){
if (response) {
skip += config.limit || 100;
taxonomies = [...taxonomies, ...response.taxonomies];
if (skip >= response?.count) {
Expand All @@ -707,15 +707,15 @@ async function getAllTaxonomies(payload, skip = 0, limit = 100, taxonomies = [])

/**
* fetch terms of related taxonomy
* @param {object} payload
* @param {number} skip
* @param {number} limit
* @param {array} terms
* @returns
* @param {object} payload
* @param {number} skip
* @param {number} limit
* @param {array} terms
* @returns
*/
async function getAllTermsOfTaxonomy(payload, skip = 0, limit = 100, terms = []) {
const response = await apiRequestHandler(payload, skip, limit);
if(response){
if (response) {
skip += config.limit || 100;
terms = [...terms, ...response.terms];
if (skip >= response?.count) {
Expand All @@ -729,9 +729,9 @@ async function getAllTermsOfTaxonomy(payload, skip = 0, limit = 100, terms = [])

/**
* Verify the existence of a taxonomy. Obtain its details if it exists and return
* @param {object} payload
* @param {string} taxonomyUID
* @returns
* @param {object} payload
* @param {string} taxonomyUID
* @returns
*/
async function getTaxonomy(payload, taxonomyUID) {
payload['url'] = `${payload.baseUrl}/${taxonomyUID}`;
Expand Down Expand Up @@ -769,7 +769,7 @@ async function apiRequestHandler(payload, skip, limit) {
let errorMsg;
if ([500, 503, 502].includes(status)) errorMsg = data?.message || data;
else errorMsg = data?.error_message;
if(errorMsg === undefined){
if (errorMsg === undefined) {
errorMsg = Object.values(data?.errors) && flat(Object.values(data.errors));
}
cliux.print(`Error: ${errorMsg}`, { color: 'red' });
Expand All @@ -781,37 +781,37 @@ async function apiRequestHandler(payload, skip, limit) {

/**
* Change taxonomies data in required CSV headers format
* @param {array} taxonomies
* @returns
* @param {array} taxonomies
* @returns
*/
function formatTaxonomiesData(taxonomies) {
if(taxonomies?.length){
if (taxonomies?.length) {
const formattedTaxonomies = taxonomies.map((taxonomy) => {
return {
return sanitizeData({
'Taxonomy UID': taxonomy.uid,
Name: taxonomy.name,
Description: taxonomy.description,
};
});
});
return formattedTaxonomies;
}
}

/**
* Modify the linked taxonomy data's terms in required CSV headers format
* @param {array} terms
* @param {string} taxonomyUID
* @returns
* @param {array} terms
* @param {string} taxonomyUID
* @returns
*/
function formatTermsOfTaxonomyData(terms, taxonomyUID) {
if(terms?.length){
if (terms?.length) {
const formattedTerms = terms.map((term) => {
return {
return sanitizeData({
'Taxonomy UID': taxonomyUID,
UID: term.uid,
Name: term.name,
'Parent UID': term.parent_uid,
};
});
});
return formattedTerms;
}
Expand Down Expand Up @@ -860,5 +860,5 @@ module.exports = {
formatTaxonomiesData,
formatTermsOfTaxonomyData,
getTaxonomy,
getStacks
getStacks,
};