Programing

대응: 위험하게 SetInner를 사용하여 삽입할 때 스크립트 태그가 작동하지 않음HTML

c10106 2022. 3. 10. 21:51
반응형

대응: 위험하게 SetInner를 사용하여 삽입할 때 스크립트 태그가 작동하지 않음HTML

위험한 SetInner를 사용하여 서버에서 보낸 html을 div에 표시하도록 설정하려고 하는 중대응의 HTML 속성.나도 그 안에 스크립트 태그를 가지고 있고, 그 html 안에서 동일한 기능을 사용한다.나는 여기서 JSFiddle의 오류의 예를 들었다.

테스트 코드:

var x = '<html><scr'+'ipt>alert("this.is.sparta");function pClicked() {console.log("p is clicked");}</scr'+'ipt><body><p onClick="pClicked()">Hello</p></body></html>';

var Hello = React.createClass({
  displayName: 'Hello',
  render: function() {
    return (<div dangerouslySetInnerHTML={{__html: x}} />);
  }
});

확인해보니 DOM에 스크립트 태그가 추가되었는데, 해당 스크립트 태그에 정의된 함수는 호출할 수 없다.이것이 올바르지 않은 경우 스크립트 태그의 내용을 주입할 수 있는 다른 방법이 있는지 확인하십시오.

나는 반응 컴포넌트를 만들었는데, 이 컴포넌트는 거의 비슷하게 작동한다.dangerouslySetInnerHtml그러나 추가로 html 문자열에서 찾은 모든 js 코드를 실행하며, 체크아웃하면 다음과 같은 도움이 될 수 있다.

https://www.npmjs.com/package/dangerously-set-html-content

여기 그것을 완성하는 약간의 더러운 방법이 있다, 여기서 일어나는 일에 대한 약간의 설명, 당신은 regex를 통해 스크립트 내용을 추출하고, react를 사용하여 html만 렌더링한다, 그리고 구성 요소가 탑재된 후에 스크립트 태그의 콘텐츠는 글로벌 범위에서 실행된다.

var x = '<html><scr'+'ipt>alert("this.is.sparta");function pClicked() {console.log("p is clicked");}</scr'+'ipt><body><p onClick="pClicked()">Hello</p></body></html>';

var extractscript=/<script>(.+)<\/script>/gi.exec(x);
x=x.replace(extractscript[0],"");

var Hello = React.createClass({
  displayName: 'Hello',
  componentDidMount: function() {
    // this runs the contents in script tag on a window/global scope
    window.eval(extractscript[1]);

  },
  render: function() {
    return (<div dangerouslySetInnerHTML={{__html: x}} />);
  }
});

ReactDOM.render(
  React.createElement(Hello),
  document.getElementById('container')
);

(연결을) 안 해도 될 것 같은데 ()+)여기다.

var x = '<html><scr'+'ipt>alert("this.is.sparta");function pClicked() {console.log("p is clicked");}</scr'+'ipt><body><p onClick="pClicked()">Hello</p></body></html>';

내 생각엔 넌 그냥 할 수 있을 것 같아:

var x = '<html><script>alert("this.is.sparta");function pClicked() {console.log("p is clicked");}</script><body><p onClick="pClicked()">Hello</p></body></html>';

로 넘어갔으니까.dangerouslySetInnerHTML어쨌든

