diff --git a/.changeset/nice-hairs-rush.md b/.changeset/nice-hairs-rush.md
new file mode 100644
index 000000000000..fb5fc6584b76
--- /dev/null
+++ b/.changeset/nice-hairs-rush.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Blocks cross-origin POST requests regardless of Content-Type to prevent CSRF bypass
diff --git a/.changeset/open-rocks-clean.md b/.changeset/open-rocks-clean.md
new file mode 100644
index 000000000000..7220314d537f
--- /dev/null
+++ b/.changeset/open-rocks-clean.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fixes prototype pollution in config merge by filtering `__proto__`, `constructor`, and `prototype` keys
diff --git a/.changeset/quiet-ligers-walk.md b/.changeset/quiet-ligers-walk.md
new file mode 100644
index 000000000000..efd3cf341f73
--- /dev/null
+++ b/.changeset/quiet-ligers-walk.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fixes XSS by escaping `` and `` sequences in raw string children of ``,
// we mark it as an HTML string to prevent the content from being HTML-escaped.
+ // ponytail: replaceAll handles common / injection in raw strings; full JS/CSS tokenizer only if user-controlled multi-line content is ever passed here
if (typeof children === 'string' && (tag === 'style' || tag === 'script')) {
- return markHTMLString(children);
+ return markHTMLString(children.replaceAll('`/` {
assert.equal(res.status, 403);
});
- it('allows cross-origin POST with application/json', async () => {
+ it('blocks cross-origin POST with application/json', async () => {
const res = await callCSRF({
method: 'POST',
url: 'http://example.com/api/',
headers: { origin: 'http://evil.com', 'content-type': 'application/json' },
});
- assert.equal(res.status, 200);
+ assert.equal(res.status, 403);
});
- it('allows cross-origin POST with application/octet-stream', async () => {
+ it('blocks cross-origin POST with application/octet-stream', async () => {
const res = await callCSRF({
method: 'POST',
url: 'http://example.com/api/',
headers: { origin: 'http://evil.com', 'content-type': 'application/octet-stream' },
});
- assert.equal(res.status, 200);
+ assert.equal(res.status, 403);
});
it('blocks cross-origin POST with uppercased form content-type', async () => {