Git Product home page Git Product logo

clj-http-ssrf's Introduction

clj-http-ssrf Build Status Clojars Project

A clj-http middleware designed to prevent SSRF attacks

Leiningen

[xtreak/clj-http-ssrf "0.2.2"]

Docs

Documentation is generated by Codox and it's available at https://tirkarthi.github.io/clj-http-ssrf

Rationale

Since many web applications accept URLs to which some payload will be posted from the app like webhook integrations there is a possibility that the URL might be an internal URL.

E.g. On notification a payload {"success": true} will be posted to some Webhook URL so that the integrated application will consume the payload. But in some cases malicious users might enter private URLs of the app that can be accessed only from the app subnet. Since HTTP requests from the apps pass the subnet checks the app might end up posting a payload to it's own private endpoint. In the above case when the URL is given as http://private.app.com/private/secret/url/ then the payload will be passed to that endpoint which might cause some unforseen actions.

clj-http enables building custom middlewares so that we can effectively block the request from being made. We can return custom status like 404 instead of 403 so that the attacker might think the URL doesn't exist reducing the attack vector.

Usage

foo.core> (require '[clj-http-ssrf.core :refer :all])
foo.core> (client/with-middleware (conj client/default-middleware (wrap-validators :hosts ["10.0.0.0/1"]))
                      (client/get "http://10.0.10.11/secret/private/endpoint/"))
{:status 403, :headers {}, :body ""}
foo.core> (client/with-middleware (conj client/default-middleware (wrap-validators :hosts ["10.0.0.0/1"] :status 404))
                      (client/get "http://10.0.10.11/secret/private/endpoint/"))
{:status 404, :headers {}, :body ""}

If you'd prefer to work with predicates,

  • Add :ignore-unknown-host as true to ignore unknown hosts instead of raising exceptions.
(ns foo.core
  (:require [clj-http.client :as client]
            [clj-http-ssrf.core :refer :all]
            [clj-http-ssrf.reserved :as reserved]))

(defn safe-scheme?
  [scheme]
  (#{:http :https} scheme))

(defn safe-url?
  [url]
  (not (some #(re-find % url) [#"private" #"secret"])))

(defn safe-host?
  [ip-address]
  (not (some #(inet.data.ip/network-contains? % ip-address)
             (reserved/reserved-ip-ranges [:private]))))

(defn safe-port?
  [port]
  (#{80 443} port))

(client/with-middleware
  (conj client/default-middleware
        (wrap-predicates
         :scheme-pred safe-scheme?
         :url-pred safe-url?
         :host-pred safe-host?
         :port-pred safe-port?))
  (client/get "https://ifconfig.co" {:ignore-unknown-host true}))

Thanks

Implementation in other languages

Resources regarding SSRF

License

Copyright © 2018 Karthikeyan S

Distributed under the MIT License

clj-http-ssrf's People

Contributors

tirkarthi avatar ackerleytng avatar

Stargazers

Evgheni Kondratenko avatar Simon Skorokhodov avatar Vincent avatar Cam Saul avatar Maciej Łotysz avatar Łukasz Korecki avatar  avatar yāλu avatar

Watchers

James Cloos avatar  avatar  avatar

Forkers

ackerleytng

clj-http-ssrf's Issues

DNS rebinding attacks?

Is this middleware vulnerable to DNS rebinding attacks? Reading InetAddress docs it looks like DNS will be cached for at least long enough between the two calls (if not forever), but wondered if it would be possible to only make a single DNS call for the client and this middleware to safely handle all cases? I'm not familiar enough with clj-http to say whether this is possible or not.

`with-additional-middleware` doesn't work?

Would you happen to know why this doesn't work? I'm getting a null pointer exception. it seems as though client/get was executed on nil

(client/with-additional-middleware [(ssrf/wrap-validators :hosts ["192.168.0.0/16"] :status 404)] (client/get "http://www.google.com"))

Feature Request: Prevent Redirect SSRF

Howdy, wonder if you've considered SSRF through redirects.

For example, if we whitelist 10.x.x.x. An outbound request may ask you to redirect to Location: 10.x.x.x, this middleware doesn't protect against it.

This is more involved than middleware (you'd have to look at a custom :redirect-strategy).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.