Skip to content

Commit f144b07

Browse files
replace CSP with new default, with start/end markers for auto replacement (#984)
* replace CSP with new default, with start/end markers for auto replacement * add copy_csp_blocks action * add guard against updating chef repo when ap file didn't change --------- Co-authored-by: labkey-tchad <tchad@labkey.com>
1 parent f46d227 commit f144b07

File tree

2 files changed

+200
-14
lines changed

2 files changed

+200
-14
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
name: Copy CSP Blocks
2+
# Upon merge of a PR in which 'server/configs/application.properties' was updated...
3+
# this workflow copies the Content Security Policy blocks to other repos, as marked by:
4+
# start: "## START OF CSP COPY BLOCK" or "## START OF CSP ENFORCE BLOCK" (to only copy and uncomment the csp.enforce section)
5+
# end: "## END OF CSP COPY BLOCK" or "## END OF CSP ENFORCE BLOCK"
6+
# note: if the contents between the start/end have not changed, it's a no-op, and no PRs are pushed to the target repos
7+
8+
on:
9+
pull_request:
10+
types:
11+
- closed
12+
branches:
13+
- fb_*
14+
paths:
15+
- server/configs/application.properties
16+
17+
jobs:
18+
copy_csp:
19+
if: github.event.pull_request.merged
20+
runs-on: ubuntu-latest
21+
outputs:
22+
csp_report_on: ${{ steps.cspvars.outputs.csp_report_on }}
23+
csp_enforce_off: ${{ steps.cspvars.outputs.csp_enforce_off }}
24+
csp_enforce_on: ${{ steps.cspvars.outputs.csp_enforce_on }}
25+
steps:
26+
- name: Check Out Code
27+
uses: actions/checkout@v4
28+
with:
29+
ref: ${{ github.event.pull_request.head.ref }}
30+
31+
- name: Copy CSP blocks into vars
32+
id: cspvars
33+
run: |
34+
# report block, fixing report-uri for non-teamcity usage:
35+
CSP_REPORT_ON=$( awk '/## END OF CSP REPORT BLOCK/{p=0};p;/## START OF CSP REPORT BLOCK/{p=1}' server/configs/application.properties |\
36+
sed 's/report-uri /report-uri https:\/\/www.labkey.org/' )
37+
38+
# enforce block, fixing report-uri for non-teamcity usage, removing useLocalBuild comment, adding upgrade-insecure-requests:
39+
CSP_ENFORCE_OFF=$( awk '/## END OF CSP ENFORCE BLOCK/{p=0};p;/## START OF CSP ENFORCE BLOCK/{p=1}' server/configs/application.properties |\
40+
sed 's/^#useLocalBuild#/# /' |\
41+
sed '/base-uri/a# upgrade-insecure-requests ;\\' |\
42+
sed 's/report-uri /report-uri https:\/\/www.labkey.org/' )
43+
44+
# enforce block, uncommented:
45+
CSP_ENFORCE_ON=$( awk '/## END OF CSP ENFORCE BLOCK/{p=0};p;/## START OF CSP ENFORCE BLOCK/{p=1}' server/configs/application.properties |\
46+
sed 's/^#useLocalBuild#//' |\
47+
sed '/base-uri/a\ upgrade-insecure-requests ;\\' |\
48+
sed 's/report-uri /report-uri https:\/\/www.labkey.org/' )
49+
50+
# use unique delimiter for multiline outputs: https://stackoverflow.com/a/74256214
51+
delimiter="$(openssl rand -hex 8)"
52+
53+
echo "csp_report_on<<${delimiter}" >> "${GITHUB_OUTPUT}"
54+
echo "$CSP_REPORT_ON" >> "${GITHUB_OUTPUT}"
55+
echo "${delimiter}" >> "${GITHUB_OUTPUT}"
56+
57+
echo "csp_enforce_off<<${delimiter}" >> "${GITHUB_OUTPUT}"
58+
echo "$CSP_ENFORCE_OFF" >> "${GITHUB_OUTPUT}"
59+
echo "${delimiter}" >> "${GITHUB_OUTPUT}"
60+
61+
echo "csp_enforce_on<<${delimiter}" >> "${GITHUB_OUTPUT}"
62+
echo "$CSP_ENFORCE_ON" >> "${GITHUB_OUTPUT}"
63+
echo "${delimiter}" >> "${GITHUB_OUTPUT}"
64+
65+
paste_csp_into_chef_repo:
66+
needs: copy_csp
67+
runs-on: ubuntu-latest
68+
env:
69+
csp_report_on: ${{ needs.copy_csp.outputs.csp_report_on }}
70+
csp_enforce_off: ${{ needs.copy_csp.outputs.csp_enforce_off }}
71+
ap_file: "cookbooks/lk_appserver/templates/default/application.properties.erb"
72+
steps:
73+
- name: Check out repo
74+
uses: actions/checkout@v4
75+
with:
76+
repository: LabKey/syseng-chef-server
77+
token: ${{ secrets.TERRAFORM_TOKEN }}
78+
- name: Paste Into Chef Repo
79+
run: |
80+
printf "\n\n>>>> $ap_file before I change it: <<<<\n\n"
81+
cat $ap_file
82+
83+
printf "\n\n>>>> caught csp_report_on env var: <<<<\n$csp_report_on n\n"
84+
printf "\n\n>>>> caught csp_enforce_off env var: <<<<\n$csp_enforce_off n\n"
85+
86+
printf "\n\n>>>> replacing csp blocks in $ap_file <<<<\n\n"
87+
88+
python <<EOF
89+
import os, sys, re
90+
fname = os.environ.get('ap_file')
91+
os.rename(fname, fname + '.orig')
92+
with open(fname + '.orig', 'r') as fin, open(fname, 'w') as fout:
93+
data = fin.read()
94+
data = re.sub(r'(## START OF CSP REPORT BLOCK \\(DO NOT CHANGE THIS TEXT\\)).*?(## END OF CSP REPORT BLOCK \\(DO NOT CHANGE THIS TEXT\\))',
95+
r'\1\n' +
96+
os.environ.get('csp_report_on') +
97+
r'\n\2', data, flags=re.DOTALL)
98+
99+
data = re.sub(r'(## START OF CSP ENFORCE BLOCK \\(DO NOT CHANGE THIS TEXT\\)).*?(## END OF CSP ENFORCE BLOCK \\(DO NOT CHANGE THIS TEXT\\))',
100+
r'\1\n' +
101+
os.environ.get('csp_enforce_off') +
102+
r'\n\2', data, flags=re.DOTALL)
103+
fout.write(data)
104+
EOF
105+
106+
printf "\n\n>>>> updated $ap_file: <<<<\n\n"
107+
cat $ap_file
108+
109+
git status
110+
if [[ $(git diff-index --name-only HEAD |grep application.properties) ]]; then
111+
printf "\n\n>>>> changes detected, so updating chef recipe version <<<<\n\n"
112+
NEW_VER=$(grep version cookbooks/lk_appserver/metadata.rb |cut -d '"' -f 2 |awk -F. -v OFS=. '{$NF += 1 ; print}')
113+
sed -i 's/\(version.*\)".*"/\1"'$NEW_VER'"/' cookbooks/lk_appserver/metadata.rb
114+
sed -i 's/\(lk_appserver .*\)([0-9]*.[0-9]*.[0-9]*)/\1('$NEW_VER')/' Berksfile.lock
115+
fi
116+
117+
- name: Create Pull Request
118+
id: cpr
119+
uses: peter-evans/create-pull-request@v7
120+
with:
121+
token: ${{ secrets.TERRAFORM_TOKEN }}
122+
branch: fb_update_csp_per_${{ github.sha }}
123+
title: "update CSP to match commit ${{ github.sha }}"
124+
body: "update CSP to match commit ${{ github.sha }}"
125+
commit-message: "update CSP to match commit ${{ github.sha }}"
126+
add-paths: |
127+
${{ env.ap_file }}
128+
cookbooks/lk_appserver/metadata.rb
129+
Berksfile.lock
130+
131+
- name: Check outputs
132+
if: ${{ steps.cpr.outputs.pull-request-number }}
133+
run: |
134+
echo "Chef Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" >> $GITHUB_STEP_SUMMARY
135+
136+
paste_enforce_csp_into_dockerfile_repo:
137+
needs: copy_csp
138+
runs-on: ubuntu-latest
139+
env:
140+
csp_enforce_on: ${{ needs.copy_csp.outputs.csp_enforce_on }}
141+
ap_file: "application.properties"
142+
steps:
143+
- name: Check out repo
144+
uses: actions/checkout@v4
145+
with:
146+
repository: Labkey/Dockerfile
147+
token: ${{ secrets.TERRAFORM_TOKEN }}
148+
- name: Paste Into Dockerfile Repo
149+
run: |
150+
printf "\n\n>>>> $ap_file before I change it: <<<<\n\n"
151+
cat $ap_file
152+
153+
printf "\n\n>>>> caught csp_enforce_on env var:<<<<\n$csp_enforce_on\n\n"
154+
155+
printf "\n\n>>>> replacing csp block in $ap_file <<<<\n\n"
156+
157+
python <<EOF
158+
import os, sys, re
159+
fname = os.environ.get('ap_file')
160+
os.rename(fname, fname + '.orig')
161+
with open(fname + '.orig', 'r') as fin, open(fname, 'w') as fout:
162+
data = fin.read()
163+
data = re.sub(r'(## START OF CSP ENFORCE BLOCK \\(DO NOT CHANGE THIS TEXT\\)).*?(## END OF CSP ENFORCE BLOCK \\(DO NOT CHANGE THIS TEXT\\))',
164+
r'\1\n' +
165+
os.environ.get('csp_enforce_on') +
166+
r'\n\2', data, flags=re.DOTALL)
167+
fout.write(data)
168+
EOF
169+
170+
printf "\n\n>>>> updated $ap_file: <<<<\n\n"
171+
cat $ap_file
172+
173+
- name: Create Pull Request
174+
id: cpr
175+
uses: peter-evans/create-pull-request@v7
176+
with:
177+
token: ${{ secrets.TERRAFORM_TOKEN }}
178+
branch: fb_update_csp_per_${{ github.sha }}
179+
title: "update CSP to match commit ${{ github.sha }}"
180+
body: "update CSP to match commit ${{ github.sha }}"
181+
commit-message: "update CSP to match commit ${{ github.sha }}"
182+
add-paths: ${{ env.ap_file }}
183+
184+
- name: Check outputs
185+
if: ${{ steps.cpr.outputs.pull-request-number }}
186+
run: |
187+
echo "Dockerfile Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" >> $GITHUB_STEP_SUMMARY

server/configs/application.properties

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -125,34 +125,33 @@ management.server.port=@@shutdownPort@@
125125
#jsonaccesslog.condition-if=attributeName
126126
#jsonaccesslog.condition-unless=attributeName
127127

128-
## Define one or both of 'csp.report' and 'csp.enforce' to enable Content Security Policy (CSP) headers
129-
## Do not use these examples for any production environment without understanding the meaning of each directive!
130-
131-
## Default enforce CSP for dev deployments
128+
## START OF CSP ENFORCE BLOCK (DO NOT CHANGE THIS TEXT)
132129
#useLocalBuild#csp.enforce=\
133-
#useLocalBuild# default-src 'self' https: http: ;\
134-
#useLocalBuild# connect-src 'self' localhost:* ws: ${LABKEY.ALLOWED.CONNECTIONS} ;\
130+
#useLocalBuild# default-src 'self' https: ;\
131+
#useLocalBuild# connect-src 'self' ${LABKEY.ALLOWED.CONNECTIONS} ;\
135132
#useLocalBuild# object-src 'none' ;\
136133
#useLocalBuild# style-src 'self' https: 'unsafe-inline' ;\
137134
#useLocalBuild# img-src 'self' https: data: ;\
138-
#useLocalBuild# font-src 'self' http: https: data: ;\
139-
#useLocalBuild# script-src 'unsafe-eval' 'strict-dynamic' 'nonce-${REQUEST.SCRIPT.NONCE}' ;\
135+
#useLocalBuild# font-src 'self' data: ;\
136+
#useLocalBuild# script-src 'self' 'unsafe-eval' 'strict-dynamic' 'nonce-${REQUEST.SCRIPT.NONCE}' ;\
140137
#useLocalBuild# base-uri 'self' ;\
141138
#useLocalBuild# frame-ancestors 'self' ;\
142139
#useLocalBuild# report-uri /admin-contentsecuritypolicyreport.api?${CSP.REPORT.PARAMS} ;
140+
## END OF CSP ENFORCE BLOCK (DO NOT CHANGE THIS TEXT)
143141

144-
## Default report CSP for TeamCity and dev deployments
142+
## START OF CSP REPORT BLOCK (DO NOT CHANGE THIS TEXT)
145143
csp.report=\
146-
default-src 'self' https: http: ;\
147-
connect-src 'self' localhost:* ws: ${LABKEY.ALLOWED.CONNECTIONS} ;\
144+
default-src 'self' ;\
145+
connect-src 'self' ${LABKEY.ALLOWED.CONNECTIONS} ;\
148146
object-src 'none' ;\
149-
style-src 'self' https: 'unsafe-inline' ;\
150-
img-src 'self' https: data: ;\
151-
font-src 'self' http: https: data: ;\
147+
style-src 'self' 'unsafe-inline' ;\
148+
img-src 'self' data: ;\
149+
font-src 'self' data: ;\
152150
script-src 'unsafe-eval' 'strict-dynamic' 'nonce-${REQUEST.SCRIPT.NONCE}' ;\
153151
base-uri 'self' ;\
154152
frame-ancestors 'self' ;\
155153
report-uri /admin-contentsecuritypolicyreport.api?${CSP.REPORT.PARAMS} ;
154+
## END OF CSP REPORT BLOCK (DO NOT CHANGE THIS TEXT)
156155

157156
## Use a custom logging configuration
158157
#logging.config=path/to/alternative/log4j2.xml

0 commit comments

Comments
 (0)