하지만 다시 그 문제로 돌아가자.스크립트 태그의 내용에 액세스하기 위해 regex를 사용할 필요는 없다.추가하면id속성(예:<script id="myId">...</script>, 쉽게 요소에 접근할 수 있다.

그러한 실행의 예를 보자.

const x = `
  <html>
    <script id="myScript">
      alert("this.is.sparta");
      function pClicked() {console.log("p is clicked");}
    </script>
    <body>
      <p onClick="pClicked()">Hello</p>
    </body>
  </html>
`;

const Hello = React.createClass({

  displayName: 'Hello',

  componentDidMount() {
    const script = document.getElementById('myScript').innerHTML;
    window.eval(script);
  }

  render() {
    return <div dangerouslySetInnerHTML={{__html: x}} />;
  }

});

스크립트가 여러 개인 경우 데이터 속성을 추가할 수 있음[data-my-script]예를 들어 jQuery를 사용하여 액세스하십시오.

const x = `
  <html>
    <script data-my-script="">
      alert("this.is.sparta");
      function pClicked() {console.log("p is clicked");}
    </script>
    <script data-my-script="">
      alert("another script");
    </script>
    <body>
      <p onClick="pClicked()">Hello</p>
    </body>
  </html>
`;

const Hello = React.createClass({

  constructor(props) {
    super(props);

    this.helloElement = null;
  }

  displayName: 'Hello',

  componentDidMount() {
    $(this.helloElement).find('[data-my-script]').each(function forEachScript() {
      const script = $(this).text();
      window.eval(script);
    });
  }

  render() {
    return (
      <div
        ref={helloElement => (this.helloElement = helloElement)} 
        dangerouslySetInnerHTML={{__html: x}} 
      />
    );
  }

});

어떤 경우든, 항상 사용하지 않는 것이 좋다.eval그래서 또 다른 옵션은 전화를 거는 대신 텍스트를 가져오고 원본의 스크립트 내용과 함께 새 스크립트 태그를 추가하는 것이다.eval대답은 그러한 접근을 시사한다.

미래의 관점에 대한 다시스의 대답에 대한 약간의 연장선...

나는 매우 유사한 문제가 있었지만 나의 경우 서버측에서 HTML을 얻어서 시간이 걸렸다(백엔드가 html에 보고서를 렌더링하는 보고 솔루션의 일부)

구성 요소WillMount() 함수에서 실행 중인 스크립트를 처리할 때만 매우 유사한 작업을 수행했다.

import React from 'react';
import jsreport from 'jsreport-browser-client-dist'
import logo from './logo.svg';
import './App.css';

class App extends React.Component {
    constructor() {
        super()
        this.state = {
            report: "",
            reportScript: ""
        }
    }

    componentWillMount() {
        jsreport.serverUrl = 'http://localhost:5488';
        let reportRequest = {template: {shortid: 'HJH11D83ce'}}
        // let temp = "this is temp"
        jsreport.renderAsync(reportRequest)
            .then(res => {
                let htmlResponse = res.toString()
                let extractedScript = /<script>[\s\S]*<\/script>/g.exec(htmlResponse)[0];
                // console.log('html is: ',htmlResponse)
                // console.log('script is: ',extractedScript)
                this.setState({report: htmlResponse})
                this.setState({reportScript: extractedScript})
            })
    }

    render() {
        let report = this.state.report
        return (
            <div className="App">
                <div className="App-header">
                    <img src={logo} className="App-logo" alt="logo"/>
                    <h2>Welcome to React</h2>
                </div>
                <div id="reportPlaceholder">
                    <div dangerouslySetInnerHTML={{__html: report}}/>

                </div>
            </div>
        );
    }

    componentDidUpdate() {
        // this runs the contents in script tag on a window/global scope
        let scriptToRun = this.state.reportScript
        if (scriptToRun !== undefined) {
            //remove <script> and </script> tags since eval expects only code without html tags
            let scriptLines = scriptToRun.split("\n")
            scriptLines.pop()
            scriptLines.shift()
            let cleanScript = scriptLines.join("\n")
            console.log('running script ',cleanScript)
            window.eval(cleanScript)
        }

    }
}

export default App;

이게 도움이 되길 바래...

그냥 알려진 XSS 트릭을 사용해.우리는 대본을 주입해야 했고 개봉을 기다릴 수 없어서 로더에게 다음과 같이 말했다.

<img src onerror="var script = document.createElement('script');script.src = 'http:';document.body.appendChild(script);"/>

참조URL: https://stackoverflow.com/questions/35614809/react-script-tag-not-working-when-inserted-using-dangerouslysetinnerhtml

반응형