Skip to content
Open
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
80 changes: 65 additions & 15 deletions server/routes/api/checkout.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,29 @@
}
}

/**
* Sanitiza uma string removendo tags HTML e caracteres perigosos.
* @param {string} str - A string a ser sanitizada.
* @returns {string} - A string sanitizada.
*/
function sanitizeString(str) {
if (typeof str !== 'string') return str; // Retorna o valor original se não for uma string

// Remove tags HTML
str = str.replace(/<[^>]*>?/gm, '');

Check failure

Code scanning / CodeQL

Incomplete multi-character sanitization High

This string may still contain
<script
, which may cause an HTML element injection vulnerability.

// Remove caracteres especiais perigosos
str = str.replace(/[&<>"'`=\/]/g, '');

Check failure on line 36 in server/routes/api/checkout.js

View workflow job for this annotation

GitHub Actions / lint

Unnecessary escape character: \/

return str.trim(); // Remove espaços extras no início e no final
}

// Exemplo de uso
const userInput = '<script>alert("XSS Attack!")</script>';
const sanitizedInput = sanitizeString(userInput);

console.log(sanitizedInput); // Saída: alert("XSS Attack!")

router.post('/create-checkout-session', async (req, res) => {
let { donation, user, letter, deliveryMethods } = req.body
console.dir(user)
Expand All @@ -38,7 +61,7 @@
const redirectUrl = `${origin}/complete?session_id=${CHECKOUT_SESSION_ID}`

let constituent
;[constituent] = await Constituent.query().where('email', user.email)
;[constituent] = await Constituent.query().where('email', user.email).limit(1)
if (!constituent) {
constituent = await Constituent.query().insert(user)
}
Expand All @@ -54,16 +77,29 @@
status: 'succeeded'
})

// Using a temporary mapping here also
// Re-render the letter html, merging user data to be saved in case that's in the template.
// Valida e mescla as variáveis de merge para a carta
if (!letter.merge_variables || typeof letter.merge_variables !== 'object') {
letter.merge_variables = {};
}

letter.merge_variables = {
...letter.merge_variables,
firstName: user.firstName,
lastName: user.lastName
firstName: user.firstName || 'N/A', // Valor padrão caso user.firstName esteja ausente
lastName: user.lastName || 'N/A' // Valor padrão caso user.lastName esteja ausente
};

// Busca o template da carta com validação de entrada
if (!letter.letter_template_id) {
throw new CheckoutError('Letter template ID is required.');
}
const template = await LetterTemplate.query().findById(
letter.letter_template_id
)

const template = await LetterTemplate.query()
.findById(letter.letter_template_id);

if (!template) {
throw new CheckoutError(`Letter template with ID ${letter.letter_template_id} not found.`);
}

const html = Handlebars.render(letter.merge_variables, template.html)

// Using a temporary mapping here also
Expand Down Expand Up @@ -104,7 +140,7 @@

// TODO: Move Constituent insert to earlier in the cycle.
let constituent
;[constituent] = await Constituent.query().where('email', user.email)
;[constituent] = await Constituent.query().where('email', user.email).limit(1)
if (!constituent) {
constituent = await Constituent.query().insert(user)
}
Expand All @@ -119,15 +155,29 @@
paymentMethod: 'credit_card'
})

// Re-render the letter html, merging user data to be saved in case that's in the template.
// Valida e mescla as variáveis de merge para a carta
if (!letter.merge_variables || typeof letter.merge_variables !== 'object') {
letter.merge_variables = {};
}

letter.merge_variables = {
...letter.merge_variables,
firstName: user.firstName,
lastName: user.lastName
firstName: user.firstName || 'N/A', // Valor padrão caso user.firstName esteja ausente
lastName: user.lastName || 'N/A' // Valor padrão caso user.lastName esteja ausente
};

// Busca o template da carta com validação de entrada
if (!letter.letter_template_id) {
throw new CheckoutError('Letter template ID is required.');
}
const template = await LetterTemplate.query().findById(
letter.letter_template_id
)

const template = await LetterTemplate.query()
.findById(letter.letter_template_id);

if (!template) {
throw new CheckoutError(`Letter template with ID ${letter.letter_template_id} not found.`);
}

const html = Handlebars.render(letter.merge_variables, template.html)

// Using a temporary mapping here also
Expand Down
Loading