Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
📦 npm

GHSA-5jcr-82fh-339v

MEDIUM

Cross-Site-Scripting attack on `<RichTextField>`

Also known asCVE-2023-25572
Published
Feb 14, 2023
Updated
Nov 8, 2023
Affected
4 pkgs
Patched
4 / 4
Exploits
2 known

EPSS Exploitation Probability

via FIRST.org ↗
0.7%probability of exploitation in next 30 days
Lower Risk48th percentile-0.11%
0.19%0.71%1.22%1.73%1.1%0.7%Dec 25Apr 26Jun 26

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

Blast Radius

4 pkgs affected

Weekly download volume for affected packages — a proxy for how broadly this vulnerability is deployed.

react-adminnpm
172Kdownloads / week
ra-ui-materialuinpm
176Kdownloads / week

Description

Impact

All React applications built with react-admin and using the <RichTextField> are affected.

<RichTextField> outputs the field value using dangerouslySetInnerHTML without client-side sanitization. If the data isn't sanitized server-side, this opens a possible Cross-Site-Scripting (XSS) attack.

Proof of concept:

import { RichTextField } from 'react-admin';

const record = {
    id: 1,
    body: `
<p>
<strong>War and Peace</strong> is a novel by the Russian author
<a href="https://en.wikipedia.org/wiki/Leo_Tolstoy" onclick="document.getElementById('stolendata').value='credentials';">Leo Tolstoy</a>,
published serially, then in its entirety in 1869.
</p>
<p onmouseover="document.getElementById('stolendata').value='credentials';">
It is regarded as one of Tolstoy's finest literary achievements and remains a classic of world literature.
</p>
<img src="x" onerror="document.getElementById('stolendata').value='credentials';" />
`,
};

const VulnerableRichTextField = () => (
    <>
        <RichTextField record={record} source="body" />
        <hr />
        <h4>Stolen data:</h4>
        <input id="stolendata" defaultValue="none" />
    </>
);

Patches

Versions 3.19.12 and 4.7.6 now use DOMPurify to escape the HTML before outputting it with React and dangerouslySetInnerHTML

Workarounds

You don't need to upgrade if you already sanitize HTML data server-side.

Otherwise, you'll have to replace the <RichTextField> by a custom field doing sanitization by hand:

// react-admin v4
import * as React from 'react';
import { memo } from 'react';
import PropTypes from 'prop-types';
import get from 'lodash/get';
import Typography from '@material-ui/core/Typography';
import { useRecordContext, sanitizeFieldRestProps, fieldPropTypes } from 'react-admin';
import purify from 'dompurify';

export const removeTags = (input) =>
    input ? input.replace(/<[^>]+>/gm, '') : '';

const RichTextField = memo(
    props => {
        const { className, emptyText, source, stripTags, ...rest } = props;
        const record = useRecordContext(props);
        const value = get(record, source);

        return (
            <Typography
                className={className}
                variant="body2"
                component="span"
                {...sanitizeFieldRestProps(rest)}
            >
                {value == null && emptyText ? (
                    emptyText
                ) : stripTags ? (
                    removeTags(value)
                ) : (
                    <span
                        dangerouslySetInnerHTML={{
                            __html: purify.sanitize(value),
                        }}
                    />
                )}
            </Typography>
        );
    }
);

RichTextField.defaultProps = {
    addLabel: true,
    stripTags: false,
};

RichTextField.propTypes = {
    // @ts-ignore
    ...Typography.propTypes,
    ...fieldPropTypes,
    stripTags: PropTypes.bool,
};

RichTextField.displayName = 'RichTextField';

export default RichTextField;

References

https://github.com/marmelab/react-admin/pull/8644, https://github.com/marmelab/react-admin/pull/8645

Affected Packages

4 total 4 fixed
EcosystemPackageVulnerable rangeFix
📦npmreact-adminall versions3.19.12
📦npmreact-admin4.0.0&&< 4.7.64.7.6
📦npmra-ui-materialui4.0.0&&< 4.7.64.7.6
📦npmra-ui-materialuiall versions3.19.12
Exploits & PoCs
2

Research use only. For defensive security, authorized penetration testing, and academic research only. Never execute exploit code against systems without explicit written authorization.

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for react-admin. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Fix

    Update react-admin to 3.19.12 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-5jcr-82fh-339v is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-5jcr-82fh-339v is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-5jcr-82fh-339v. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

### Impact All React applications built with react-admin and using the `<RichTextField>` are affected. `<RichTextField>` outputs the field value using `dangerouslySetInnerHTML` without client-side sanitization. If the data isn't sanitized server-side, this opens a possible Cross-Site-Scripting (XSS) attack. Proof of concept: ```jsx import { RichTextField } from 'react-admin'; const record = { id: 1, body: ` <p> <strong>War and Peace</strong> is a novel by the Russian author <a href="https://en.wikipedia.org/wiki/Leo_Tolstoy" onclick="document.getElementById('stolendata').value='
O3 Security · Impact-Aware SCA

Is GHSA-5jcr-82fh-339v in your dependencies?

O3 detects GHSA-5jcr-82fh-339v across npm dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.