Compare commits

...

21 Commits

Author SHA1 Message Date
Joe Chen
d06ba7e527 ci: mirror lint config from main 2022-05-05 16:18:01 +08:00
Joe Chen
b0a902dcca release: update version to 0.12.7 2022-05-05 16:10:55 +08:00
Joe Chen
bc77440b30 attachment: set CSP header in the serving endpoint (#6926) 2022-05-05 16:01:44 +08:00
Joe Chen
2a8f561c64 mod: update golang.org/x/crypto/ssh (#6884)
# Conflicts:
#	go.mod
#	go.sum
2022-04-06 21:34:26 +08:00
E99p1ant
8a046c22a8 context: fix Access-Control-Allow-Credentials header typo (#6381) 2022-04-06 21:30:38 +08:00
Joe Chen
26395294bd go mod tidy 2022-03-19 14:39:55 +08:00
Joe Chen
c91365774b Fix tests 2022-03-19 14:34:43 +08:00
Joe Chen
dff067ac28 ci: add go 1.18.x 2022-03-19 14:29:05 +08:00
Joe Chen
45fdfecf64 Disable flaky generated files check 2022-03-19 14:28:24 +08:00
Joe Chen
1bf5d89386 run task generate 2022-03-19 14:08:46 +08:00
Joe Chen
670cbccf98 release: update version to 0.12.3 2022-03-19 14:07:09 +08:00
Joe Chen
4e10265568 chore: run task generate (#6844)
# Conflicts:
#	.github/workflows/go.yml
#	internal/assets/templates/templates_gen.go
2022-03-15 22:44:47 +08:00
tc608
640e2f62e0 templates: fetch fixed size of members' avatar (#5755)
Co-authored-by: Joe Chen <jc@unknwon.io>
2022-03-15 22:43:11 +08:00
Joe Chen
eddae31ada conf: add allowlist for accessing local network (#6842)
# Conflicts:
#	CHANGELOG.md
#	internal/assets/conf/conf_gen.go
#	internal/assets/templates/templates_gen.go
#	internal/conf/static.go
#	internal/conf/testdata/TestInit.golden.ini
2022-03-14 23:54:23 +08:00
Joe Chen
0fef3c9082 repo_editor: check upload TreePath and file name (#6838) 2022-03-14 00:37:34 +08:00
Bo Lorentsen
5aca56d2dd docker: check "/data" mount ownership before forcing it (#6553)
Co-authored-by: bl <bl@moch.dk>
2022-03-13 21:44:43 +08:00
Joe Chen
e309bc8324 release: update version to 0.12.5 2022-03-11 14:58:57 +08:00
ysf
64102be2c9 security: fix improper PAM authorization handling (#6819)
Co-authored-by: Joe Chen <jc@unknwon.io>
# Conflicts:
#	CHANGELOG.md
#	internal/auth/pam/pam.go
2022-03-11 14:52:11 +08:00
Michael Rowley
91f2cde5e9 security: fix SSRF in repository migration (#6812)
Co-authored-by: Joe Chen <jc@unknwon.io>
# Conflicts:
#	CHANGELOG.md
#	internal/route/repo/webhook.go
2022-03-11 14:51:32 +08:00
Joe Chen
b3541030c3 Update Taskfile for Windows 2022-01-18 00:23:27 +08:00
Joe Chen
bc8b8c3767 Add Taskfile 2022-01-17 21:38:13 +08:00
27 changed files with 5351 additions and 5124 deletions

View File

@@ -30,12 +30,30 @@ jobs:
with:
version: latest
args: --timeout=30m
- name: Install Task
uses: arduino/setup-task@v1
- name: Install go-bindata
shell: bash
run: |
curl --silent --location --output /usr/local/bin/go-bindata https://github.com/kevinburke/go-bindata/releases/download/v3.23.0/go-bindata-linux-amd64
chmod +x /usr/local/bin/go-bindata
- name: Check Go module tidiness
shell: bash
run: |
go mod tidy
STATUS=$(git status --porcelain)
if [ ! -z "$STATUS" ]; then
echo "Unstaged files:"
echo $STATUS
echo "Run 'go mod tidy' and commit them"
exit 1
fi
test:
name: Test
strategy:
matrix:
go-version: [ 1.14.x, 1.15.x, 1.16.x, 1.17.x ]
go-version: [ 1.14.x, 1.15.x, 1.16.x, 1.17.x, 1.18.x ]
platform: [ ubuntu-latest, macos-latest, windows-latest ]
runs-on: ${{ matrix.platform }}
steps:

1
.gitignore vendored
View File

@@ -16,3 +16,4 @@ output*
*.sublime-project
*.sublime-workspace
/release
.task

View File

@@ -1,4 +1,9 @@
linters-settings:
staticcheck:
checks: [
"all",
"-SA1019" # There are valid use cases of strings.Title
]
nakedret:
max-func-lines: 0 # Disallow any unnamed return statement

91
Taskfile.yml Normal file
View 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

View File

@@ -169,6 +169,8 @@ COOKIE_SECURE = false
ENABLE_LOGIN_STATUS_COOKIE = false
; The cookie name to store user login status.
LOGIN_STATUS_COOKIE_NAME = login_status
; A comma separated list of hostnames that are explicitly allowed to be accessed within the local network.
LOCAL_NETWORK_ALLOWLIST =
[email]
; Whether to enable the email service.

View File

@@ -1242,6 +1242,7 @@ config.security.cookie_secure = Enable secure cookie
config.security.reverse_proxy_auth_user = Reverse proxy authentication header
config.security.enable_login_status_cookie = Enable login status cookie
config.security.login_status_cookie_name = Login status cookie
config.security.local_network_allowlist = Local network allowlist
config.email_config = Email configuration
config.email.enabled = Enabled

View File

@@ -31,8 +31,12 @@ cleanup() {
}
create_volume_subfolder() {
# Modify the owner of /data dir, make $USER(git) user have permission to create sub-dir in /data.
chown -R "$USER:$USER" /data
# only change ownership if needed, if using an nfs mount this could be expensive
if [ "$USER:$USER" != "$(stat /data -c '%U:%G')" ]
then
# Modify the owner of /data dir, make $USER(git) user have permission to create sub-dir in /data.
chown -R "$USER:$USER" /data
fi
# Create VOLUME subfolder
for f in /data/gogs/data /data/gogs/conf /data/gogs/log /data/git /data/ssh; do

View File

@@ -153,6 +153,8 @@ You would have to re-run this command after changing Go files, or any file under
When you are actively working on HTML templates and static files during development, you may want to enable the following configuration to avoid recompiling and restarting Gogs every time you make a change to files under `template/` and `public/` directories:
```ini
RUN_MODE = dev
[server]
LOAD_ASSETS_FROM_DISK = true
```

8
go.mod
View File

@@ -28,7 +28,7 @@ require (
github.com/issue9/identicon v1.0.1
github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43
github.com/jinzhu/gorm v1.9.12
github.com/json-iterator/go v1.1.10
github.com/json-iterator/go v1.1.12
github.com/klauspost/compress v1.8.6 // indirect
github.com/klauspost/cpuid v1.2.1 // indirect
github.com/lib/pq v1.3.0 // indirect
@@ -56,10 +56,10 @@ require (
github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6
github.com/unknwon/paginater v0.0.0-20170405233947-45e5d631308e
github.com/urfave/cli v1.22.4
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975
golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
golang.org/x/text v0.3.3
golang.org/x/text v0.3.6
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df

24
go.sum
View File

@@ -151,8 +151,8 @@ github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
@@ -202,8 +202,9 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/msteinert/pam v0.0.0-20190215180659-f29b9f28d6f9 h1:ZivaaKmjs9q90zi6I4gTLW6tbVGtlBjellr3hMYaly0=
github.com/msteinert/pam v0.0.0-20190215180659-f29b9f28d6f9/go.mod h1:np1wUFZ6tyoke22qDJZY40URn9Ae51gX7ljIWXN5TJs=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
@@ -309,8 +310,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 h1:tkVvjkPTB7pnW3jnid7kNyAMPVWllTNOf/qKDze4p9o=
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -331,8 +332,8 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 h1:p9xBe/w/OzkeYVKm234g55gMdD1nSIooTir5kV11kfA=
golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -358,13 +359,18 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View File

@@ -19,7 +19,7 @@ import (
)
func init() {
conf.App.Version = "0.12.4"
conf.App.Version = "0.12.7"
}
func main() {

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -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)
}

View File

@@ -314,6 +314,7 @@ func runWeb(c *cli.Context) error {
}
defer fr.Close()
c.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; sandbox")
c.Header().Set("Cache-Control", "public,max-age=86400")
c.Header().Set("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, attach.Name))

View File

@@ -103,6 +103,7 @@ var (
CookieSecure bool
EnableLoginStatusCookie bool
LoginStatusCookieName string
LocalNetworkAllowlist []string `delim:","`
// Deprecated: Use Auth.ReverseProxyAuthenticationHeader instead, will be removed in 0.13.
ReverseProxyAuthenticationUser string

View File

@@ -80,6 +80,7 @@ COOKIE_USERNAME=gogs_awesome
COOKIE_SECURE=false
ENABLE_LOGIN_STATUS_COOKIE=false
LOGIN_STATUS_COOKIE_NAME=login_status
LOCAL_NETWORK_ALLOWLIST=
REVERSE_PROXY_AUTHENTICATION_USER=
[email]

View File

@@ -249,7 +249,7 @@ func Contexter() macaron.Handler {
if len(conf.HTTP.AccessControlAllowOrigin) > 0 {
c.Header().Set("Access-Control-Allow-Origin", conf.HTTP.AccessControlAllowOrigin)
c.Header().Set("'Access-Control-Allow-Credentials' ", "true")
c.Header().Set("Access-Control-Allow-Credentials", "true")
c.Header().Set("Access-Control-Max-Age", "3600")
c.Header().Set("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With")
}

View File

@@ -16,6 +16,7 @@ import (
"strings"
"time"
"github.com/pkg/errors"
gouuid "github.com/satori/go.uuid"
"github.com/unknwon/com"
@@ -23,9 +24,10 @@ import (
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/cryptoutil"
"gogs.io/gogs/internal/db/errors"
dberrors "gogs.io/gogs/internal/db/errors"
"gogs.io/gogs/internal/gitutil"
"gogs.io/gogs/internal/osutil"
"gogs.io/gogs/internal/pathutil"
"gogs.io/gogs/internal/process"
"gogs.io/gogs/internal/tool"
)
@@ -134,7 +136,7 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (
if opts.OldBranch != opts.NewBranch {
// Directly return error if new branch already exists in the server
if git.RepoHasBranch(repoPath, opts.NewBranch) {
return errors.BranchAlreadyExists{Name: opts.NewBranch}
return dberrors.BranchAlreadyExists{Name: opts.NewBranch}
}
// Otherwise, delete branch from local copy in case out of sync
@@ -449,11 +451,16 @@ func isRepositoryGitPath(path string) bool {
return strings.HasSuffix(path, ".git") || strings.Contains(path, ".git"+string(os.PathSeparator))
}
func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions) (err error) {
func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions) error {
if len(opts.Files) == 0 {
return nil
}
// Prevent uploading files into the ".git" directory
if isRepositoryGitPath(opts.TreePath) {
return errors.Errorf("bad tree path %q", opts.TreePath)
}
uploads, err := GetUploadsByUUIDs(opts.Files)
if err != nil {
return fmt.Errorf("get uploads by UUIDs[%v]: %v", opts.Files, err)
@@ -487,7 +494,9 @@ func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions)
continue
}
// Prevent copying files into .git directory, see https://gogs.io/gogs/issues/5558.
upload.Name = pathutil.Clean(upload.Name)
// Prevent uploading files into the ".git" directory
if isRepositoryGitPath(upload.Name) {
continue
}

View File

@@ -12,7 +12,9 @@ import (
"github.com/unknwon/com"
"gopkg.in/macaron.v1"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/db"
"gogs.io/gogs/internal/netutil"
)
// _______________________________________ _________.______________________ _______________.___.
@@ -67,6 +69,11 @@ func (f MigrateRepo) ParseRemoteAddr(user *db.User) (string, error) {
if err != nil {
return "", db.ErrInvalidCloneAddr{IsURLError: true}
}
if netutil.IsLocalHostname(u.Hostname(), conf.Security.LocalNetworkAllowlist) {
return "", db.ErrInvalidCloneAddr{IsURLError: true}
}
if len(f.AuthUsername)+len(f.AuthPassword) > 0 {
u.User = url.UserPassword(f.AuthUsername, f.AuthPassword)
}

View File

@@ -0,0 +1,71 @@
// 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 resolved to local network
// address, except exempted from the allowlist.
func IsLocalHostname(hostname string, allowlist []string) bool {
for _, allow := range allowlist {
if hostname == allow {
return false
}
}
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
}

View File

@@ -0,0 +1,40 @@
// 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
allowlist []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},
{hostname: "192.168.123.45", allowlist: []string{"10.0.0.17"}, want: true},
{hostname: "gogs.local", allowlist: []string{"gogs.local"}, want: false},
}
for _, test := range tests {
t.Run("", func(t *testing.T) {
assert.Equal(t, test.want, IsLocalHostname(test.hostname, test.allowlist))
})
}
}

View File

@@ -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(), conf.Security.LocalNetworkAllowlist) {
return "PayloadURL", l.Tr("repo.settings.webhook.err_cannot_use_local_addresses"), false
}
}

View File

@@ -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",

View File

@@ -206,6 +206,8 @@
<dd><i class="fa fa{{if .Security.EnableLoginStatusCookie}}-check{{end}}-square-o"></i></dd>
<dt>{{.i18n.Tr "admin.config.security.login_status_cookie_name"}}</dt>
<dd>{{.Security.LoginStatusCookieName}}</dd>
<dt>{{.i18n.Tr "admin.config.security.local_network_allowlist"}}</dt>
<dd><code>{{.Security.LocalNetworkAllowlist}}</code></dd>
</dl>
</div>

View File

@@ -14,7 +14,7 @@
{{range .Members}}
<div class="item ui grid">
<div class="ui one wide column">
<img class="ui avatar" src="{{.RelAvatarLink}}?s=48">
<img class="ui avatar" src="{{AppendAvatarSize .RelAvatarLink 48}}">
</div>
<div class="ui three wide column">
<div class="meta"><a href="{{.HomeLink}}">{{.Name}}</a></div>