fix: resolve critical bugs and security issues across the project
Security: - Disable SSL verification only in development (lib/req.js) - Wrap all JSON.parse(cookie) calls in try-catch via safeJsonParse utility - Sanitize dangerouslySetInnerHTML in blog/clinic with sanitizeHtml utility - Fix open redirect in payment page — validate URL origin before redirect - Fix cookie cleanup on 401 — use js-cookie with correct domain scope Performance: - Wrap ItemDoctor with React.memo to prevent unnecessary re-renders - Replace <img> with Next.js <Image> in blog Caption component Functionality: - Fix memory leak in Recode.js — store intervals in refs, cleanup on unmount - Add null guard on retryIcon.current before classList manipulation - Fix getParsedUserInfo in helper to handle malformed cookie gracefully Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
1aa9f82d2a
commit
59e0a0fe4f
+4
-3
@@ -1,4 +1,5 @@
|
||||
import { AbilityBuilder, createMongoAbility } from "@casl/ability";
|
||||
import { safeJsonParse } from "./sanitize";
|
||||
|
||||
export function defineAbilitiesFor(user) {
|
||||
const { can, cannot, build } = new AbilityBuilder(createMongoAbility);
|
||||
@@ -6,9 +7,9 @@ export function defineAbilitiesFor(user) {
|
||||
if (user) {
|
||||
can("access", "Dashboard");
|
||||
cannot("access", "Login");
|
||||
const parsedData = JSON.parse(user.value);
|
||||
|
||||
if (parsedData.roles && Object.values(parsedData.roles).includes("representation")) {
|
||||
const parsedData = safeJsonParse(user.value);
|
||||
const roles = parsedData?.roles;
|
||||
if (roles && Array.isArray(Object.values(roles)) && Object.values(roles).includes("representation")) {
|
||||
can("access", "Panel");
|
||||
}
|
||||
} else {
|
||||
|
||||
+3
-4
@@ -1,11 +1,10 @@
|
||||
import axios from "axios";
|
||||
import https from "https";
|
||||
|
||||
// Create axios instance with SSL verification disabled for development
|
||||
const axiosInstance = axios.create({
|
||||
httpsAgent: new https.Agent({
|
||||
rejectUnauthorized: false
|
||||
})
|
||||
...(process.env.NODE_ENV === "development" && {
|
||||
httpsAgent: new https.Agent({ rejectUnauthorized: false }),
|
||||
}),
|
||||
});
|
||||
|
||||
export const fetchReq = async (url, headers) => {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
const DANGEROUS_TAGS = ['script', 'iframe', 'object', 'embed', 'link', 'meta', 'base', 'form'];
|
||||
|
||||
export function sanitizeHtml(html) {
|
||||
if (!html || typeof html !== 'string') return '';
|
||||
|
||||
let sanitized = html;
|
||||
|
||||
DANGEROUS_TAGS.forEach((tag) => {
|
||||
const openClose = new RegExp(`<${tag}[\\s\\S]*?(?:<\\/${tag}>|/?>)`, 'gi');
|
||||
sanitized = sanitized.replace(openClose, '');
|
||||
});
|
||||
|
||||
sanitized = sanitized.replace(/\s+on\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]*)/gi, '');
|
||||
sanitized = sanitized.replace(/(?:javascript|vbscript):/gi, '');
|
||||
|
||||
return sanitized;
|
||||
}
|
||||
|
||||
export function safeJsonParse(str, fallback = null) {
|
||||
if (!str) return fallback;
|
||||
try {
|
||||
return JSON.parse(str);
|
||||
} catch {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user