@@ -676,9 +676,35 @@ private byte[] retrieve(String path) throws IOException {
676676 }
677677
678678 private static byte [] get (URL target , int timeout ) throws IOException {
679- HttpURLConnection conn = configureConnection (target , "GET" , timeout );
679+ HttpURLConnection conn = configureConnection (target , "POST" , timeout );
680+ conn .setDoOutput (true );
681+ /* See IFFS commit for why this is a POST and not a GET https://github.com/ipfs/go-ipfs/pull/7097
682+ This commit upgrades go-ipfs-cmds and configures the commands HTTP API Handler
683+ to only allow POST/OPTIONS, disallowing GET and others in the handling of
684+ command requests in the IPFS HTTP API (where before every type of request
685+ method was handled, with GET/POST/PUT/PATCH being equivalent).
686+
687+ The Read-Only commands that the HTTP API attaches to the gateway endpoint will
688+ additional handled GET as they did before (but stop handling PUT,DELETEs).
689+
690+ By limiting the request types we address the possibility that a website
691+ accessed by a browser abuses the IPFS API by issuing GET requests to it which
692+ have no Origin or Referrer set, and are thus bypass CORS and CSRF protections.
693+
694+ This is a breaking change for clients that relay on GET requests against the
695+ HTTP endpoint (usually :5001). Applications integrating on top of the
696+ gateway-read-only API should still work (including cross-domain access).
697+ */
698+ conn .setRequestMethod ("POST" );
699+ conn .setRequestProperty ("Content-Type" , "application/json" );
700+ conn .setConnectTimeout (10_000 );
701+ conn .setReadTimeout (60_000 );
680702
681703 try {
704+ OutputStream out = conn .getOutputStream ();
705+ out .write (new byte [0 ]);
706+ out .flush ();
707+ out .close ();
682708 InputStream in = conn .getInputStream ();
683709 ByteArrayOutputStream resp = new ByteArrayOutputStream ();
684710
@@ -689,13 +715,10 @@ private static byte[] get(URL target, int timeout) throws IOException {
689715 return resp .toByteArray ();
690716 } catch (ConnectException e ) {
691717 throw new RuntimeException ("Couldn't connect to IPFS daemon at " +target +"\n Is IPFS running?" );
692- } catch (SocketTimeoutException e ) {
693- throw new RuntimeException (String .format ("timeout (%d ms) has been exceeded" , timeout ));
694718 } catch (IOException e ) {
695- String err = Optional .ofNullable (conn .getErrorStream ())
696- .map (s ->new String (readFully (s )))
697- .orElse (e .getMessage ());
698- throw new RuntimeException ("IOException contacting IPFS daemon.\n Trailer: " + conn .getHeaderFields ().get ("Trailer" ) + " " + err , e );
719+ InputStream errorStream = conn .getErrorStream ();
720+ String err = errorStream == null ? e .getMessage () : new String (readFully (errorStream ));
721+ throw new RuntimeException ("IOException contacting IPFS daemon.\n " +err +"\n Trailer: " + conn .getHeaderFields ().get ("Trailer" ), e );
699722 }
700723 }
701724
0 commit comments