Skip to content

Latest commit

 

History

History
241 lines (209 loc) · 5.83 KB

File metadata and controls

241 lines (209 loc) · 5.83 KB

FlexNet JSX Security Best Practices

XSS Prevention

Content Handling

const escape = str => compose(
    String,
    s => s.replace(/&/g, '&')
         .replace(/</g, '&lt;')
         .replace(/>/g, '&gt;')
         .replace(/"/g, '&quot;')
         .replace(/'/g, '&#039;')
)(str);

const validateInput = compose(
    input => {
        const escaped = escape(input);
        return escaped.length === input.length
            ? Either.Right(input)
            : Either.Left('Invalid characters detected');
    }
);

DOM Interaction

// Safe createElement implementation
const createElement = (type, props, ...children) => {
    // Validate type
    if (typeof type !== 'string' && typeof type !== 'function') {
        return Either.Left('Invalid element type');
    }

    // Sanitize props
    const safeProps = Object.entries(props || {}).reduce((acc, [key, value]) => {
        // Prevent script injection in event handlers
        if (key.startsWith('on') && typeof value === 'string') {
            return acc;
        }
        // Escape string values
        if (typeof value === 'string') {
            acc[key] = safeContent.escape(value);
        } else {
            acc[key] = value;
        }
        return acc;
    }, {});

    return Either.Right({ type, props: safeProps, children });
};

URL Validation

const urlValidator = {
    // Whitelist of allowed protocols
    allowedProtocols: ['https:', 'data:image/'],

    validate: (url) => {
        try {
            const parsed = new URL(url);
            return allowedProtocols.some(protocol => 
                parsed.protocol.startsWith(protocol))
                ? Either.Right(url)
                : Either.Left('Invalid protocol');
        } catch {
            return Either.Left('Invalid URL');
        }
    }
};

State Management Security

Immutable State Updates

const secureState = {
    update: (state, updater) => {
        const newState = Object.freeze({
            ...state,
            value: updater(state.value),
            timestamp: new Date().toISOString(),
            hash: generateStateHash(state)
        });
        return validateStateIntegrity(newState);
    },

    validateStateIntegrity: (state) => {
        const currentHash = generateStateHash(state);
        return currentHash === state.hash
            ? Either.Right(state)
            : Either.Left('State integrity compromised');
    }
};

Access Control

const stateAccess = {
    permissions: {
        READ: 'read',
        WRITE: 'write',
        ADMIN: 'admin'
    },

    validateAccess: (state, operation, permission) => {
        const userPermissions = getCurrentUserPermissions();
        return userPermissions.includes(permission)
            ? Either.Right(state)
            : Either.Left('Insufficient permissions');
    }
};

Error Handling

Error Boundaries

const ErrorBoundary = ({ children, fallback }) => {
    const [error, setError] = useState(null);

    useEffect(() => {
        const handleError = (event) => {
            event.preventDefault();
            setError(event.error);
            logError(event.error);
        };

        window.addEventListener('error', handleError);
        return () => window.removeEventListener('error', handleError);
    }, []);

    return error ? fallback(error) : children;
};

Secure Error Logging

const errorLogger = {
    sensitiveKeys: ['password', 'token', 'secret'],

    sanitizeError: (error) => {
        const sanitized = { ...error };
        sensitiveKeys.forEach(key => {
            if (key in sanitized) {
                sanitized[key] = '[REDACTED]';
            }
        });
        return sanitized;
    },

    logError: (error) => {
        const sanitizedError = sanitizeError(error);
        console.error('Secure Error:', sanitizedError);
    }
};

Memory State Security

Context Validation

const secureContext = {
    validate: (context) => {
        if (!context.activeFiles || !context.implementationState) {
            return Either.Left('Invalid context structure');
        }

        return validateFilePaths(context.activeFiles)
            .chain(validateImplementation)
            .chain(validateStateIntegrity);
    }
};

File System Security

const fileSystem = {
    validatePath: (path) => {
        // Prevent directory traversal
        const normalized = path.replace(/\.\./g, '');
        return path === normalized
            ? Either.Right(path)
            : Either.Left('Invalid path');
    },

    validatePermissions: (path) => {
        const stats = getFileStats(path);
        return stats.mode === expectedMode
            ? Either.Right(path)
            : Either.Left('Invalid permissions');
    }
};

Technical Standards Implementation

Script Safety

const scriptSafety = {
    // Error trapping
    trapErrors: (fn) => (...args) => {
        try {
            return Either.Right(fn(...args));
        } catch (error) {
            return Either.Left(error);
        }
    },

    // Variable quoting
    quoteVariable: (value) => 
        typeof value === 'string' ? `'${value}'` : value,

    // Permission handling
    checkPermissions: (operation) =>
        validateAccess(operation)
            .chain(validateFilesystem)
            .chain(validateState),

    // Cleanup procedures
    ensureCleanup: (operation) => {
        const cleanup = [];
        return {
            addCleanup: (fn) => cleanup.push(fn),
            execute: () => {
                try {
                    return operation();
                } finally {
                    cleanup.forEach(fn => fn());
                }
            }
        };
    }
};

Version Information

  • Security Version: 1.0
  • Framework Version: 1.0
  • Last Updated: 2024-12-19