const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World');
});

server.listen(port, hostname, () => {
console.log(Server running at http://${hostname}:${port}/); });

然后您可以轉(zhuǎn)到終端并使用以下命令運(yùn)行代碼: 

node app.js

訪問 http://localhost:3000,您應(yīng)該會看到一條消息“Hello World”。 

很簡單,對吧?

什么是 SQL 注入?

現(xiàn)在我們來簡單解釋一下什么是 SQL 注入。它是一種利用數(shù)據(jù)庫集成不充分和用戶輸入驗(yàn)證不完善而進(jìn)行的注入攻擊。  

輸入平臺的惡意SQL指令可以到達(dá)ORM層,通過面向用戶的輸入字段直接進(jìn)入SQL數(shù)據(jù)庫,并接管整個(gè)系統(tǒng)。 

SQL 注入攻擊的主要目的是操縱數(shù)據(jù)庫中的數(shù)據(jù)、迫使系統(tǒng)交出其數(shù)據(jù),或兩者兼而有之。  

由于 SQL 注入攻擊以系統(tǒng)數(shù)據(jù)庫為目標(biāo),一旦成功,即可提供全部或部分訪問權(quán)限,因此影響可能非常巨大。因此,人們可以有理由相信這些漏洞非常復(fù)雜,并且只用于復(fù)雜的攻擊。但事實(shí)上,大多數(shù) SQL 注入攻擊并不是特別復(fù)雜或罕見。  

事實(shí)上,情況恰恰相反。

SQL 注入示例

為了說明這一點(diǎn),讓我們看一下針對允許用戶輸入的系統(tǒng)的 SQL 注入攻擊的典型實(shí)現(xiàn)。 

想象一下,您在模型層或數(shù)據(jù)庫集成層中有代碼,您可以通過格式化以下 SQL 查詢命令來檢索用戶信息:

query = 'SELECT * FROM Users WHERE Email = "' + USERNAME + '" AND Pass = "' + PASSWORD + '";'

如您所見,這個(gè)簡單(且非常危險(xiǎn))的查詢命令搜索用戶表并檢索具有匹配憑據(jù)的用戶。 

任何對 SQL 有基本了解的不良行為者都可以利用用戶輸入缺乏驗(yàn)證的情況,輸入開發(fā)人員未預(yù)見到有效用戶提供的值。  

例如,如果你在該查詢中輸入如下內(nèi)容,系統(tǒng)將把表中的所有用戶交給攻擊者:

" or ""="

現(xiàn)在應(yīng)該清楚的是,這種攻擊的復(fù)雜性和復(fù)雜性都很少。它依靠簡單的輸入驗(yàn)證來生存和消亡。然而,這并不意味著 SQL 注入攻擊不能很復(fù)雜,也不能成為更強(qiáng)大和更復(fù)雜的攻擊的一部分。 

Typescript SQL 注入指南:示例及預(yù)防 - 圖片 1 圖片

常見的 SQL 注入攻擊

除了我們之前探討過的“””=”””攻擊外,還有幾種注入攻擊形式也很常見。攻擊者可以利用這些攻擊,在充分了解數(shù)據(jù)庫結(jié)構(gòu)并反復(fù)試驗(yàn)的情況下,成功攻擊易受攻擊的系統(tǒng)。

緩解 SQL 注入的措施

現(xiàn)在您已經(jīng)對 SQL 注入攻擊如何利用您的系統(tǒng)有了基本的了解,讓我們來看看一些簡單的預(yù)防措施。 

首先,有必要解決在面向用戶的前端代碼中實(shí)現(xiàn)的用戶輸入驗(yàn)證問題。此驗(yàn)證將成為您抵御不良行為者的第一道防線,并充當(dāng)用戶的響應(yīng)機(jī)制。 

我們需要確保用戶提供的值具有相應(yīng)的范圍和清理功能。這意味著,例如,如果輸入字段用于接收電子郵件,則它不允許用戶提交包含無效電子郵件的表單 – 或者根本沒有值。  

這個(gè)想法的簡單實(shí)現(xiàn)如下:

const email_regex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

function validate(email: string): boolean {
if (email == "") {
alert("Email must be filled out");

return false;
} else if (email_regex.test(email.toLowerCase()) == false) {
alert("Email must be valid");

return false;
}

return true;
}

當(dāng)然,我們可以通過輸入掩碼和響應(yīng)式表單樣式來擴(kuò)展這種方法。這可以告知用戶提供的值無效,從而改善用戶體驗(yàn)。 

其次,我們必須在應(yīng)用程序級別實(shí)現(xiàn)輸入驗(yàn)證,因?yàn)榇蠖鄶?shù)業(yè)務(wù)層都存在于該級別。此策略可以簡單到在到達(dá)模型層之前重新驗(yàn)證并在適當(dāng)?shù)那闆r下清理用戶輸入。  

