This commit is contained in:
2024-05-24 15:27:07 +03:00
parent 17df2ce6a9
commit fc1da2c238
643 changed files with 110185 additions and 231 deletions

View File

@ -0,0 +1,106 @@
import React from "react"
import { render } from "enzyme"
import { fromJS } from "immutable"
import Info, { InfoUrl } from "components/info"
import { Link } from "components/layout-utils"
import Markdown from "components/providers/markdown"
describe("<Info/> Anchor Target Safety", function(){
const dummyComponent = () => null
const components = {
Markdown,
InfoUrl,
Link
}
const baseProps = {
getComponent: c => components[c] || dummyComponent,
host: "example.test",
basePath: "/api",
info: fromJS({
title: "Hello World"
})
}
it("renders externalDocs links with safe `rel` attributes", function () {
const props = {
...baseProps,
externalDocs: fromJS({
url: "http://google.com/"
})
}
let wrapper = render(<Info {...props} />)
const anchor = wrapper.find("a")
expect(anchor.html()).toEqual("http://google.com/")
expect(anchor.attr("target")).toEqual("_blank")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
it("renders Contact links with safe `rel` attributes", function () {
const props = {
...baseProps,
info: fromJS({
contact: {
url: "http://google.com/",
name: "My Site"
}
})
}
let wrapper = render(<Info {...props} />)
const anchor = wrapper.find("a")
expect(anchor.attr("href")).toEqual("http://google.com/")
expect(anchor.attr("target")).toEqual("_blank")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
it("renders License links with safe `rel` attributes", function () {
const props = {
...baseProps,
info: fromJS({
license: {
url: "http://mit.edu/"
}
})
}
let wrapper = render(<Info {...props} />)
const anchor = wrapper.find("a")
expect(anchor.attr("href")).toEqual("http://mit.edu/")
expect(anchor.attr("target")).toEqual("_blank")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
it("renders termsOfService links with safe `rel` attributes", function () {
const props = {
...baseProps,
info: fromJS({
termsOfService: "http://smartbear.com/"
})
}
let wrapper = render(<Info {...props} />)
const anchor = wrapper.find("a")
expect(anchor.attr("href")).toEqual("http://smartbear.com/")
expect(anchor.attr("target")).toEqual("_blank")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
it("renders definition URL links with safe `rel` attributes", function () {
const props = {
...baseProps,
url: "http://petstore.swagger.io/v2/petstore.json"
}
let wrapper = render(<Info {...props} />)
const anchor = wrapper.find("a")
expect(anchor.attr("href")).toEqual("http://petstore.swagger.io/v2/petstore.json")
expect(anchor.attr("target")).toEqual("_blank")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
})

View File

@ -0,0 +1,39 @@
import React from "react"
import { render } from "enzyme"
import { Link } from "components/layout-utils"
describe("<Link/> Anchor Target Safety", function () {
const dummyComponent = () => null
const components = {
Link
}
const baseProps = {
getComponent: c => components[c] || dummyComponent
}
it("renders regular links with `noreferrer` and `noopener`", function () {
const props = {
...baseProps,
href: "http://google.com/"
}
let wrapper = render(<Link {...props} />)
expect(wrapper.attr("href")).toEqual("http://google.com/")
expect(wrapper.attr("rel") || "").toMatch("noopener")
expect(wrapper.attr("rel") || "").toMatch("noreferrer")
})
it("enforces `noreferrer` and `noopener` on target=_blank links", function () {
const props = {
...baseProps,
href: "http://google.com/",
target: "_blank"
}
let wrapper = render(<Link {...props} />)
expect(wrapper.attr("href")).toEqual("http://google.com/")
expect(wrapper.attr("target")).toEqual("_blank")
expect(wrapper.attr("rel") || "").toMatch("noopener")
expect(wrapper.attr("rel") || "").toMatch("noreferrer")
})
})

View File

@ -0,0 +1,64 @@
import React from "react"
import { render } from "enzyme"
import Markdown from "components/providers/markdown"
import { Markdown as OAS3Markdown } from "corePlugins/oas3/wrap-components/markdown.jsx"
describe("Markdown Link Anchor Safety", function () {
describe("Swagger 2.0", function () {
it("sanitizes Markdown links", function () {
const str = `Hello, [here](http://google.com/) is my link`
const wrapper = render(<Markdown source={str} />)
const anchor = wrapper.find("a")
expect(anchor.attr("href")).toEqual("http://google.com/")
expect(anchor.attr("target")).toEqual("_blank")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
it("sanitizes raw HTML links", function () {
const str = `Hello, <a href="http://google.com/">here</a> is my link`
const wrapper = render(<Markdown source={str} />)
const anchor = wrapper.find("a")
expect(anchor.attr("href")).toEqual("http://google.com/")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
})
describe("OAS 3", function () {
it("sanitizes Markdown links", function () {
const str = `Hello, [here](http://google.com/) is my link`
const wrapper = render(<OAS3Markdown source={str} />)
const anchor = wrapper.find("a")
expect(anchor.attr("href")).toEqual("http://google.com/")
expect(anchor.attr("target")).toEqual("_blank")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
it("sanitizes raw HTML links", function () {
const str = `Hello, <a href="http://google.com/">here</a> is my link`
const wrapper = render(<OAS3Markdown source={str} />)
const anchor = wrapper.find("a")
expect(anchor.attr("href")).toEqual("http://google.com/")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
})
})
function withMarkdownWrapper(str, { isOAS3 = false } = {}) {
if(isOAS3) {
return `<div class="renderedMarkdown"><p>${str}</p></div>`
}
return `<div class="markdown"><p>${str}</p>\n</div>`
}

View File

@ -0,0 +1,29 @@
import React from "react"
import { mount } from "enzyme"
import OnlineValidatorBadge from "components/online-validator-badge"
describe("<OnlineValidatorBadge/> Anchor Target Safety", function () {
it("should render a validator link with safe `rel` attributes", function () {
// When
const props = {
getConfigs: () => ({}),
getComponent: () => null,
specSelectors: {
url: () => "swagger.json"
}
}
const wrapper = mount(
<OnlineValidatorBadge {...props} />
)
const anchor = wrapper.find("a")
// Then
expect(anchor.props().href).toEqual(
"https://validator.swagger.io/validator/debug?url=swagger.json"
)
expect(anchor.props().target).toEqual("_blank")
expect(anchor.props().rel || "").toInclude("noopener")
expect(anchor.props().rel || "").toInclude("noreferrer")
})
})

View File

@ -0,0 +1,32 @@
import React from "react"
import { render } from "enzyme"
import { fromJS } from "immutable"
import Info from "components/info"
import Markdown from "components/providers/markdown"
describe("<Info/> Sanitization", function(){
const dummyComponent = () => null
const components = {
Markdown
}
const props = {
getComponent: c => components[c] || dummyComponent,
info: fromJS({
title: "Test Title **strong** <script>alert(1)</script>",
description: "Description *with* <script>Markdown</script>"
}),
host: "example.test",
basePath: "/api",
selectedServer: "https://example.test",
}
it("renders sanitized .title content", function(){
let wrapper = render(<Info {...props}/>)
expect(wrapper.find(".title").html()).toEqual("Test Title **strong** &lt;script&gt;alert(1)&lt;/script&gt;")
})
it("renders sanitized .description content", function() {
let wrapper = render(<Info {...props}/>)
expect(wrapper.find(".description").html()).toEqual("<div class=\"markdown\"><p>Description <em>with</em> </p>\n</div>")
})
})

View File

@ -0,0 +1,46 @@
import React from "react"
import { render } from "enzyme"
import Markdown from "components/providers/markdown"
import { Markdown as OAS3Markdown } from "corePlugins/oas3/wrap-components/markdown.jsx"
describe("Markdown Script Sanitization", function() {
describe("Swagger 2.0", function() {
it("sanitizes <script> elements", function() {
const str = `script <script>alert(1)</script>`
const el = render(<Markdown source={str} />)
expect(el.prop("outerHTML")).toEqual(`<div class="markdown"><p>script </p>\n</div>`)
})
it("sanitizes <img> elements", function() {
const str = `<img src=x onerror="alert('img-in-description')">`
const el = render(<Markdown source={str} />)
expect(el.prop("outerHTML")).toEqual(`<div class="markdown"><p><img src="x"></p>\n</div>`)
})
it("sanitizes <form> elements", function() {
const str = `"<form action='https://do.not.use.url/fake' method='post' action='java'><input type='email' id='email' placeholder='Email-address' name='email' value=''><button type='submit'>Login</button>"`
const el = render(<Markdown source={str} />)
expect(el.prop("outerHTML")).toEqual(`<div class="markdown"><p>"</p><input value="" name="email" placeholder="Email-address" id="email" type="email"><button type="submit">Login</button>"<p></p>\n</div>`)
})
})
describe("OAS 3", function() {
it("sanitizes <script> elements", function() {
const str = `script <script>alert(1)</script>`
const el = render(<OAS3Markdown source={str} />)
expect(el.prop("outerHTML")).toEqual(`<div class="renderedMarkdown"><p>script </p></div>`)
})
it("sanitizes <img> elements", function() {
const str = `<img src=x onerror="alert('img-in-description')">`
const el = render(<OAS3Markdown source={str} />)
expect(el.prop("outerHTML")).toEqual(`<div class="renderedMarkdown"><p><img src="x"></p></div>`)
})
it("sanitizes <form> elements", function () {
const str = `"<form action='https://do.not.use.url/fake' method='post' action='java'><input type='email' id='email' placeholder='Email-address' name='email' value=''><button type='submit'>Login</button>"`
const el = render(<OAS3Markdown source={str} />)
expect(el.prop("outerHTML")).toEqual(`<div class="renderedMarkdown"><p>"</p><input value="" name="email" placeholder="Email-address" id="email" type="email"><button type="submit">Login</button>"<p></p></div>`)
})
})
})