Chuangyu Blockchain: Security Research between Traditional Security and IPFS
创宇区块链安全实验室
2022-05-25 14:03
本文约4459字,阅读全文需要约18分钟
How does Web3, built on blockchain technology, guarantee the privacy and security of users through IPFS?

foreword

foreword

Communication technology has made the world more connected, and each of us is affected and benefited by such connections. At the same time, this connection also produces more convenience for monitoring needs. The privacy or liberty of many people may be inadvertently compromised, and this creates a need for privacy protection. Usually, due to the existence of centralized servers, it is difficult for us to achieve complete privacy protection, but technologies such as distributed storage make it possible.

Knowing that Chuangyu Blockchain Security Lab will explain this in detail.

first level title

Web-interface and IPFS

1. What is Web-interface

In Web3.0, distributed public chain technology facilities provide various interfaces for users to call, but these interfaces cannot be directly used by ordinary users. For the user, the Web-interface is a bridge between the user and the software running on the Web server. Users use a browser to connect to the Web-interface for display and interaction, and at the same time identify themselves through the wallet. For the underlying blockchain infrastructure, the Web-interface is a layer of encapsulation of the public chain/smart contract, which is packaged into a friendly page that can be directly available to users. Its structure and function are similar to the following picture:

2. What is IPFS

The Interplanetary File System (IPFS) is a network transmission protocol for distributed storage and shared files. It combines the existing successful system distributed hash table, version control system Git, BitTorrent, self-certified file system and blockchain. It is the comprehensive advantages of these systems that bring the following notable features to IPFS:

1. Permanent, decentralized storage and sharing of files

2. Peer-to-peer hypermedia: P2P saves various types of data

3. Versioning: traceable file modification history

4. Content addressable: identify the file by generating an independent hash value from the file content, rather than by the location where the file is saved

When a user adds a file to IPFS, the file is broken into smaller chunks, cryptographically hashed and given a content identifier (CID) as a unique fingerprint; when other nodes look for the file, the node asks the peers Whoever stores the content referenced by the file's CID, when viewing and downloading the file, will have a cached copy -- and become another provider of that content -- until their cache is cleared.

IPFS usage exampleshttps://ipfs.iowebsite

Provide a client with a UI interface. After installation and operation, the IPFS service will be started, and the current node ID, gateway and API address will be displayed:

We import the file we want to upload. After uploading the file successfully, the CID information of the file will be generated. We can also find the specified file through QmHash (CID):

Since IPFS is a network transmission protocol for distributed storage and shared files, after a successfully uploaded file is copied to other nodes, even if our local node actively deletes it, the file can still be queried on the IPFS network:

Traditional Security Issues in IPFS

According to the usage examples, we know that IPFS allows uploading any type of file. Due to the feature of allowing web access to download files, attackers can use HTML or SVG files to achieve phishing just like traditional security:https://IPFS.ioby

Take the gateway as an example. Upload a Metamask phishing website. Since the file is stored in a trusted domain name, the attack is likely to be successful when the victim accesses the file:

However, because IPFS can only query files through CID, the use of phishing attacks is very narrow, and there is no way to carry out targeted attacks. Since CID is the key to launching targeted attacks, let's go back and study CID.

IPLD is the data layer for building IPFS. It defines three data types: Merkle-Links, Merkle-DAG and Merkle-Paths. The data sent by IPLD to IPFS is stored on the chain, and the user will receive a CID to access the data.

`CID::=`

CID is a string composed of Version, Codec and Multihash, currently divided into two versions, V0 and V1. The V0 version uses Base58 encoding to generate the CID, and the V1 version includes the number type Codec indicating the content, the hash algorithm MhType and the hash length MhLength:

package main

import (

"fmt"

mc "github.com/multiformats/go-multicodec"

mh "github.com/multiformats/go-multihash"

cid "github.com/ipfs/go-cid"

)

const (

File = "./go.sum"

)