此外,添加“node-mysql”等第三方庫可以提供更強(qiáng)大的保護(hù)層來抵御這些攻擊。

數(shù)據(jù)庫層

最后,一旦解決了頂層問題,我們就可以著手保護(hù)數(shù)據(jù)庫層的安全。  

我們需要做的就是實(shí)現(xiàn)所謂的查詢占位符或名稱占位符。這些占位符(此處用 ? 符號表示)指示接口層自動轉(zhuǎn)義傳遞給它的輸入并驗(yàn)證其類型和格式,以使其符合數(shù)據(jù)庫結(jié)構(gòu)。  

例如,如果給一個(gè)期望整數(shù)的列提供一個(gè)字符串,則查詢將中止并引發(fā)異常。 

假設(shè)您有一種檢索敏感信息并傳遞未經(jīng)驗(yàn)證的用戶輸入的方法。

app.post("/records", (request, response) => {
const data = request.body;
const query = SELECT * FROM health_records WHERE id = (${data.id}); // === MySQL === const mysql = require('mysql'); const mycon = mysql.createConnection({ host: host, user: user, password: pass, database: db }); mycon.connect(function(err) { mycon.query(query, (err, rows) => { if(err) throw err; response.json({data:rows}); }); }); });

這段代碼可能會引發(fā)很多麻煩。  

但解決這個(gè)問題非常簡單。

app.post("/records", (request, response) => {
const data = request.body;

// === MySQL ===
const mysql = require('mysql');

const mycon = mysql.createConnection({ host: host, user: user, password: pass, database: db });

mycon.connect(function(err) {
mycon.query('SELECT * FROM health_records WHERE id = ?', [data.id], (err, res) => {
if(err) throw err;

response.json({data:rows});
});
});
});

如您所見,查詢指令現(xiàn)在使用 ? 字符作為占位符來提供參數(shù)。這告訴查詢庫清理并驗(yàn)證輸入的值以防止注入。這是一個(gè)微妙的變化,但它對我們代碼的安全性有重大影響。 

總結(jié):如何防止 Typescript SQL 注入

我們探討了 SQL 注入并提供了一些示例,我們可以這樣總結(jié)最佳策略: 

遵守正確的 SQL 注入預(yù)防措施并不復(fù)雜。  

由于我們擁有穩(wěn)健且久經(jīng)考驗(yàn)的方法和庫,我們可以毫不費(fèi)力地提供可靠的保護(hù)。但是,根據(jù)代碼庫的大小和復(fù)雜性,您的里程可能會有所不同。  

盡管如此,這種保護(hù)所需的時(shí)間投入將在未來幾年帶來回報(bào)。 

文章來源:Typescript SQL Injection Guide: Examples and Prevention

上一篇:

Typescript命令注入:示例及預(yù)防

下一篇:

.NET CORS指南:它是什么如何啟用它
#你可能也喜歡這些API文章!

我們有何不同?

API服務(wù)商零注冊

多API并行試用

數(shù)據(jù)驅(qū)動選型,提升決策效率

查看全部API→
??

熱門場景實(shí)測,選對API

#AI文本生成大模型API

對比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個(gè)渠道
一鍵對比試用API 限時(shí)免費(fèi)

#AI深度推理大模型API

對比大模型API的邏輯推理準(zhǔn)確性、分析深度、可視化建議合理性

10個(gè)渠道
一鍵對比試用API 限時(shí)免費(fèi)