Home > Software design >  Replace string text with HTML Tag <br>
Replace string text with HTML Tag <br>

Time:11-10

this is what I have:

"de-de": "This is a description for Process\r\nHere is no line break"

I want to replace the \r\n with an <br> tag

This is what I am trying:

<p
     v-if="process.description"
     
     v-html="process.description.replace('\r\n', '<br >')"
>
</p>

This works, but if I use v-html , there are security warnings in case of XSS vulnerabilities. So v-html isn't the solution ether.

Someone an idea?

CodePudding user response:

As you said, You are getting description text straight from an API that means it's not directly coming from a user input. In that case you are good to go with v-html.

But if you still concern about the XSS vulnerability by using v-html, then you can do this with the help of v-for and splitting a string.

Live Demo :

new Vue({
  el: '#app',
  data: {
    description: 'This is a description for Process\r\nHere is no line break'
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <span v-for="(line, index) of description.split('\r\n')" :key="index">
    {{ line }}<br/>
  </span>
</div>

CodePudding user response:

Use Vue's built-in security

It's an interesting problem, but there is a simple solution that leverages Vue's built-in security.

If we split the description at carriage returns we can then use v-for with a template to output each text fragment appended with a <br> break.

  <p  v-if="process.description">
    <template v-for="line in process.description?.split('\r\n')">
      {{line}}<br>
    </template>
  </p>

Which produces rendered output:

<p >
    This is a description for Process<br>
    Here is no line break<br>
</p>

Further Reading

  1. OWASP XSS Filter Evasion Cheat Sheet
  2. Vue Security Best Practices

Snippet

For this test, a XSS alert has been embedded in the description. Vue escapes the alert and displays it as text. Yet, if we were to use v-html to render the description it would trigger the XSS alert.

const {
  createApp
} = Vue

createApp({
  data() {
    return {
      process: {
        description: 'This is a description for Process\r\nHere is no line break\r\n<svg/onload=alert("XSS")>'
      }
    }
  }
}).mount('#app')
body {
  font-family: sans-serif;
}
.description {
  border: 1px solid blue;
  border-radius: 0.5rem;
  padding: 1rem;
}
<div id="app">

  <p  v-if="process.description">
    <template v-for="line in process.description?.split('\r\n')">
      {{line}}<br>
    </template>
  </p>
  
  <!-- v-html will trigger a XSS alert 
  <div v-html="process.description"></div>
  -->
  
  <!-- v-text will NOT trigger XSS alert, but no line breaks 
  <div v-text="process.description"></div>
  -->
  
</div>

<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>

CodePudding user response:

I think you should put your string in a <pre> tag instead https://www.w3schools.com/tags/tag_pre.asp .

<pre> respects line breaks etc and will avoid you doing replacement hacks.

  • Related