http-agent.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. const nock = require('nock')
  2. const { getRedirectEvaluator, FORBIDDEN_IP_ADDRESS, FORBIDDEN_RESOLVED_IP_ADDRESS } = require('../../src/server/helpers/request')
  3. const { getProtectedGot } = require('../../src/server/helpers/request')
  4. describe('test getRedirectEvaluator', () => {
  5. const httpURL = 'http://uppy.io'
  6. const httpsURL = 'https://uppy.io'
  7. const httpRedirectResp = {
  8. headers: {
  9. location: 'http://transloadit.com',
  10. },
  11. }
  12. const httpsRedirectResp = {
  13. headers: {
  14. location: 'https://transloadit.com',
  15. },
  16. }
  17. test('when original URL has "https:" as protocol', (done) => {
  18. const shouldRedirectHttps = getRedirectEvaluator(httpsURL, true)
  19. expect(shouldRedirectHttps(httpsRedirectResp)).toEqual(true)
  20. expect(shouldRedirectHttps(httpRedirectResp)).toEqual(false)
  21. done()
  22. })
  23. test('when original URL has "http:" as protocol', (done) => {
  24. const shouldRedirectHttp = getRedirectEvaluator(httpURL, true)
  25. expect(shouldRedirectHttp(httpRedirectResp)).toEqual(true)
  26. expect(shouldRedirectHttp(httpsRedirectResp)).toEqual(false)
  27. done()
  28. })
  29. })
  30. afterAll(() => {
  31. nock.cleanAll()
  32. nock.restore()
  33. })
  34. describe('test protected request Agent', () => {
  35. test('allows URLs without IP addresses', async () => {
  36. nock('https://transloadit.com').get('/').reply(200)
  37. const url = 'https://transloadit.com'
  38. await getProtectedGot({ url, blockLocalIPs: true }).get(url)
  39. })
  40. test('blocks url that resolves to forbidden IP', async () => {
  41. const url = 'https://localhost'
  42. const promise = getProtectedGot({ url, blockLocalIPs: true }).get(url)
  43. await expect(promise).rejects.toThrow(new Error(FORBIDDEN_RESOLVED_IP_ADDRESS))
  44. })
  45. test('blocks private http IP address', async () => {
  46. const url = 'http://172.20.10.4:8090'
  47. const promise = getProtectedGot({ url, blockLocalIPs: true }).get(url)
  48. await expect(promise).rejects.toThrow(new Error(FORBIDDEN_IP_ADDRESS))
  49. })
  50. test('blocks private https IP address', async () => {
  51. const url = 'https://172.20.10.4:8090'
  52. const promise = getProtectedGot({ url, blockLocalIPs: true }).get(url)
  53. await expect(promise).rejects.toThrow(new Error(FORBIDDEN_IP_ADDRESS))
  54. })
  55. test('blocks various private IP addresses', async () => {
  56. // eslint-disable-next-line max-len
  57. // taken from: https://github.com/transloadit/uppy/blob/4aeef4dac0490ebb1d1fccd5582ba42c6c0fb87d/packages/%40uppy/companion/src/server/helpers/request.js#L14
  58. const ipv4s = [
  59. '0.0.0.0',
  60. '0.0.0.1',
  61. '127.0.0.1',
  62. '127.16.0.1',
  63. '192.168.1.1',
  64. '169.254.1.1',
  65. '10.0.0.1',
  66. ]
  67. const ipv6s = [
  68. 'fd80::1234:5678:abcd:0123',
  69. 'fe80::1234:5678:abcd:0123',
  70. 'ff00::1234',
  71. '::ffff:192.168.1.10',
  72. '::1',
  73. '0:0:0:0:0:0:0:1',
  74. 'fda1:3f9f:dbf7::1c8d',
  75. ]
  76. for (const ip of ipv4s) {
  77. const url = `http://${ip}:8090`
  78. const promise = getProtectedGot({ url, blockLocalIPs: true }).get(url)
  79. await expect(promise).rejects.toThrow(new Error(FORBIDDEN_IP_ADDRESS))
  80. }
  81. for (const ip of ipv6s) {
  82. const url = `http://[${ip}]:8090`
  83. const promise = getProtectedGot({ url, blockLocalIPs: true }).get(url)
  84. await expect(promise).rejects.toThrow(new Error(FORBIDDEN_IP_ADDRESS))
  85. }
  86. })
  87. })