Skip to content

Commit b89ecca

Browse files
committed
Bound record sets for DNS transport and reject scoped addresses
Signed-off-by: Anthony Ettinger <anthony@chovy.com>
1 parent 29fc4c2 commit b89ecca

2 files changed

Lines changed: 3 additions & 3 deletions

File tree

‎src/net-records.mjs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export function normalizeNetRecord(input, name) {
1717
let priority = 0;
1818
if (type === 'AAAA') {
1919
value = value.replace(/^\[|\]$/g, '').toLowerCase();
20-
if (isIP(value) !== 6) throw new W3bsError('INVALID_RECORD', 'AAAA needs an IPv6 address. Use CNAME for a hostname.', 400);
20+
if (isIP(value) !== 6 || value.includes('%')) throw new W3bsError('INVALID_RECORD', 'AAAA needs an IPv6 address. Use CNAME for a hostname.', 400);
2121
value = new URL(`http://[${value}]/`).hostname.slice(1,-1);
2222
if (/^(?:::(?:1)?$|::ffff:|f[cd]|fe[89ab]|ff)/i.test(value)) throw new W3bsError('INVALID_RECORD', 'Use a public IPv6 address, not a local, mapped or multicast address.', 400);
2323
} else if (type === 'CNAME' || type === 'MX') {
@@ -68,7 +68,7 @@ export function createNetRecords(db) {
6868
const existing = await rows(tx,tld,label);
6969
if (existing.some(r=>r.type==='CNAME' && (record.type!=='CNAME' || r.value!==record.value)) || (record.type==='CNAME' && existing.some(r=>r.type!=='CNAME')))
7070
throw new W3bsError('CNAME_CONFLICT','CNAME must be the only record on a name. Remove the existing records first.',409);
71-
if (existing.length >= 100 && !existing.some(r=>r.type===record.type && r.value===record.value && r.priority===record.priority)) throw new W3bsError('RECORD_LIMIT','A name can have at most 100 records.',409);
71+
if (existing.length >= 50 && !existing.some(r=>r.type===record.type && r.value===record.value && r.priority===record.priority)) throw new W3bsError('RECORD_LIMIT','A name can have at most 50 records.',409);
7272
await tx.run('INSERT INTO net_dns_records(id,tld,label,type,value,ttl,priority,created_at) VALUES(?,?,?,?,?,?,?,?) ON CONFLICT(tld,label,type,value,priority) DO UPDATE SET ttl=excluded.ttl',[randomUUID(),tld,label,record.type,record.value,record.ttl,record.priority,new Date().toISOString()]);
7373
return rows(tx,tld,label);
7474
});

‎test/net-records.test.mjs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ for(const databaseUrl of [null,...(process.env.W3BS_TEST_DATABASE_URL?[process.e
5050
test('record validation rejects private addresses, URLs, invalid TTLs and self aliases',()=>{
5151
for(const bad of [
5252
{type:'A',value:'127.0.0.1'}, {type:'AAAA',value:'::1'}, {type:'AAAA',value:'::ffff:127.0.0.1'},
53-
{type:'AAAA',value:'fd00::1'}, {type:'AAAA',value:'fe80::1'}, {type:'CNAME',value:'https://example.com/'},
53+
{type:'AAAA',value:'fd00::1'}, {type:'AAAA',value:'fe80::1%eth0'}, {type:'AAAA',value:'fe80::1'}, {type:'CNAME',value:'https://example.com/'},
5454
{type:'CNAME',value:'dumb.fuck.w3bs.org'}, {type:'MX',value:'mx.example.com',priority:-1},
5555
{type:'TXT',value:'x',ttl:1}, {type:'TXT',value:'x'.repeat(1025)},
5656
])assert.throws(()=>normalizeNetRecord(bad,'dumb.fuck'));

0 commit comments

Comments
 (0)