Skip to content

Commit

Permalink
fix: sanitize options
Browse files Browse the repository at this point in the history
  • Loading branch information
acnormun committed Jan 22, 2025
1 parent 361b529 commit 8b3d1e2
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 10 deletions.
4 changes: 2 additions & 2 deletions src/components/Accordion/Accordion.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

<script>
import UnnnicIcon from '../Icon.vue';
import { escapeHtml } from '../../utils/sanitize';
import { sanitizeHtml } from '../../utils/sanitize';

export default {
components: {
Expand Down Expand Up @@ -64,7 +64,7 @@ export default {

computed: {
sanitizedTitle() {
return escapeHtml(this.title);
return sanitizeHtml(this.title, ['b', 'i', 'u'], 500);
},
},

Expand Down
57 changes: 49 additions & 8 deletions src/utils/sanitize.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// src/utils/sanitize.js

/**
* @param {string} input
* @returns {string}
* Escapa caracteres perigosos no HTML para evitar XSS.
* @param {string} input
* @returns {string}
*/
export function escapeHtml(input) {
if (typeof input !== 'string') return '';
Expand All @@ -15,6 +16,7 @@ export function escapeHtml(input) {
}

/**
* Remove todas as tags HTML para retornar texto puro.
* @param {string} input
* @returns {string}
*/
Expand All @@ -26,19 +28,58 @@ export function stripHtml(input) {
}

/**
* @param {string} input
* @param {Array<string>} allowedTags
* @returns {string}
* Verifica se uma URL é segura (http, https, mailto).
* @param {string} url
* @returns {boolean}
*/
function isSafeUrl(url) {
try {
const parsedUrl = new URL(url);
return ['http:', 'https:', 'mailto:'].includes(parsedUrl.protocol);
} catch (e) {
return false;
}
}

/**
* Sanitiza o HTML permitindo apenas certas tags e removendo atributos perigosos.
* @param {string} input
* @param {Array<string>} allowedTags
* @param {number} maxLength
* @returns {string}
*/
export function sanitizeHtml(input, allowedTags = []) {
export function sanitizeHtml(input, allowedTags = [], maxLength = 1000) {
if (typeof input !== 'string') return '';

// Limitar o tamanho do texto
if (input.length > maxLength) {
input = input.substring(0, maxLength);
}

const tempDiv = document.createElement('div');
tempDiv.innerHTML = input;

const elements = tempDiv.getElementsByTagName('*');
for (let i = elements.length - 1; i >= 0; i--) {
if (!allowedTags.includes(elements[i].nodeName.toLowerCase())) {
elements[i].parentNode.removeChild(elements[i]);
const el = elements[i];

// Remover tags não permitidas
if (!allowedTags.includes(el.nodeName.toLowerCase())) {
el.parentNode.removeChild(el);
continue;
}

// Remover atributos perigosos
const attributes = el.attributes;
for (let j = attributes.length - 1; j >= 0; j--) {
const attrName = attributes[j].name.toLowerCase();
const attrValue = attributes[j].value;

if (attrName.startsWith('on') || attrName === 'srcdoc') {
el.removeAttribute(attrName);
} else if (['href', 'src'].includes(attrName) && !isSafeUrl(attrValue)) {
el.removeAttribute(attrName);
}
}
}

Expand Down

0 comments on commit 8b3d1e2

Please sign in to comment.