func main() {

pref := cid.Prefix{

Version:  0,

Codec:    mc.Raw,

MhType:   mh.Base58,

MhLength: -1,

}

c, err := pref.Sum([]byte("CIDTest"))

if err != nil {...}

fmt.Println("CID: ", c)

}

We generate a set of CID tests with go-cid:

type AddEvent struct {

Name  string

Hash  string `json:",omitempty"`

Bytes int64  `json:",omitempty"`

Size  string `json:",omitempty"`

}

const (

quietOptionName       = "quiet"

quieterOptionName     = "quieter"

silentOptionName      = "silent"

progressOptionName    = "progress"

trickleOptionName     = "trickle"

wrapOptionName        = "wrap-with-directory"

onlyHashOptionName    = "only-hash"

chunkerOptionName     = "chunker"

pinOptionName         = "pin"

rawLeavesOptionName   = "raw-leaves"

noCopyOptionName      = "nocopy"

fstoreCacheOptionName = "fscache"

cidVersionOptionName  = "cid-version"

hashOptionName        = "hash"

inlineOptionName      = "inline"

inlineLimitOptionName = "inline-limit"

)

It can be seen that in the process of generating CID, the prediction and replacement of the result cannot be realized. Let's analyze the part of uploading files. The process of uploading files to IPFS and saving them to the local blockstore by means of blocks is located at /go-ipfs-master/core/commands/add.go:

func (adder *Adder) AddAllAndPin(ctx context.Context, file files.Node) (ipld.Node, error) {

ctx, span := tracing.Span(ctx, "CoreUnix.Adder", "AddAllAndPin")

defer span.End()

Save the uploaded file information into the AddEvent object, and then traverse the file path through the addALLAndPin and fileAdder.AddFile methods in /go-ipfs-master/core/coreunix/add.go, read the file content, and send the data into the block:

adder.unlocker = adder.gcLocker.PinLock(ctx)

}

defer func() {

if adder.unlocker != nil {

adder.unlocker.Unlock(ctx)

}

}()

if err := adder.addFileNode(ctx, "", file, true); err != nil {

return nil, err

}

mr, err := adder.mfsRoot()

if err != nil {

return nil, err

}

var root mfs.FSNode

if adder.Pin {//knownsec if it is locked

root = rootdir

err = root.Flush()

if err != nil {

return nil, err

}

_, dir := file.(files.Directory)

var name string

if !dir {

children,rootdir := mr.GetDirectory()//knownsec get path

if err != nil {

return nil, err

}

if len(children) == 0 {

return nil, fmt.Errorf("expected at least one child dir, got none")

}

name = children[0]

root, err = rootdir.Child(name)

if err != nil {

return nil, err

}

}

err = mr.Close()

if err != nil {

return nil, err

}

nd, err := root.GetNode()

if err != nil {

return nil, err

}

err = adder.outputDirs(name, root)

if err != nil {

return nil, err

}

if asyncDagService, ok := adder.dagService.(syncer); ok {

err = asyncDagService.Sync()

if err != nil {

return nil, err

}

}

if !adder.Pin {

return nd, nil

}

return nd, adder.PinRoot(ctx, nd)

}

err := rootdir.ListNames(adder.ctx)//knownsec display current path file name

func (adder *Adder) addFile(path string, file files.File) error {

var reader io.Reader = file

if adder.Progress {

rdr := &progressReader{file: reader, path: path,Finally, use the addFile function to upload the file:

if fi, ok := file.(files.FileInfo); ok {

reader = &progressReader2{rdr, fi}

} else {

reader = rdr

}

}

dagnode,out: adder.Out}//knonwsec read file by byte

if err != nil {

return err

}

return adder.addNode(dagnode, path)

}

Analyzing the code, it is found that IPFS has no possibility of hijacking during the entire process of uploading and returning the CID of the packaged file, and the successfully uploaded file cannot be modified or tampered with:

postscript

postscript

创宇区块链安全实验室
作者文库