Rules for preventing common security vulnerabilities and unsafe patterns in React applications. These rules help protect against XSS attacks, unsafe DOM operations, and other security risks.
Rules preventing unsafe DOM operations and manipulations.
const domSecurityRules = {
/** Prevent usage of dangerous JSX props */
'react/no-danger': ESLintRule;
/** Report when a DOM element is using both children and dangerouslySetInnerHTML */
'react/no-danger-with-children': ESLintRule;
/** Prevent usage of findDOMNode */
'react/no-find-dom-node': ESLintRule;
/** Prevent usage of unknown DOM property */
'react/no-unknown-property': ESLintRule;
/** Prevent usage of invalid HTML attributes */
'react/no-invalid-html-attribute': ESLintRule;
};Usage Examples:
// ✓ Good - Safe content rendering
<div>{userContent}</div>
// ✗ Bad - Using dangerouslySetInnerHTML (when rule enabled)
<div dangerouslySetInnerHTML={{__html: userContent}} />
// ✓ Good - Using dangerouslySetInnerHTML without children
<div dangerouslySetInnerHTML={{__html: sanitizedHTML}} />
// ✗ Bad - Using dangerouslySetInnerHTML with children
<div dangerouslySetInnerHTML={{__html: html}}>
<span>This will cause issues</span>
</div>
// ✓ Good - Using refs instead of findDOMNode
const MyComponent = () => {
const divRef = useRef(null);
return <div ref={divRef}>Content</div>;
};
// ✗ Bad - Using findDOMNode
import { findDOMNode } from 'react-dom';
const node = findDOMNode(this);
// ✓ Good - Valid HTML attributes
<input type="text" className="input" />
// ✗ Bad - Unknown DOM property
<div clasName="container" /> // typo: should be classNameRules for secure handling of URLs and external links.
const urlSecurityRules = {
/** Forbid javascript: URLs */
'react/jsx-no-script-url': ESLintRule;
/** Forbid target="_blank" attribute without rel="noreferrer" */
'react/jsx-no-target-blank': ESLintRule;
};Usage Examples:
// ✓ Good - Safe external link with proper rel attribute
<a href="https://example.com" target="_blank" rel="noreferrer noopener">
External Link
</a>
// ✗ Bad - target="_blank" without rel="noreferrer"
<a href="https://example.com" target="_blank">
External Link
</a>
// ✓ Good - Internal link
<a href="/internal-page">Internal Link</a>
// ✗ Bad - javascript: URL
<a href="javascript:void(0)">Click me</a>
<button onClick={() => location.href = 'javascript:alert(1)'}>
Dangerous
</button>
// ✓ Good - Safe button handler
<button onClick={handleClick}>Click me</button>
// ✓ Good - Safe dynamic URL (when properly validated)
<a href={sanitizedUrl} target="_blank" rel="noreferrer">
Dynamic Link
</a>Rules preventing unsafe usage of deprecated or dangerous lifecycle methods.
const lifecycleSecurityRules = {
/** Prevent usage of deprecated methods */
'react/no-deprecated': ESLintRule;
/** Prevent usage of UNSAFE_ methods */
'react/no-unsafe': ESLintRule;
/** Prevent usage of isMounted */
'react/no-is-mounted': ESLintRule;
/** Prevent usage of the return value of React.render */
'react/no-render-return-value': ESLintRule;
};Usage Examples:
// ✓ Good - Using modern lifecycle methods
class MyComponent extends React.Component {
componentDidMount() {
// Safe lifecycle method
}
static getDerivedStateFromProps(props, state) {
// Safe static method
}
}
// ✗ Bad - Using deprecated lifecycle methods
class MyComponent extends React.Component {
componentWillMount() {
// Deprecated and potentially unsafe
}
componentWillReceiveProps(nextProps) {
// Deprecated and potentially unsafe
}
}
// ✗ Bad - Using UNSAFE_ methods
class MyComponent extends React.Component {
UNSAFE_componentWillMount() {
// Explicitly unsafe
}
}
// ✓ Good - Not using isMounted
class MyComponent extends React.Component {
componentDidMount() {
this.fetchData().then(data => {
if (this._mounted) {
this.setState({ data });
}
});
}
componentWillUnmount() {
this._mounted = false;
}
}
// ✗ Bad - Using isMounted
class MyComponent extends React.Component {
componentDidMount() {
this.fetchData().then(data => {
if (this.isMounted()) {
this.setState({ data });
}
});
}
}Rules for secure iframe and embedded content handling.
const embedSecurityRules = {
/** Prevent usage of children with iframe elements and enforce sandbox */
'react/iframe-missing-sandbox': ESLintRule;
};Usage Examples:
// ✓ Good - iframe with sandbox attribute
<iframe
src="https://trusted-site.com/embed"
sandbox="allow-scripts allow-same-origin"
title="Embedded content"
/>
// ✓ Good - iframe with restrictive sandbox
<iframe
src="https://untrusted-site.com/content"
sandbox="allow-scripts"
title="Untrusted content"
/>
// ✗ Bad - iframe without sandbox
<iframe src="https://untrusted-site.com/content" />
// ✗ Bad - iframe with children (iframes should be self-closing)
<iframe src="https://example.com">
Fallback content
</iframe>Rules specifically designed to prevent Cross-Site Scripting (XSS) attacks.
const xssPreventionRules = {
/** Prevent unescaped entities in JSX */
'react/no-unescaped-entities': ESLintRule;
/** Prevent problematic leaked values from being rendered */
'react/jsx-no-leaked-render': ESLintRule;
/** Prevent passing of children to void DOM elements */
'react/jsx-no-constructed-context-values': ESLintRule;
};Usage Examples:
// ✓ Good - Properly escaped entities
<div>You & I</div>
<div>Price: $100 < $200</div>
<div>{"You & I"}</div>
<div>{"Price: $100 < $200"}</div>
// ✗ Bad - Unescaped entities that could cause rendering issues
<div>You & I</div>
<div>Price: $100 < $200</div>
// ✓ Good - Safe conditional rendering
<div>
{items.length > 0 && <ItemList items={items} />}
{showMessage && <Message text="Hello" />}
</div>
// ✗ Bad - Potential leaked render values
<div>
{items.length && <ItemList items={items} />}
{/* If items.length is 0, renders "0" */}
</div>
// ✓ Good - Static context values or memoized objects
const contextValue = useMemo(() => ({ user, settings }), [user, settings]);
<MyContext.Provider value={contextValue}>
{children}
</MyContext.Provider>
// ✗ Bad - Constructed context values on each render
<MyContext.Provider value={{ user, settings }}>
{children}
</MyContext.Provider>Rules for safe handling of user input and form data.
const inputValidationRules = {
/** Enforce button elements to have explicit type attribute */
'react/button-has-type': ESLintRule;
/** Enforce onChange or readonly for checked property */
'react/checked-requires-onchange-or-readonly': ESLintRule;
/** Prevent array index in keys */
'react/no-array-index-key': ESLintRule;
};Usage Examples:
// ✓ Good - Button with explicit type
<button type="button" onClick={handleClick}>
Action Button
</button>
<button type="submit">
Submit Form
</button>
<button type="reset">
Reset Form
</button>
// ✗ Bad - Button without type (defaults to submit)
<button onClick={handleClick}>
Action Button
</button>
// ✓ Good - Controlled checkbox with proper event handling
<input
type="checkbox"
checked={isSelected}
onChange={handleSelectionChange}
/>
// ✓ Good - Read-only checkbox
<input
type="checkbox"
checked={isSelected}
readOnly
/>
// ✗ Bad - Checked input without onChange or readOnly
<input type="checkbox" checked={isSelected} />
// ✓ Good - Using stable, unique keys
{users.map(user => (
<UserCard key={user.id} user={user} />
))}
// ✗ Bad - Using array index as key
{users.map((user, index) => (
<UserCard key={index} user={user} />
))}Rules that help maintain CSP compliance and secure content policies.
const cspRules = {
/** Prevent inline event handlers that violate CSP */
'react/jsx-no-script-url': ESLintRule;
/** Prevent usage of eval-like constructs */
'react/no-danger': ESLintRule;
};Usage Examples:
// ✓ Good - CSP-compliant event handling
const MyComponent = () => {
const handleClick = () => {
// Event handler logic
};
return <button onClick={handleClick}>Click me</button>;
};
// ✗ Bad - Inline javascript URLs that violate CSP
<button onClick={() => eval('some code')}>
Dangerous Button
</button>
<a href="javascript:someFunction()">
CSP-violating Link
</a>
// ✓ Good - Safe external resource loading
<img src="https://trusted-cdn.com/image.jpg" alt="Safe image" />
// ✗ Bad - Potentially unsafe inline content
<div dangerouslySetInnerHTML={{__html: `<script>alert('xss')</script>`}} />Security rules often support configuration for different security levels:
{
"rules": {
"react/no-danger": "error", // Completely forbid dangerouslySetInnerHTML
"react/jsx-no-target-blank": ["error", {
"allowReferrer": false,
"enforceDynamicLinks": "always",
"warnOnSpreadAttributes": true,
"links": true,
"forms": true
}],
"react/iframe-missing-sandbox": ["error", {
"allowFullScreen": false
}],
"react/no-unknown-property": ["error", {
"ignore": ["css"] // Allow CSS-in-JS properties
}],
"react/jsx-no-script-url": ["error", [
{
"name": "Link",
"props": ["to", "href"]
},
{
"name": "Foo",
"props": ["href"]
}
]]
}
}When using these rules, consider these additional security practices: