feat(core): 限制dangerouslySetInnerHTML API生效的条件,减少XSS攻击面
This commit is contained in:
parent
ec34490202
commit
ebfe1eceb9
|
@ -95,4 +95,16 @@ describe('Dom Attribute', () => {
|
||||||
Inula.render(<div {...emptyStringProps} />, container);
|
Inula.render(<div {...emptyStringProps} />, container);
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('dangerouslySetInnerHTML和children同时设置,只渲染children', () => {
|
||||||
|
Inula.act(() => {
|
||||||
|
Inula.render(
|
||||||
|
<div className="root" dangerouslySetInnerHTML={{ __html: '1234' }}>
|
||||||
|
123
|
||||||
|
</div>,
|
||||||
|
container
|
||||||
|
);
|
||||||
|
});
|
||||||
|
expect(container.innerHTML).toBe('<div class="root">123</div>');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,6 +17,25 @@ import { getPropDetails, PROPERTY_TYPE, PropDetails } from './PropertiesData';
|
||||||
|
|
||||||
const INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
|
const INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
|
||||||
|
|
||||||
|
const voidTagElements = [
|
||||||
|
'area',
|
||||||
|
'base',
|
||||||
|
'br',
|
||||||
|
'col',
|
||||||
|
'embed',
|
||||||
|
'hr',
|
||||||
|
'img',
|
||||||
|
'input',
|
||||||
|
'keygen',
|
||||||
|
'link',
|
||||||
|
'meta',
|
||||||
|
'param',
|
||||||
|
'source',
|
||||||
|
'track',
|
||||||
|
'wbr',
|
||||||
|
'menuitem',
|
||||||
|
];
|
||||||
|
|
||||||
// 是内置元素
|
// 是内置元素
|
||||||
export function isNativeElement(tagName: string, props: Record<string, any>) {
|
export function isNativeElement(tagName: string, props: Record<string, any>) {
|
||||||
return !tagName.includes('-') && props.is === undefined;
|
return !tagName.includes('-') && props.is === undefined;
|
||||||
|
@ -108,6 +127,18 @@ export function validateProps(type, props) {
|
||||||
throw new Error('style should be a object.');
|
throw new Error('style should be a object.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 对于没有children的元素,设置dangerouslySetInnerHTML不生效
|
||||||
|
if (voidTagElements.includes(type)) {
|
||||||
|
if (props.dangerouslySetInnerHTML != null) {
|
||||||
|
delete props.dangerouslySetInnerHTML;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dangerouslySetInnerHTML和children同时设置,只渲染children
|
||||||
|
if (props.dangerouslySetInnerHTML != null && props.children != null) {
|
||||||
|
delete props.dangerouslySetInnerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
if (isDev) {
|
if (isDev) {
|
||||||
// 校验属性
|
// 校验属性
|
||||||
const invalidProps = Object.keys(props).filter(key => !isValidProp(type, key, props[key]));
|
const invalidProps = Object.keys(props).filter(key => !isValidProp(type, key, props[key]));
|
||||||
|
|
Loading…
Reference in New Issue