mirror of
https://github.com/gogs/gogs.git
synced 2026-02-28 09:10:57 +01:00
Compare commits
5 Commits
v0.12.4-rc
...
v0.12.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e309bc8324 | ||
|
|
64102be2c9 | ||
|
|
91f2cde5e9 | ||
|
|
b3541030c3 | ||
|
|
bc8b8c3767 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -16,3 +16,4 @@ output*
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
/release
|
||||
.task
|
||||
|
||||
91
Taskfile.yml
Normal file
91
Taskfile.yml
Normal file
@@ -0,0 +1,91 @@
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
BINARY_EXT:
|
||||
sh: echo '{{if eq OS "windows"}}.exe{{end}}'
|
||||
|
||||
tasks:
|
||||
web:
|
||||
desc: Build the binary and start the web server.
|
||||
deps: [build]
|
||||
cmds:
|
||||
- ./gogs web
|
||||
|
||||
build:
|
||||
desc: Build the binary.
|
||||
cmds:
|
||||
- go build -v
|
||||
-ldflags '
|
||||
-X "{{.PKG_PATH}}.BuildTime={{.BUILD_TIME}}"
|
||||
-X "{{.PKG_PATH}}.BuildCommit={{.BUILD_COMMIT}}"
|
||||
'
|
||||
-tags '{{.TAGS}}'
|
||||
-trimpath -o gogs{{.BINARY_EXT}}
|
||||
vars:
|
||||
PKG_PATH: gogs.io/gogs/internal/conf
|
||||
BUILD_TIME:
|
||||
sh: date -u '+%Y-%m-%d %I:%M:%S %Z'
|
||||
BUILD_COMMIT:
|
||||
sh: git rev-parse HEAD
|
||||
sources:
|
||||
- gogs.go
|
||||
- internal/**/*.go
|
||||
|
||||
generate-bindata:
|
||||
desc: Generate bindata for all assets.
|
||||
deps: [clean]
|
||||
cmds:
|
||||
- go generate internal/assets/conf/conf.go
|
||||
- go generate internal/assets/templates/templates.go
|
||||
- go generate internal/assets/public/public.go
|
||||
|
||||
generate-schemadoc:
|
||||
desc: Generate database schema documentation.
|
||||
cmds:
|
||||
- go generate ./internal/db/schemadoc
|
||||
|
||||
generate:
|
||||
desc: Run all go:generate commands.
|
||||
deps: [generate-bindata, generate-schemadoc]
|
||||
|
||||
test:
|
||||
desc: Run all tests.
|
||||
cmds:
|
||||
- go test -cover -race ./...
|
||||
|
||||
clean:
|
||||
desc: Cleans up system meta files for code generation.
|
||||
cmds:
|
||||
- find . -name "*.DS_Store" -type f -delete
|
||||
|
||||
release:
|
||||
desc: Build the binary and pack resources to a ZIP file.
|
||||
deps: [build]
|
||||
cmds:
|
||||
- rm -rf {{.RELEASE_GOGS}}
|
||||
- mkdir -p {{.RELEASE_GOGS}}
|
||||
- cp -r gogs{{.BINARY_EXT}} LICENSE README.md README_ZH.md scripts {{.RELEASE_GOGS}}
|
||||
- cd {{.RELEASE_ROOT}} && zip -r gogs.$(NOW).zip "gogs"
|
||||
vars:
|
||||
RELEASE_ROOT: release
|
||||
RELEASE_GOGS: release/gogs
|
||||
|
||||
less:
|
||||
desc: Generate CSS from LESS files.
|
||||
cmds:
|
||||
- lessc --clean-css --source-map "public/less/gogs.less" public/css/gogs.min.css
|
||||
|
||||
fixme:
|
||||
desc: Show all occurrences of "FIXME".
|
||||
cmds:
|
||||
- grep -rnw "FIXME" internal
|
||||
|
||||
todo:
|
||||
desc: Show all occurrences of "TODO".
|
||||
cmds:
|
||||
- grep -rnw "TODO" internal
|
||||
|
||||
legacy:
|
||||
desc: Identify legacy and deprecated lines.
|
||||
cmds:
|
||||
- grep -rnw "\(LEGACY\|Deprecated\)" internal
|
||||
2
gogs.go
2
gogs.go
@@ -19,7 +19,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
conf.App.Version = "0.12.4"
|
||||
conf.App.Version = "0.12.5"
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -27,9 +27,9 @@ func PAMAuth(serviceName, userName, passwd string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = t.Authenticate(0); err != nil {
|
||||
err = t.Authenticate(0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return t.AcctMgmt(0)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"gopkg.in/macaron.v1"
|
||||
|
||||
"gogs.io/gogs/internal/db"
|
||||
"gogs.io/gogs/internal/netutil"
|
||||
)
|
||||
|
||||
// _______________________________________ _________.______________________ _______________.___.
|
||||
@@ -67,6 +68,11 @@ func (f MigrateRepo) ParseRemoteAddr(user *db.User) (string, error) {
|
||||
if err != nil {
|
||||
return "", db.ErrInvalidCloneAddr{IsURLError: true}
|
||||
}
|
||||
|
||||
if netutil.IsLocalHostname(u.Hostname()) {
|
||||
return "", db.ErrInvalidCloneAddr{IsURLError: true}
|
||||
}
|
||||
|
||||
if len(f.AuthUsername)+len(f.AuthPassword) > 0 {
|
||||
u.User = url.UserPassword(f.AuthUsername, f.AuthPassword)
|
||||
}
|
||||
|
||||
64
internal/netutil/netutil.go
Normal file
64
internal/netutil/netutil.go
Normal file
@@ -0,0 +1,64 @@
|
||||
// Copyright 2022 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package netutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
var localCIDRs []*net.IPNet
|
||||
|
||||
func init() {
|
||||
// Parsing hardcoded CIDR strings should never fail, if in case it does, let's
|
||||
// fail it at start.
|
||||
rawCIDRs := []string{
|
||||
// https://datatracker.ietf.org/doc/html/rfc5735:
|
||||
"127.0.0.0/8", // Loopback
|
||||
"0.0.0.0/8", // "This" network
|
||||
"100.64.0.0/10", // Shared address space
|
||||
"169.254.0.0/16", // Link local
|
||||
"172.16.0.0/12", // Private-use networks
|
||||
"192.0.0.0/24", // IETF Protocol assignments
|
||||
"192.0.2.0/24", // TEST-NET-1
|
||||
"192.88.99.0/24", // 6to4 Relay anycast
|
||||
"192.168.0.0/16", // Private-use networks
|
||||
"198.18.0.0/15", // Network interconnect
|
||||
"198.51.100.0/24", // TEST-NET-2
|
||||
"203.0.113.0/24", // TEST-NET-3
|
||||
"255.255.255.255/32", // Limited broadcast
|
||||
|
||||
// https://datatracker.ietf.org/doc/html/rfc1918:
|
||||
"10.0.0.0/8", // Private-use networks
|
||||
|
||||
// https://datatracker.ietf.org/doc/html/rfc6890:
|
||||
"::1/128", // Loopback
|
||||
"FC00::/7", // Unique local address
|
||||
"FE80::/10", // Multicast address
|
||||
}
|
||||
for _, raw := range rawCIDRs {
|
||||
_, cidr, err := net.ParseCIDR(raw)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("parse CIDR %q: %v", raw, err))
|
||||
}
|
||||
localCIDRs = append(localCIDRs, cidr)
|
||||
}
|
||||
}
|
||||
|
||||
// IsLocalHostname returns true if given hostname is a known local address.
|
||||
func IsLocalHostname(hostname string) bool {
|
||||
ips, err := net.LookupIP(hostname)
|
||||
if err != nil {
|
||||
return true
|
||||
}
|
||||
for _, ip := range ips {
|
||||
for _, cidr := range localCIDRs {
|
||||
if cidr.Contains(ip) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
36
internal/netutil/netutil_test.go
Normal file
36
internal/netutil/netutil_test.go
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright 2022 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package netutil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIsLocalHostname(t *testing.T) {
|
||||
tests := []struct {
|
||||
hostname string
|
||||
want bool
|
||||
}{
|
||||
{hostname: "localhost", want: true},
|
||||
{hostname: "127.0.0.1", want: true},
|
||||
{hostname: "::1", want: true},
|
||||
{hostname: "0:0:0:0:0:0:0:1", want: true},
|
||||
{hostname: "fuf.me", want: true},
|
||||
{hostname: "127.0.0.95", want: true},
|
||||
{hostname: "0.0.0.0", want: true},
|
||||
{hostname: "192.168.123.45", want: true},
|
||||
|
||||
{hostname: "gogs.io", want: false},
|
||||
{hostname: "google.com", want: false},
|
||||
{hostname: "165.232.140.255", want: false},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run("", func(t *testing.T) {
|
||||
assert.Equal(t, test.want, IsLocalHostname(test.hostname))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"gogs.io/gogs/internal/db"
|
||||
"gogs.io/gogs/internal/db/errors"
|
||||
"gogs.io/gogs/internal/form"
|
||||
"gogs.io/gogs/internal/netutil"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -118,24 +119,7 @@ func WebhooksNew(c *context.Context, orCtx *orgRepoContext) {
|
||||
c.Success(orCtx.TmplNew)
|
||||
}
|
||||
|
||||
var localHostnames = []string{
|
||||
"localhost",
|
||||
"127.0.0.1",
|
||||
"::1",
|
||||
"0:0:0:0:0:0:0:1",
|
||||
}
|
||||
|
||||
// isLocalHostname returns true if given hostname is a known local address.
|
||||
func isLocalHostname(hostname string) bool {
|
||||
for _, local := range localHostnames {
|
||||
if hostname == local {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func validateWebhook(actor *db.User, l macaron.Locale, w *db.Webhook) (field string, msg string, ok bool) {
|
||||
func validateWebhook(actor *db.User, l macaron.Locale, w *db.Webhook) (field, msg string, ok bool) {
|
||||
if !actor.IsAdmin {
|
||||
// 🚨 SECURITY: Local addresses must not be allowed by non-admins to prevent SSRF,
|
||||
// see https://github.com/gogs/gogs/issues/5366 for details.
|
||||
@@ -144,7 +128,7 @@ func validateWebhook(actor *db.User, l macaron.Locale, w *db.Webhook) (field str
|
||||
return "PayloadURL", l.Tr("repo.settings.webhook.err_cannot_parse_payload_url", err), false
|
||||
}
|
||||
|
||||
if isLocalHostname(payloadURL.Hostname()) {
|
||||
if netutil.IsLocalHostname(payloadURL.Hostname()) {
|
||||
return "PayloadURL", l.Tr("repo.settings.webhook.err_cannot_use_local_addresses"), false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,25 +13,6 @@ import (
|
||||
"gogs.io/gogs/internal/mocks"
|
||||
)
|
||||
|
||||
func Test_isLocalHostname(t *testing.T) {
|
||||
tests := []struct {
|
||||
hostname string
|
||||
want bool
|
||||
}{
|
||||
{hostname: "localhost", want: true},
|
||||
{hostname: "127.0.0.1", want: true},
|
||||
{hostname: "::1", want: true},
|
||||
{hostname: "0:0:0:0:0:0:0:1", want: true},
|
||||
|
||||
{hostname: "gogs.io", want: false},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run("", func(t *testing.T) {
|
||||
assert.Equal(t, test.want, isLocalHostname(test.hostname))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_validateWebhook(t *testing.T) {
|
||||
l := &mocks.Locale{
|
||||
MockLang: "en",
|
||||
|
||||
Reference in New Issue
Block a user